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

class  TextGeneratorIntf
 Abstract interface for a hyperlinked text fragment. More...
class  TextGeneratorOLImpl
 Implements TextGeneratorIntf for an OutputDocInterface stream. More...
struct  GetDefInput
struct  GetDefResult
struct  SelectionBlock
struct  SelectionMarkerInfo
struct  KeywordSubstitution
struct  ColoredImgDataItem
 Data associated with a HSV colored image. More...

Typedefs

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

Functions

QCString langToString (SrcLangExt lang)
 Returns a string representation of lang.
QCString getLanguageSpecificSeparator (SrcLangExt lang, bool classScope=FALSE)
 Returns the scope separator to use given the programming language lang.
void linkifyText (const TextGeneratorIntf &ol, const Definition *scope, const FileDef *fileScope, const Definition *self, const QCString &text, bool autoBreak=FALSE, bool external=TRUE, bool keepSpaces=FALSE, int indentLevel=0, size_t breakThreshold=30)
QCString fileToString (const QCString &name, bool filter=FALSE, bool isSourceCode=FALSE)
GetDefResult getDefs (const GetDefInput &input)
QCString getFileFilter (const QCString &name, bool isSourceCode)
bool resolveRef (const QCString &scName, const QCString &name, bool inSeeBlock, const Definition **resContext, const MemberDef **resMember, SrcLangExt lang, bool lookForSpecializations=TRUE, const FileDef *currentFile=nullptr, bool checkScope=FALSE)
bool resolveLink (const QCString &scName, const QCString &lr, bool inSeeBlock, const Definition **resContext, QCString &resAnchor, SrcLangExt lang, const QCString &prefix=QCString())
void generateFileRef (OutputList &ol, const QCString &, const QCString &linkTxt=QCString())
void writePageRef (OutputList &ol, const QCString &cn, const QCString &mn)
bool matchArguments2 (const Definition *srcScope, const FileDef *srcFileScope, const QCString &srcReturnType, const ArgumentList *srcAl, const Definition *dstScope, const FileDef *dstFileScope, const QCString &dstReturnType, const ArgumentList *dstAl, bool checkCV, SrcLangExt lang)
void mergeArguments (ArgumentList &, ArgumentList &, bool forceNameOverwrite=FALSE)
bool matchTemplateArguments (const ArgumentList &srcAl, const ArgumentList &dstAl)
QCString substituteClassNames (const QCString &s)
QCString selectBlocks (const QCString &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 QCString &s, const QCString fileName, const SelectionMarkerInfo &markerInfo)
QCString removeEmptyLines (const QCString &s)
FileDeffindFileDef (const FileNameLinkedMap *fnMap, const QCString &n, bool &ambig)
QCString findFilePath (const QCString &file, bool &ambig)
QCString showFileDefMatches (const FileNameLinkedMap *fnMap, const QCString &n)
EntryType guessSection (const QCString &name)
bool isId (int c)
bool isIdJS (int c)
QCString removeRedundantWhiteSpace (const QCString &s)
QCString inlineArgListToDoc (const ArgumentList &al)
QCString inlineTemplateArgListToDoc (const ArgumentList &al)
QCString argListToString (const ArgumentList &al, bool useCanonicalType=FALSE, bool showDefVals=TRUE)
QCString tempArgListToString (const ArgumentList &al, SrcLangExt lang, bool includeDefaults=true)
QCString generateMarker (int id)
void writeExamples (OutputList &ol, const ExampleList &el)
QCString stripAnonymousNamespaceScope (const QCString &s)
QCString stripFromPath (const QCString &path)
QCString stripFromIncludePath (const QCString &path)
bool rightScopeMatch (const QCString &scope, const QCString &name)
bool leftScopeMatch (const QCString &scope, const QCString &name)
QCString substituteKeywords (const QCString &file, const QCString &s, const KeywordSubstitutionList &keywords)
QCString substituteKeywords (const QCString &file, const QCString &s, const QCString &title, const QCString &projName, const QCString &projNum, const QCString &projBrief)
int getPrefixIndex (const QCString &name)
QCString removeAnonymousScopes (const QCString &s)
QCString replaceAnonymousScopes (const QCString &s, const QCString &replacement=QCString())
QCString convertNameToFile (const QCString &name, bool allowDots=FALSE, bool allowUnderscore=FALSE)
QCString generateAnonymousAnchor (const QCString &fileName, int count)
void extractNamespaceName (const QCString &scopeName, QCString &className, QCString &namespaceName, bool allowEmptyClass=FALSE)
QCString insertTemplateSpecifierInScope (const QCString &scope, const QCString &templ)
QCString stripScope (const QCString &name)
QCString convertToId (const QCString &s)
QCString correctId (const QCString &s)
QCString convertToHtml (const QCString &s, bool keepEntities=true)
QCString convertToXML (const QCString &s, bool keepEntities=false)
QCString convertToJSString (const QCString &s, bool keepEntities=false, bool singleQuotes=false)
QCString getOverloadDocs ()
void addMembersToMemberGroup (MemberList *ml, MemberGroupList *pMemberGroups, const Definition *context)
int extractClassNameFromType (const QCString &type, int &pos, QCString &name, QCString &templSpec, SrcLangExt=SrcLangExt::Unknown)
QCString normalizeNonTemplateArgumentsInString (const QCString &name, const Definition *context, const ArgumentList &formalArgs)
QCString substituteTemplateArgumentsInString (const QCString &name, const ArgumentList &formalArgs, const ArgumentList *actualArgs)
QCString stripTemplateSpecifiersFromScope (const QCString &fullName, bool parentOnly=TRUE, QCString *lastScopeStripped=nullptr, QCString scopeName=QCString(), bool allowArtificial=true)
QCString resolveTypeDef (const Definition *d, const QCString &name, const Definition **typedefContext=nullptr)
QCString mergeScopes (const QCString &leftScope, const QCString &rightScope)
int getScopeFragment (const QCString &s, int p, int *l)
void addRefItem (const RefItemVector &sli, const QCString &key, const QCString &prefix, const QCString &name, const QCString &title, const QCString &args, const Definition *scope)
PageDefaddRelatedPage (const QCString &name, const QCString &ptitle, const QCString &doc, const QCString &fileName, int docLine, int startLine, const RefItemVector &sli=RefItemVector(), GroupDef *gd=nullptr, const TagInfo *tagInfo=nullptr, bool xref=FALSE, SrcLangExt lang=SrcLangExt::Unknown)
bool getCaseSenseNames ()
QCString escapeCharsInString (const QCString &name, bool allowDots, bool allowUnderscore=FALSE)
QCString unescapeCharsInString (const QCString &s)
void addGroupListToTitle (OutputList &ol, const Definition *d)
QCString linkToText (SrcLangExt lang, const QCString &link, bool isFileName)
bool checkExtension (const QCString &fName, const QCString &ext)
void addHtmlExtensionIfMissing (QCString &fName)
QCString stripExtensionGeneral (const QCString &fName, const QCString &ext)
QCString stripExtension (const QCString &fName)
QCString makeBaseName (const QCString &name, const QCString &ext)
int computeQualifiedIndex (const QCString &name)
 Return the index of the last :: in the string name that is still before the first <.
void addDirPrefix (QCString &fileName)
QCString relativePathToRoot (const QCString &name)
QCString determineAbsoluteIncludeName (const QCString &curFile, const QCString &incFileName)
void createSubDirs (const Dir &d)
void clearSubDirs (const Dir &d)
QCString removeLongPathMarker (QCString path)
QCString stripPath (const QCString &s)
bool containsWord (const QCString &s, const char *word)
 returns TRUE iff string s contains word w
bool findAndRemoveWord (QCString &s, const char *word)
 removes occurrences of whole word from sentence, while keeps internal spaces and reducing multiple sequences of spaces.
QCString stripLeadingAndTrailingEmptyLines (const QCString &s, int &docLine)
 Special version of QCString::stripWhiteSpace() that only strips completely blank lines.
bool updateLanguageMapping (const QCString &extension, const QCString &parser)
SrcLangExt getLanguageFromFileName (const QCString &fileName, SrcLangExt defLang=SrcLangExt::Cpp)
SrcLangExt getLanguageFromCodeLang (QCString &fileName)
 Routine to handle the language attribute of the \code command.
QCString getFileNameExtension (const QCString &fn)
void initDefaultExtensionMapping ()
void addCodeOnlyMappings ()
bool checkIfTypedef (const Definition *scope, const FileDef *fileScope, const QCString &n)
QCString parseCommentAsText (const Definition *scope, const MemberDef *member, const QCString &doc, const QCString &fileName, int lineNr)
QCString parseCommentAsHtml (const Definition *scope, const MemberDef *member, const QCString &doc, const QCString &fileName, int lineNr)
bool transcodeCharacterStringToUTF8 (std::string &input, const char *inputEncoding)
QCString recodeString (const QCString &str, const char *fromEncoding, const char *toEncoding)
void writeTypeConstraints (OutputList &ol, const Definition *d, const ArgumentList &al)
QCString convertCharEntitiesToUTF8 (const QCString &s)
void stackTrace ()
bool readInputFile (const QCString &fileName, std::string &contents, bool filter=TRUE, bool isSourceCode=FALSE)
 read a file name fileName and optionally filter and transcode it
QCString filterTitle (const QCString &title)
bool patternMatch (const FileInfo &fi, const StringVector &patList)
QCString externalLinkTarget (const bool parent=false)
QCString createHtmlUrl (const QCString &relPath, const QCString &ref, bool href, bool islocalFile, const QCString &targetFileName, const QCString &anchor)
QCString externalRef (const QCString &relPath, const QCString &ref, bool href)
int nextUtf8CharPosition (const QCString &utf8Str, uint32_t len, uint32_t startPos)
void writeMarkerList (OutputList &ol, const std::string &markerText, size_t numMarkers, std::function< void(size_t)> replaceFunc)
QCString writeMarkerList (const std::string &markerText, size_t numMarkers, std::function< QCString(size_t)> replaceFunc)
void writeColoredImgData (const QCString &dir, ColoredImgDataItem data[])
 Writes the intensity only bitmap represented by data as an image to directory dir using the colors defined by HTML_COLORSTYLE_*.
QCString replaceColorMarkers (const QCString &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 QCString &src, const QCString &dest)
 Copies the contents of file with name src to the newly created file with name dest.
int lineBlock (const QCString &text, const QCString &marker)
 Returns the line number of the line following the line with the marker.
bool isURL (const QCString &url)
 Checks whether the given url starts with a supported protocol.
QCString correctURL (const QCString &url, const QCString &relPath)
 Corrects URL url according to the relative path relPath.
QCString processMarkup (const QCString &s)
bool protectionLevelVisible (Protection prot)
QCString stripIndentation (const QCString &s, bool skipFirstLine=false)
void stripIndentationVerbatim (QCString &doc, const int indentationLevel, bool skipFirstLine=true)
QCString getDotImageExtension ()
bool fileVisibleInIndex (const FileDef *fd, bool &genSourceFile)
QCString extractDirection (QCString &docs)
 Strip the direction part from docs and return it as a string in canonical form The input docs string can start with e.g.
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 QCString &outFile, std::ofstream &f)
StringVector split (const std::string &s, const std::string &delimiter)
 split input string s by string delimiter delimiter.
StringVector split (const std::string &s, const reg::Ex &delimiter)
 split input string s by regular expression delimiter delimiter.
int findIndex (const StringVector &sv, const std::string &s)
 find the index of a string in a vector of strings, returns -1 if the string could not be found
int findIndex (const std::string &s, const reg::Ex &re)
 find the index of the first occurrence of pattern re in a string s returns -1 if the pattern could not be found
std::string join (const StringVector &s, const std::string &delimiter)
 create a string where the string in the vector are joined by the given delimiter
bool recognizeFixedForm (const QCString &contents, FortranFormat format)
FortranFormat convertFileNameFortranParserCode (QCString fn)
QCString integerToAlpha (int n, bool upper=true)
QCString integerToRoman (int n, bool upper=true)
QCString getEncoding (const FileInfo &fi)
QCString fixSpaces (const QCString &s)
QCString detab (const QCString &s, size_t &refIndent)
QCString getProjectId ()
QCString projectLogoFile ()
void mergeMemberOverrideOptions (MemberDefMutable *md1, MemberDefMutable *md2)
size_t updateColumnCount (const char *s, size_t col)
QCString mangleCSharpGenericName (const QCString &name)
QCString demangleCSharpGenericName (const QCString &name, const QCString &templArgs)
QCString extractBeginRawStringDelimiter (const char *rawStart)
QCString extractEndRawStringDelimiter (const char *rawEnd)
QCString writeFileContents (const QCString &baseName, const QCString &extension, const QCString &content, bool &exists)
 Thread-safe function to write a string to a file.
void cleanupInlineGraph ()

Detailed Description

A bunch of utility functions.

Definition in file util.h.

Typedef Documentation

◆ KeywordSubstitutionList

Definition at line 248 of file util.h.

◆ SelectionBlockList

using SelectionBlockList = std::vector<SelectionBlock>

Definition at line 182 of file util.h.

Function Documentation

◆ addCodeOnlyMappings()

void addCodeOnlyMappings ( )

Definition at line 5188 of file util.cpp.

5189{
5190 updateLanguageMapping(".xml", "xml");
5191 updateLanguageMapping(".sql", "sql");
5192}
bool updateLanguageMapping(const QCString &extension, const QCString &language)
Definition util.cpp:5089

References updateLanguageMapping().

Referenced by generateOutput().

◆ addDirPrefix()

void addDirPrefix ( QCString & fileName)

◆ addGroupListToTitle()

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

◆ addHtmlExtensionIfMissing()

void addHtmlExtensionIfMissing ( QCString & fName)

Definition at line 4905 of file util.cpp.

4906{
4907 if (fName.isEmpty()) return;
4908 int i_fs = fName.findRev('/');
4909 int i_bs = fName.findRev('\\');
4910 int i = fName.find('.',std::max({ i_fs, i_bs ,0})); // search for . after path part
4911 if (i==-1)
4912 {
4914 }
4915}
static QCString htmlFileExtension
Definition doxygen.h:121
int find(char c, int index=0, bool cs=TRUE) const
Definition qcstring.cpp:43
bool isEmpty() const
Returns TRUE iff the string is empty.
Definition qcstring.h:163
int findRev(char c, int index=-1, bool cs=TRUE) const
Definition qcstring.cpp:96

References QCString::find(), QCString::findRev(), Doxygen::htmlFileExtension, and QCString::isEmpty().

Referenced by HtmlCodeGenerator::_writeCodeLink(), Crawlmap::addContentsItem(), DocSets::addContentsItem(), EclipseHelp::addContentsItem(), HtmlHelp::addContentsItem(), Qhp::addContentsItem(), Crawlmap::addIndexFile(), Sitemap::addIndexFile(), common_attributes(), convertMapFile(), dumpSymbol(), field2URL(), FTVHelp::Private::generateTree(), Crawlmap::initialize(), makeFileName(), makeFileName(), makeURL(), DefinitionImpl::navigationPathAsString(), node2URL(), HtmlDocVisitor::operator()(), replaceRef(), SearchIndexExternal::setCurrentDoc(), HtmlGenerator::startFile(), HtmlGenerator::startIndexItem(), HtmlDocVisitor::startLink(), HtmlGenerator::startTextLink(), LayoutNavEntry::url(), DefinitionImpl::writeDocAnchorsToTagFile(), writeIndex(), 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().

◆ addMembersToMemberGroup()

void addMembersToMemberGroup ( MemberList * ml,
MemberGroupList * pMemberGroups,
const Definition * context )

Definition at line 4081 of file util.cpp.

4084{
4085 ASSERT(context!=nullptr);
4086 //printf("addMemberToMemberGroup() context=%s\n",qPrint(context->name()));
4087 if (ml==nullptr) return;
4088
4089 struct MoveMemberInfo
4090 {
4091 MoveMemberInfo(MemberDef *md,MemberGroup *mg,const RefItemVector &rv)
4092 : memberDef(md), memberGroup(mg), sli(rv) {}
4093 MemberDef *memberDef;
4094 MemberGroup *memberGroup;
4095 RefItemVector sli;
4096 };
4097 std::vector<MoveMemberInfo> movedMembers;
4098
4099 for (const auto &md : *ml)
4100 {
4101 if (md->isEnumerate()) // insert enum value of this enum into groups
4102 {
4103 for (const auto &fmd : md->enumFieldList())
4104 {
4105 int groupId=fmd->getMemberGroupId();
4106 if (groupId!=-1)
4107 {
4108 auto it = Doxygen::memberGroupInfoMap.find(groupId);
4110 {
4111 const auto &info = it->second;
4112 auto mg_it = std::find_if(pMemberGroups->begin(),
4113 pMemberGroups->end(),
4114 [&groupId](const auto &g)
4115 { return g->groupId()==groupId; }
4116 );
4117 MemberGroup *mg_ptr = nullptr;
4118 if (mg_it==pMemberGroups->end())
4119 {
4120 auto mg = std::make_unique<MemberGroup>(
4121 context,
4122 groupId,
4123 info->header,
4124 info->doc,
4125 info->docFile,
4126 info->docLine,
4127 ml->container());
4128 mg_ptr = mg.get();
4129 pMemberGroups->push_back(std::move(mg));
4130 }
4131 else
4132 {
4133 mg_ptr = (*mg_it).get();
4134 }
4135 mg_ptr->insertMember(fmd); // insert in member group
4137 if (fmdm)
4138 {
4139 fmdm->setMemberGroup(mg_ptr);
4140 }
4141 }
4142 }
4143 }
4144 }
4145 int groupId=md->getMemberGroupId();
4146 if (groupId!=-1)
4147 {
4148 auto it = Doxygen::memberGroupInfoMap.find(groupId);
4150 {
4151 const auto &info = it->second;
4152 auto mg_it = std::find_if(pMemberGroups->begin(),
4153 pMemberGroups->end(),
4154 [&groupId](const auto &g)
4155 { return g->groupId()==groupId; }
4156 );
4157 MemberGroup *mg_ptr = nullptr;
4158 if (mg_it==pMemberGroups->end())
4159 {
4160 auto mg = std::make_unique<MemberGroup>(
4161 context,
4162 groupId,
4163 info->header,
4164 info->doc,
4165 info->docFile,
4166 info->docLine,
4167 ml->container());
4168 mg_ptr = mg.get();
4169 pMemberGroups->push_back(std::move(mg));
4170 }
4171 else
4172 {
4173 mg_ptr = (*mg_it).get();
4174 }
4175 movedMembers.emplace_back(md,mg_ptr,info->m_sli);
4176 }
4177 }
4178 }
4179
4180 // move the members to their group
4181 for (const auto &mmi : movedMembers)
4182 {
4183 ml->remove(mmi.memberDef); // remove from member list
4184 mmi.memberGroup->insertMember(mmi.memberDef->resolveAlias()); // insert in member group
4185 mmi.memberGroup->setRefItems(mmi.sli);
4186 MemberDefMutable *rmdm = toMemberDefMutable(mmi.memberDef);
4187 if (rmdm)
4188 {
4189 rmdm->setMemberGroup(mmi.memberGroup);
4190 }
4191 }
4192}
static MemberGroupInfoMap memberGroupInfoMap
Definition doxygen.h:117
virtual void setMemberGroup(MemberGroup *grp)=0
A class representing a group of members.
Definition membergroup.h:44
void insertMember(MemberDef *md)
DirIterator end(const DirIterator &) noexcept
Definition dir.cpp:175
MemberDefMutable * toMemberDefMutable(Definition *d)
#define ASSERT(x)
Definition qcstring.h:39
std::vector< RefItem * > RefItemVector
Definition reflist.h:133

References ASSERT, MemberList::container(), Definition::docFile(), end(), MemberGroup::insertMember(), Doxygen::memberGroupInfoMap, MemberVector::remove(), MemberDef::setMemberGroup(), and toMemberDefMutable().

◆ addRefItem()

void addRefItem ( const RefItemVector & sli,
const QCString & key,
const QCString & prefix,
const QCString & name,
const QCString & title,
const QCString & args,
const Definition * scope )

Definition at line 4808 of file util.cpp.

4811{
4812 //printf("addRefItem(sli=%d,key=%s,prefix=%s,name=%s,title=%s,args=%s)\n",(int)sli.size(),key,prefix,name,title,args);
4813 if (!key.isEmpty() && key[0]!='@') // check for @ to skip anonymous stuff (see bug427012)
4814 {
4815 for (RefItem *item : sli)
4816 {
4817 item->setPrefix(prefix);
4818 item->setScope(scope);
4819 item->setName(name);
4820 item->setTitle(title);
4821 item->setArgs(args);
4822 item->setGroup(key);
4823 }
4824 }
4825}
constexpr auto prefix
Definition anchor.cpp:44
This struct represents an item in the list of references.
Definition reflist.h:32

References QCString::isEmpty(), and prefix.

Referenced by MemberDefImpl::addListReference(), ClassDefImpl::addListReferences(), ConceptDefImpl::addListReferences(), DirDefImpl::addListReferences(), FileDefImpl::addListReferences(), GroupDefImpl::addListReferences(), ModuleDefImpl::addListReferences(), NamespaceDefImpl::addListReferences(), PageDefImpl::addListReferences(), and buildPageList().

◆ addRelatedPage()

PageDef * addRelatedPage ( const QCString & name,
const QCString & ptitle,
const QCString & doc,
const QCString & 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 4678 of file util.cpp.

4689{
4690 PageDef *pd=nullptr;
4691 //printf("addRelatedPage(name=%s gd=%p)\n",qPrint(name),gd);
4692 QCString title=ptitle.stripWhiteSpace();
4693 bool newPage = true;
4694 if ((pd=Doxygen::pageLinkedMap->find(name)) && !pd->isReference())
4695 {
4696 if (!xref && !title.isEmpty() && pd->title()!=pd->name() && pd->title()!=title)
4697 {
4698 warn(fileName,startLine,"multiple use of page label '{}' with different titles, (other occurrence: {}, line: {})",
4699 name,pd->docFile(),pd->getStartBodyLine());
4700 }
4701 if (!title.isEmpty() && pd->title()==pd->name()) // pd has no real title yet
4702 {
4703 pd->setTitle(title);
4705 if (si)
4706 {
4707 si->setTitle(title);
4708 }
4709 }
4710 // append documentation block to the page.
4711 pd->setDocumentation(doc,fileName,docLine);
4712 //printf("Adding page docs '%s' pi=%p name=%s\n",qPrint(doc),pd,name);
4713 // append (x)refitems to the page.
4714 pd->setRefItems(sli);
4715 newPage = false;
4716 }
4717
4718 if (newPage) // new page
4719 {
4720 QCString baseName=name;
4721 if (baseName.endsWith(".tex"))
4722 baseName=baseName.left(baseName.length()-4);
4723 else if (baseName.right(Doxygen::htmlFileExtension.length())==Doxygen::htmlFileExtension)
4724 baseName=baseName.left(baseName.length()-Doxygen::htmlFileExtension.length());
4725
4726 //printf("Appending page '%s'\n",qPrint(baseName));
4727 if (pd) // replace existing page
4728 {
4729 pd->setDocumentation(doc,fileName,docLine);
4731 pd->setShowLineNo(FALSE);
4732 pd->setNestingLevel(0);
4733 pd->setPageScope(nullptr);
4734 pd->setTitle(title);
4735 pd->setReference(QCString());
4736 }
4737 else // newPage
4738 {
4739 pd = Doxygen::pageLinkedMap->add(baseName,
4740 createPageDef(fileName,docLine,baseName,doc,title));
4741 }
4742 pd->setBodySegment(startLine,startLine,-1);
4743
4744 pd->setRefItems(sli);
4745 pd->setLanguage(lang);
4746
4747 if (tagInfo)
4748 {
4749 pd->setReference(tagInfo->tagName);
4750 pd->setFileName(tagInfo->fileName);
4751 }
4752
4753 if (gd) gd->addPage(pd);
4754
4755 if (pd->hasTitle())
4756 {
4757 //outputList->writeTitle(pi->name,pi->title);
4758
4759 // a page name is a label as well!
4760 QCString file;
4761 QCString orgFile;
4762 int line = -1;
4763 if (gd)
4764 {
4765 file=gd->getOutputFileBase();
4766 orgFile=gd->getOutputFileBase();
4767 }
4768 else
4769 {
4770 file=pd->getOutputFileBase();
4771 orgFile=pd->docFile();
4772 line = pd->getStartBodyLine();
4773 }
4774 const SectionInfo *si = SectionManager::instance().find(pd->name());
4775 if (si)
4776 {
4777 if (!si->ref().isEmpty()) // we are from a tag file
4778 {
4780 file,-1,pd->title(),SectionType::Page,0,pd->getReference());
4781 }
4782 else if (si->lineNr() != -1)
4783 {
4784 warn(orgFile,line,"multiple use of section label '{}', (first occurrence: {}, line {})",pd->name(),si->fileName(),si->lineNr());
4785 }
4786 else
4787 {
4788 warn(orgFile,line,"multiple use of section label '{}', (first occurrence: {})",pd->name(),si->fileName());
4789 }
4790 }
4791 else
4792 {
4794 file,-1,pd->title(),SectionType::Page,0,pd->getReference());
4795 //printf("si->label='%s' si->definition=%s si->fileName='%s'\n",
4796 // qPrint(si->label),si->definition?si->definition->name().data():"<none>",
4797 // qPrint(si->fileName));
4798 //printf(" SectionInfo: sec=%p sec->fileName=%s\n",si,qPrint(si->fileName));
4799 //printf("Adding section key=%s si->fileName=%s\n",qPrint(pageName),qPrint(si->fileName));
4800 }
4801 }
4802 }
4803 return pd;
4804}
virtual QCString docFile() const =0
virtual QCString getReference() const =0
virtual QCString getOutputFileBase() const =0
virtual int getStartBodyLine() const =0
virtual bool isReference() const =0
virtual const QCString & name() const =0
virtual void setBodySegment(int defLine, int bls, int ble)=0
virtual void setDocumentation(const QCString &d, const QCString &docFile, int docLine, bool stripWhiteSpace=TRUE)=0
virtual void setLanguage(SrcLangExt lang)=0
virtual void setReference(const QCString &r)=0
virtual void setRefItems(const RefItemVector &sli)=0
static PageLinkedMap * pageLinkedMap
Definition doxygen.h:99
virtual void addPage(PageDef *def)=0
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 QCString &title)=0
virtual void setNestingLevel(int)=0
virtual bool hasTitle() const =0
virtual void setFileName(const QCString &name)=0
virtual void setShowLineNo(bool)=0
virtual QCString title() const =0
virtual void setPageScope(Definition *)=0
This is an alternative implementation of QCString.
Definition qcstring.h:101
size_t length() const
Returns the length of the string, not counting the 0-terminator.
Definition qcstring.h:166
bool endsWith(const char *s) const
Definition qcstring.h:524
QCString stripWhiteSpace() const
returns a copy of this string with leading and trailing whitespace removed
Definition qcstring.h:260
QCString right(size_t len) const
Definition qcstring.h:234
QCString left(size_t len) const
Definition qcstring.h:229
class that provide information about a section.
Definition section.h:58
QCString ref() const
Definition section.h:72
QCString fileName() const
Definition section.h:74
int lineNr() const
Definition section.h:73
void setTitle(const QCString &t)
Definition section.h:84
SectionInfo * replace(const QCString &label, const QCString &fileName, int lineNr, const QCString &title, SectionType type, int level, const QCString &ref=QCString())
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 QCString &f, int l, const QCString &n, const QCString &d, const QCString &t)
Definition pagedef.cpp:82
#define FALSE
Definition qcstring.h:34
QCString fileName
Definition entry.h:106
QCString tagName
Definition entry.h:105
QCString convertNameToFile(const QCString &name, bool allowDots, bool allowUnderscore)
Definition util.cpp:3488

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

◆ argListToString()

QCString argListToString ( const ArgumentList & al,
bool useCanonicalType = FALSE,
bool showDefVals = TRUE )

Definition at line 1234 of file util.cpp.

1235{
1236 QCString result;
1237 if (!al.hasParameters()) return result;
1238 result+="(";
1239 for (auto it = al.begin() ; it!=al.end() ;)
1240 {
1241 Argument a = *it;
1242 QCString type1 = useCanonicalType && !a.canType.isEmpty() ? a.canType : a.type;
1243 QCString type2;
1244 int i=type1.find(")("); // hack to deal with function pointers
1245 if (i!=-1)
1246 {
1247 type2=type1.mid(i);
1248 type1=type1.left(i);
1249 }
1250 if (!a.attrib.isEmpty())
1251 {
1252 result+=a.attrib+" ";
1253 }
1254 if (!a.name.isEmpty() || !a.array.isEmpty())
1255 {
1256 result+= type1+" "+a.name+type2+a.array;
1257 }
1258 else
1259 {
1260 result+= type1+type2;
1261 }
1262 if (!a.defval.isEmpty() && showDefVals)
1263 {
1264 result+="="+a.defval;
1265 }
1266 ++it;
1267 if (it!=al.end()) result+=", ";
1268 }
1269 result+=")";
1270 if (al.constSpecifier()) result+=" const";
1271 if (al.volatileSpecifier()) result+=" volatile";
1272 if (al.refQualifier()==RefQualifierType::LValue) result+=" &";
1273 else if (al.refQualifier()==RefQualifierType::RValue) result+=" &&";
1274 if (!al.trailingReturnType().isEmpty()) result+=al.trailingReturnType();
1275 if (al.pureSpecifier()) result+=" =0";
1276 return removeRedundantWhiteSpace(result);
1277}
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
QCString 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
QCString mid(size_t index, size_t len=static_cast< size_t >(-1)) const
Definition qcstring.h:241
This class contains the information about the argument of a function or template.
Definition arguments.h:27
QCString type
Definition arguments.h:42
QCString name
Definition arguments.h:44
QCString defval
Definition arguments.h:46
QCString array
Definition arguments.h:45
QCString canType
Definition arguments.h:43
QCString attrib
Definition arguments.h:41
QCString removeRedundantWhiteSpace(const QCString &s)
Definition util.cpp:568

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

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

◆ checkBlocks()

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

Definition at line 6525 of file util.cpp.

6526{
6527 if (s.isEmpty()) return;
6528
6529 const char *p = s.data();
6530 char c = 0;
6531 while ((c=*p))
6532 {
6533 if (c==markerInfo.markerChar) // potential start of marker
6534 {
6535 if (qstrncmp(p,markerInfo.beginStr,markerInfo.beginLen)==0) // start of begin marker
6536 {
6537 size_t len = markerInfo.beginLen;
6538 bool negate = *(p+len)=='!';
6539 if (negate) len++;
6540 p += len;
6541 QCString marker;
6542 while (*p)
6543 {
6544 if (markerInfo.closeLen==0 && *p=='\n') // matching end of line
6545 {
6546 warn(fileName,-1,"Remaining begin replacement with marker '{}'",marker);
6547 break;
6548 }
6549 else if (markerInfo.closeLen!= 0 && qstrncmp(p,markerInfo.closeStr,markerInfo.closeLen)==0) // matching marker closing
6550 {
6551 p += markerInfo.closeLen;
6552 warn(fileName,-1,"Remaining begin replacement with marker '{}'",marker);
6553 break;
6554 }
6555 marker += *p;
6556 p++;
6557 }
6558 }
6559 else if (qstrncmp(p,markerInfo.endStr,markerInfo.endLen)==0) // start of end marker
6560 {
6561 size_t len = markerInfo.endLen;
6562 bool negate = *(p+len)=='!';
6563 if (negate) len++;
6564 p += len;
6565 QCString marker;
6566 while (*p)
6567 {
6568 if (markerInfo.closeLen==0 && *p=='\n') // matching end of line
6569 {
6570 warn(fileName,-1,"Remaining end replacement with marker '{}'",marker);
6571 break;
6572 }
6573 else if (markerInfo.closeLen!= 0 && qstrncmp(p,markerInfo.closeStr,markerInfo.closeLen)==0) // matching marker closing
6574 {
6575 p += markerInfo.closeLen;
6576 warn(fileName,-1,"Remaining end replacement with marker '{}'",marker);
6577 break;
6578 }
6579 marker += *p;
6580 p++;
6581 }
6582 }
6583 }
6584 p++;
6585 }
6586}
const char * data() const
Returns a pointer to the contents of the string in the form of a 0-terminated C string.
Definition qcstring.h:172
int qstrncmp(const char *str1, const char *str2, size_t len)
Definition qcstring.h:75
size_t beginLen
Definition util.h:188
const char * closeStr
Definition util.h:191
const char * beginStr
Definition util.h:187
size_t closeLen
Definition util.h:192
const char * endStr
Definition util.h:189

References SelectionMarkerInfo::beginLen, SelectionMarkerInfo::beginStr, SelectionMarkerInfo::closeLen, SelectionMarkerInfo::closeStr, QCString::data(), SelectionMarkerInfo::endLen, SelectionMarkerInfo::endStr, QCString::isEmpty(), SelectionMarkerInfo::markerChar, qstrncmp(), and warn.

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

◆ checkExtension()

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

Definition at line 4900 of file util.cpp.

4901{
4902 return fName.right(ext.length())==ext;
4903}

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

Referenced by copyLatexStyleSheet(), and extraLatexStyleSheet().

◆ checkIfTypedef()

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

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

Definition at line 5298 of file util.cpp.

5299{
5300 MemberDef *bestMatch = getMemberFromSymbol(scope,fileScope,n);
5301
5302 if (bestMatch && bestMatch->isTypedef())
5303 return TRUE; // closest matching symbol is a typedef
5304 else
5305 return FALSE;
5306}
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 QCString &n)
Definition util.cpp:5246

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

Referenced by isVarWithConstructor().

◆ cleanupInlineGraph()

void cleanupInlineGraph ( )

Definition at line 6993 of file util.cpp.

6994{
6995 if (Config_getBool(DOT_CLEANUP))
6996 {
6997 for (const auto& fileName: writeFileContents_set)
6998 {
6999 Dir().remove(qPrint(fileName));
7000 }
7001 }
7002}
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
#define Config_getBool(name)
Definition config.h:33
const char * qPrint(const char *s)
Definition qcstring.h:687
static StringUnorderedSet writeFileContents_set
Definition util.cpp:6952

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

Referenced by generateOutput().

◆ clearSubDirs()

void clearSubDirs ( const Dir & d)

Definition at line 3651 of file util.cpp.

3652{
3653 if (Config_getBool(CREATE_SUBDIRS))
3654 {
3655 // remove empty subdirectories
3656 int createSubdirsLevelPow2 = 1 << Config_getInt(CREATE_SUBDIRS_LEVEL);
3657 for (int l1=0;l1<16;l1++)
3658 {
3659 QCString subdir;
3660 subdir.sprintf("d%x",l1);
3661 for (int l2=0; l2 < createSubdirsLevelPow2; l2++)
3662 {
3663 QCString subsubdir;
3664 subsubdir.sprintf("d%x/d%02x",l1,l2);
3665 if (d.exists(subsubdir.str()) && d.isEmpty(subsubdir.str()))
3666 {
3667 d.rmdir(subsubdir.str());
3668 }
3669 }
3670 if (d.exists(subdir.str()) && d.isEmpty(subdir.str()))
3671 {
3672 d.rmdir(subdir.str());
3673 }
3674 }
3675 }
3676}
bool isEmpty(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
const std::string & str() const
Definition qcstring.h:552
QCString & sprintf(const char *format,...)
Definition qcstring.cpp:29
#define Config_getInt(name)
Definition config.h:34

References Config_getBool, Config_getInt, Dir::exists(), Dir::isEmpty(), Dir::rmdir(), QCString::sprintf(), and QCString::str().

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

◆ computeQualifiedIndex()

int computeQualifiedIndex ( const QCString & name)

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

Definition at line 6827 of file util.cpp.

6828{
6829 int l = static_cast<int>(name.length());
6830 int lastSepPos = -1;
6831 const char *p = name.data();
6832 int i=l-2;
6833 int sharpCount=0;
6834 // --- begin optimized version of ts=name.findRev(">::");
6835 int ts = -1;
6836 while (i>=0)
6837 {
6838 if (p[i]=='>')
6839 {
6840 if (sharpCount==0 && p[i+1]==':' && p[i+2]==':')
6841 {
6842 ts=i;
6843 break;
6844 }
6845 sharpCount++;
6846 }
6847 else if (p[i]=='<')
6848 {
6849 sharpCount--;
6850 }
6851 i--;
6852 }
6853 // --- end optimized version
6854 if (ts==-1) ts=0; else p+=++ts;
6855 for (i=ts;i<l-1;i++)
6856 {
6857 char c=*p++;
6858 if (c==':' && *p==':') lastSepPos=i;
6859 if (c=='<') break;
6860 }
6861 return lastSepPos;
6862}

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

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

◆ containsWord()

bool containsWord ( const QCString & s,
const char * word )

returns TRUE iff string s contains word w

Definition at line 4954 of file util.cpp.

4955{
4956 if (str.isEmpty() || word==nullptr) return false;
4957 static const reg::Ex re(R"(\a+)");
4958 std::string s = str.str();
4959 for (reg::Iterator it(s,re) ; it!=reg::Iterator() ; ++it)
4960 {
4961 if (it->str()==word) return true;
4962 }
4963 return false;
4964}
Class representing a regular expression.
Definition regex.h:39
Class to iterate through matches.
Definition regex.h:230

References QCString::isEmpty(), and QCString::str().

◆ convertCharEntitiesToUTF8()

QCString convertCharEntitiesToUTF8 ( const QCString & s)

Definition at line 4031 of file util.cpp.

4032{
4033 if (str.isEmpty()) return QCString();
4034
4035 std::string s = str.data();
4036 static const reg::Ex re(R"(&\a\w*;)");
4037 reg::Iterator it(s,re);
4039
4040 QCString result;
4041 result.reserve(str.length()+32);
4042 size_t p=0, i=0, l=0;
4043 for (; it!=end ; ++it)
4044 {
4045 const auto &match = *it;
4046 p = match.position();
4047 l = match.length();
4048 if (p>i)
4049 {
4050 result+=s.substr(i,p-i);
4051 }
4052 QCString entity(match.str());
4054 const char *code=nullptr;
4055 if (symType!=HtmlEntityMapper::Sym_Unknown && (code=HtmlEntityMapper::instance().utf8(symType)))
4056 {
4057 result+=code;
4058 }
4059 else
4060 {
4061 result+=entity;
4062 }
4063 i=p+l;
4064 }
4065 result+=s.substr(i);
4066 //printf("convertCharEntitiesToUTF8(%s)->%s\n",qPrint(s),qPrint(result));
4067 return result;
4068}
static HtmlEntityMapper & instance()
Returns the one and only instance of the HTML entity mapper.
SymType name2sym(const QCString &symName) const
Give code of the requested HTML entity name.
void reserve(size_t size)
Reserve space for size bytes without changing the string contents.
Definition qcstring.h:185
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:855

References QCString::data(), end(), HtmlEntityMapper::instance(), QCString::isEmpty(), QCString::length(), HtmlEntityMapper::name2sym(), QCString::reserve(), and HtmlEntityMapper::Sym_Unknown.

Referenced by convertToJSString(), generateSqlite3ForPage(), generateXMLForPage(), generateXMLForRequirement(), getSQLDocBlock(), and parseCommentAsText().

◆ convertFileNameFortranParserCode()

FortranFormat convertFileNameFortranParserCode ( QCString fn)

Definition at line 6399 of file util.cpp.

6400{
6402 QCString parserName = Doxygen::parserManager->getParserName(ext);
6403
6404 if (parserName == "fortranfixed") return FortranFormat::Fixed;
6405 else if (parserName == "fortranfree") return FortranFormat::Free;
6406
6408}
static ParserManager * parserManager
Definition doxygen.h:130
QCString getFileNameExtension(const QCString &fn)
Definition util.cpp:5236

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

◆ convertNameToFile()

QCString convertNameToFile ( const QCString & 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 3488 of file util.cpp.

3489{
3490 if (name.isEmpty()) return name;
3491 bool shortNames = Config_getBool(SHORT_NAMES);
3492 bool createSubdirs = Config_getBool(CREATE_SUBDIRS);
3493 QCString result;
3494 if (shortNames) // use short names only
3495 {
3496 std::lock_guard<std::mutex> lock(g_usedNamesMutex);
3497 auto kv = g_usedNames.find(name.str());
3498 uint32_t num=0;
3499 if (kv!=g_usedNames.end())
3500 {
3501 num = kv->second;
3502 }
3503 else
3504 {
3505 num = g_usedNamesCount;
3506 g_usedNames.emplace(name.str(),g_usedNamesCount++);
3507 }
3508 result.sprintf("a%05d",num);
3509 }
3510 else // long names
3511 {
3512 result=escapeCharsInString(name,allowDots,allowUnderscore);
3513 size_t resultLen = result.length();
3514 if (resultLen>=128) // prevent names that cannot be created!
3515 {
3516 // third algorithm based on MD5 hash
3517 uint8_t md5_sig[16];
3518 char sigStr[33];
3519 MD5Buffer(result.data(),static_cast<unsigned int>(resultLen),md5_sig);
3520 MD5SigToString(md5_sig,sigStr);
3521 result=result.left(128-32)+sigStr;
3522 }
3523 }
3524 if (createSubdirs)
3525 {
3526 int l1Dir=0,l2Dir=0;
3527 int createSubdirsLevel = Config_getInt(CREATE_SUBDIRS_LEVEL);
3528 int createSubdirsBitmaskL2 = (1<<createSubdirsLevel)-1;
3529
3530 // compute md5 hash to determine sub directory to use
3531 uint8_t md5_sig[16];
3532 MD5Buffer(result.data(),static_cast<unsigned int>(result.length()),md5_sig);
3533 l1Dir = md5_sig[14] & 0xf;
3534 l2Dir = md5_sig[15] & createSubdirsBitmaskL2;
3535
3536 result.prepend(QCString().sprintf("d%x/d%02x/",l1Dir,l2Dir));
3537 }
3538 //printf("*** convertNameToFile(%s)->%s\n",qPrint(name),qPrint(result));
3539 return result;
3540}
QCString & prepend(const char *s)
Definition qcstring.h:422
static int g_usedNamesCount
Definition util.cpp:3480
QCString escapeCharsInString(const QCString &name, bool allowDots, bool allowUnderscore)
Definition util.cpp:3313
static std::mutex g_usedNamesMutex
Definition util.cpp:3479
static std::unordered_map< std::string, int > g_usedNames
Definition util.cpp:3478

References Config_getBool, Config_getInt, QCString::data(), escapeCharsInString(), g_usedNames, g_usedNamesCount, g_usedNamesMutex, QCString::isEmpty(), QCString::left(), QCString::length(), QCString::prepend(), QCString::sprintf(), and QCString::str().

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

◆ convertProtectionLevel()

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

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

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

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

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

Definition at line 6232 of file util.cpp.

6238{
6239 bool extractPrivate = Config_getBool(EXTRACT_PRIVATE);
6240
6241 // default representing 1-1 mapping
6242 *outListType1=inListType;
6243 *outListType2=MemberListType::Invalid();
6244
6245 if (inProt==Protection::Public)
6246 {
6247 if (inListType.isPrivate())
6248 {
6249 *outListType1=MemberListType::Invalid();
6250 }
6251 }
6252 else if (inProt==Protection::Protected)
6253 {
6254 if (inListType.isPrivate() || inListType.isPublic())
6255 {
6256 *outListType1=MemberListType::Invalid();
6257 }
6258 else if (inListType.isProtected())
6259 {
6260 *outListType2=inListType.toPublic();
6261 }
6262 }
6263 else if (inProt==Protection::Private)
6264 {
6265 if (inListType.isPublic() || inListType.isProtected())
6266 {
6267 *outListType1=MemberListType::Invalid();
6268 }
6269 else if (inListType.isPrivate())
6270 {
6271 if (extractPrivate)
6272 {
6273 *outListType1=inListType.toPublic();
6274 *outListType2=inListType.toProtected();
6275 }
6276 else
6277 {
6278 *outListType1=MemberListType::Invalid();
6279 }
6280 }
6281 }
6282
6283 //printf("convertProtectionLevel(type=%s prot=%d): %s,%s\n",
6284 // qPrint(inListType.to_string()),inProt,qPrint(outListType1->to_string()),qPrint(outListType2->to_string()));
6285}
constexpr bool isPrivate() const noexcept
Definition types.h:382
constexpr MemberListType toPublic() const noexcept
Definition types.h:426
static constexpr MemberListType Invalid() noexcept
Definition types.h:371
constexpr MemberListType toProtected() const noexcept
Definition types.h:438
constexpr bool isProtected() const noexcept
Definition types.h:380
ML_TYPES constexpr bool isPublic() const noexcept
Definition types.h:378

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

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

◆ convertToHtml()

QCString convertToHtml ( const QCString & s,
bool keepEntities )

Converts a string to a HTML-encoded string

Definition at line 3947 of file util.cpp.

3948{
3949 if (s.isEmpty()) return s;
3950 QCString result;
3951 result.reserve(s.length()+32);
3952 const char *p=s.data();
3953 char c = 0;
3954 while ((c=*p++))
3955 {
3956 switch (c)
3957 {
3958 case '<': result+="&lt;"; break;
3959 case '>': result+="&gt;"; break;
3960 case '&': if (keepEntities)
3961 {
3962 const char *e=p;
3963 char ce = 0;
3964 while ((ce=*e++))
3965 {
3966 if (ce==';' || (!(isId(ce) || ce=='#'))) break;
3967 }
3968 if (ce==';') // found end of an entity
3969 {
3970 // copy entry verbatim
3971 result+=c;
3972 while (p<e) result+=*p++;
3973 }
3974 else
3975 {
3976 result+="&amp;";
3977 }
3978 }
3979 else
3980 {
3981 result+="&amp;";
3982 }
3983 break;
3984 case '\'': result+="&#39;"; break;
3985 case '"': result+="&quot;"; break;
3986 default:
3987 {
3988 uint8_t uc = static_cast<uint8_t>(c);
3989 if (uc<32 && !isspace(c))
3990 {
3991 result+="&#x24";
3992 result+=hex[uc>>4];
3993 result+=hex[uc&0xF];
3994 result+=';';
3995 }
3996 else
3997 {
3998 result+=c;
3999 }
4000 }
4001 break;
4002 }
4003 }
4004 return result;
4005}
static constexpr auto hex
bool isId(int c)
Definition util.h:208

References QCString::data(), hex, QCString::isEmpty(), isId(), QCString::length(), and QCString::reserve().

Referenced by HtmlCodeGenerator::_writeCodeLink(), HtmlHelp::addContentsItem(), addMembersToIndex(), convertToHtmlAndTruncate(), FTVHelp::Private::generateLink(), DefinitionImpl::navigationPathAsString(), 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()

QCString convertToId ( const QCString & s)

Converts a string to a HTML id string

Definition at line 3856 of file util.cpp.

3857{
3858 if (s.isEmpty()) return s;
3859 QCString result;
3860 result.reserve(s.length()+8);
3861 const char *p = s.data();
3862 char c = 0;
3863 bool first = true;
3864 while ((c=*p++))
3865 {
3866 char encChar[4];
3867 if ((c>='0' && c<='9') || (c>='a' && c<='z') || (c>='A' && c<='Z') || c=='-')
3868 { // any permissive character except _
3869 if (first && c>='0' && c<='9') result+='a'; // don't start with a digit
3870 result+=c;
3871 }
3872 else
3873 {
3874 encChar[0]='_';
3875 encChar[1]=hex[static_cast<unsigned char>(c)>>4];
3876 encChar[2]=hex[static_cast<unsigned char>(c)&0xF];
3877 encChar[3]=0;
3878 result+=encChar;
3879 }
3880 first=false;
3881 }
3882 return result;
3883}

References QCString::data(), hex, QCString::isEmpty(), QCString::length(), and QCString::reserve().

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

◆ convertToJSString()

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

Definition at line 4007 of file util.cpp.

4008{
4009 if (s.isEmpty()) return s;
4010 QCString result;
4011 result.reserve(s.length()+32);
4012 const char *p=s.data();
4013 char c = 0;
4014 while ((c=*p++))
4015 {
4016 switch (c)
4017 {
4018 case '"': if (!singleQuotes) result+="\\\""; else result+=c;
4019 break;
4020 case '\'': if (singleQuotes) result+="\\\'"; else result+=c;
4021 break;
4022 case '\\': if (*p=='u' && *(p+1)=='{') result+="\\"; // keep \u{..} unicode escapes
4023 else result+="\\\\";
4024 break;
4025 default: result+=c; break;
4026 }
4027 }
4028 return keepEntities ? result : convertCharEntitiesToUTF8(result);
4029}
QCString convertCharEntitiesToUTF8(const QCString &str)
Definition util.cpp:4031

References convertCharEntitiesToUTF8(), QCString::data(), QCString::isEmpty(), QCString::length(), and QCString::reserve().

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

◆ convertToXML()

QCString convertToXML ( const QCString & s,
bool keepEntities )

Converts a string to an XML-encoded string

Definition at line 3896 of file util.cpp.

3897{
3898 if (s.isEmpty()) return s;
3899 QCString result;
3900 result.reserve(s.length()+32);
3901 const char *p = s.data();
3902 char c = 0;
3903 while ((c=*p++))
3904 {
3905 switch (c)
3906 {
3907 case '<': result+="&lt;"; break;
3908 case '>': result+="&gt;"; break;
3909 case '&': if (keepEntities)
3910 {
3911 const char *e=p;
3912 char ce = 0;
3913 while ((ce=*e++))
3914 {
3915 if (ce==';' || (!(isId(ce) || ce=='#'))) break;
3916 }
3917 if (ce==';') // found end of an entity
3918 {
3919 // copy entry verbatim
3920 result+=c;
3921 while (p<e) result+=*p++;
3922 }
3923 else
3924 {
3925 result+="&amp;";
3926 }
3927 }
3928 else
3929 {
3930 result+="&amp;";
3931 }
3932 break;
3933 case '\'': result+="&apos;"; break;
3934 case '"': result+="&quot;"; break;
3935 case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8:
3936 case 11: case 12: case 13: case 14: case 15: case 16: case 17: case 18:
3937 case 19: case 20: case 21: case 22: case 23: case 24: case 25: case 26:
3938 case 27: case 28: case 29: case 30: case 31:
3939 break; // skip invalid XML characters (see http://www.w3.org/TR/2000/REC-xml-20001006#NT-Char)
3940 default: result+=c; break;
3941 }
3942 }
3943 return result;
3944}

References QCString::data(), QCString::isEmpty(), isId(), QCString::length(), and QCString::reserve().

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

◆ copyFile()

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

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

Returns TRUE if successful.

Definition at line 5860 of file util.cpp.

5861{
5862 if (!Dir().copy(src.str(),dest.str()))
5863 {
5864 err("could not copy file {} to {}\n",src,dest);
5865 return false;
5866 }
5867 return true;
5868}
#define err(fmt,...)
Definition message.h:127

References err, and QCString::str().

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

◆ correctId()

QCString correctId ( const QCString & s)

Some strings have been corrected but the requirement regarding the fact that an id cannot have a digit at the first position. To overcome problems with double labels we always place an "a" in front

Definition at line 3889 of file util.cpp.

3890{
3891 if (s.isEmpty()) return s;
3892 return "a" + s;
3893}

References QCString::isEmpty().

Referenced by DotGraph::generateCode(), and DotFilePatcher::run().

◆ correctURL()

QCString correctURL ( const QCString & url,
const QCString & 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 5928 of file util.cpp.

5929{
5930 QCString result = url;
5931 if (!relPath.isEmpty() && !isURL(url))
5932 {
5933 result.prepend(relPath);
5934 }
5935 return result;
5936}
bool isURL(const QCString &url)
Checks whether the given url starts with a supported protocol.
Definition util.cpp:5916

References QCString::isEmpty(), isURL(), and QCString::prepend().

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

◆ createHtmlUrl()

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

Definition at line 5719 of file util.cpp.

5725{
5726 QCString url;
5727 if (!ref.isEmpty())
5728 {
5729 url = externalRef(relPath,ref,href);
5730 }
5731 if (!targetFileName.isEmpty())
5732 {
5733 QCString fn = targetFileName;
5734 if (ref.isEmpty())
5735 {
5736 if (!anchor.isEmpty() && isLocalFile)
5737 {
5738 fn=""; // omit file name for local links
5739 }
5740 else
5741 {
5742 url = relPath;
5743 }
5744 }
5745 url+=fn;
5746 }
5747 if (!anchor.isEmpty())
5748 {
5749 if (!url.endsWith("=")) url+="#";
5750 url+=anchor;
5751 }
5752 //printf("createHtmlUrl(relPath=%s,local=%d,target=%s,anchor=%s)=%s\n",qPrint(relPath),isLocalFile,qPrint(targetFileName),qPrint(anchor),qPrint(url));
5753 return url;
5754}
QCString externalRef(const QCString &relPath, const QCString &ref, bool href)
Definition util.cpp:5756

References QCString::endsWith(), externalRef(), and QCString::isEmpty().

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

◆ createSubDirs()

void createSubDirs ( const Dir & d)

Definition at line 3624 of file util.cpp.

3625{
3626 if (Config_getBool(CREATE_SUBDIRS))
3627 {
3628 // create up to 4096 subdirectories
3629 int createSubdirsLevelPow2 = 1 << Config_getInt(CREATE_SUBDIRS_LEVEL);
3630 for (int l1=0; l1<16; l1++)
3631 {
3632 QCString subdir;
3633 subdir.sprintf("d%x",l1);
3634 if (!d.exists(subdir.str()) && !d.mkdir(subdir.str()))
3635 {
3636 term("Failed to create output directory '{}'\n",subdir);
3637 }
3638 for (int l2=0; l2<createSubdirsLevelPow2; l2++)
3639 {
3640 QCString subsubdir;
3641 subsubdir.sprintf("d%x/d%02x",l1,l2);
3642 if (!d.exists(subsubdir.str()) && !d.mkdir(subsubdir.str()))
3643 {
3644 term("Failed to create output directory '{}'\n",subsubdir);
3645 }
3646 }
3647 }
3648 }
3649}
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, Dir::exists(), Dir::mkdir(), QCString::sprintf(), QCString::str(), and term.

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

◆ demangleCSharpGenericName()

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

Definition at line 6926 of file util.cpp.

6927{
6928 QCString result=name;
6929 if (result.endsWith("-g"))
6930 {
6931 int idx = result.find('-');
6932 result = result.left(idx)+templArgs;
6933 }
6934 return result;
6935}

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

Referenced by ClassDefImpl::className().

◆ detab()

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

Definition at line 6723 of file util.cpp.

6724{
6725 int tabSize = Config_getInt(TAB_SIZE);
6726 size_t size = s.length();
6727 QCString result;
6728 result.reserve(size+256);
6729 const char *data = s.data();
6730 size_t i=0;
6731 int col=0;
6732 constexpr auto doxy_nbsp = "&_doxy_nbsp;"; // doxygen escape command for UTF-8 nbsp
6733 const int maxIndent=1000000; // value representing infinity
6734 int minIndent=maxIndent;
6735 bool skip = false;
6736 while (i<size)
6737 {
6738 char c = data[i++];
6739 switch(c)
6740 {
6741 case '\t': // expand tab
6742 {
6743 int stop = tabSize - (col%tabSize);
6744 //printf("expand at %d stop=%d\n",col,stop);
6745 col+=stop;
6746 while (stop--) result+=' ';
6747 }
6748 break;
6749 case '\\':
6750 if (data[i] == '\\') // escaped command -> ignore
6751 {
6752 result+=c;
6753 result+=data[i++];
6754 col+=2;
6755 }
6756 else if (i+5<size && literal_at(data+i,"iskip")) // command
6757 {
6758 i+=5;
6759 skip = true;
6760 }
6761 else if (i+8<size && literal_at(data+i,"endiskip")) // command
6762 {
6763 i+=8;
6764 skip = false;
6765 }
6766 else // some other command
6767 {
6768 result+=c;
6769 col++;
6770 }
6771 break;
6772 case '\n': // reset column counter
6773 result+=c;
6774 col=0;
6775 break;
6776 case ' ': // increment column counter
6777 result+=c;
6778 col++;
6779 break;
6780 default: // non-whitespace => update minIndent
6781 if (c<0 && i<size) // multibyte sequence
6782 {
6783 // special handling of the UTF-8 nbsp character 0xC2 0xA0
6784 int nb = isUTF8NonBreakableSpace(data);
6785 if (nb>0)
6786 {
6787 result+=doxy_nbsp;
6788 i+=nb-1;
6789 }
6790 else
6791 {
6792 int bytes = getUTF8CharNumBytes(c);
6793 for (int j=0;j<bytes-1 && c;j++)
6794 {
6795 result+=c;
6796 c = data[i++];
6797 }
6798 result+=c;
6799 }
6800 }
6801 else
6802 {
6803 result+=c;
6804 }
6805 if (!skip && col<minIndent) minIndent=col;
6806 col++;
6807 }
6808 }
6809 if (minIndent!=maxIndent) refIndent=minIndent; else refIndent=0;
6810 //printf("detab(\n%s\n)=[\n%s\n]\n",qPrint(s),qPrint(out.get()));
6811 return result;
6812}
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:98
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, QCString::data(), getUTF8CharNumBytes(), isUTF8NonBreakableSpace(), QCString::length(), literal_at(), and QCString::reserve().

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

◆ determineAbsoluteIncludeName()

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

Definition at line 3584 of file util.cpp.

3585{
3586 bool searchIncludes = Config_getBool(SEARCH_INCLUDES);
3587 QCString absIncFileName = incFileName;
3588 FileInfo fi(curFile.str());
3589 if (fi.exists())
3590 {
3591 QCString absName = fi.dirPath(TRUE)+"/"+incFileName;
3592 FileInfo fi2(absName.str());
3593 if (fi2.exists())
3594 {
3595 absIncFileName=fi2.absFilePath();
3596 }
3597 else if (searchIncludes) // search in INCLUDE_PATH as well
3598 {
3599 const StringVector &includePath = Config_getList(INCLUDE_PATH);
3600 for (const auto &incPath : includePath)
3601 {
3602 FileInfo fi3(incPath);
3603 if (fi3.exists() && fi3.isDir())
3604 {
3605 absName = fi3.absFilePath()+"/"+incFileName;
3606 //printf("trying absName=%s\n",qPrint(absName));
3607 FileInfo fi4(absName.str());
3608 if (fi4.exists())
3609 {
3610 absIncFileName=fi4.absFilePath();
3611 break;
3612 }
3613 //printf( "absIncFileName = %s\n", qPrint(absIncFileName) );
3614 }
3615 }
3616 }
3617 //printf( "absIncFileName = %s\n", qPrint(absIncFileName) );
3618 }
3619 return absIncFileName;
3620}
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, FileInfo::dirPath(), FileInfo::exists(), FileInfo::isDir(), QCString::str(), and TRUE.

Referenced by ModuleManager::resolveImports().

◆ escapeCharsInString()

QCString escapeCharsInString ( const QCString & name,
bool allowDots,
bool allowUnderscore = FALSE )

Definition at line 3313 of file util.cpp.

3314{
3315 if (name.isEmpty()) return name;
3316 bool caseSenseNames = getCaseSenseNames();
3317 bool allowUnicodeNames = Config_getBool(ALLOW_UNICODE_NAMES);
3318 QCString result;
3319 result.reserve(name.length()+8);
3320 signed char c = 0;
3321 const char *p=name.data();
3322 while ((c=*p++)!=0)
3323 {
3324 switch(c)
3325 {
3326 case '_': if (allowUnderscore) result+='_'; else result+="__"; break;
3327 case '-': result+='-'; break;
3328 case ':': result+="_1"; break;
3329 case '/': result+="_2"; break;
3330 case '<': result+="_3"; break;
3331 case '>': result+="_4"; break;
3332 case '*': result+="_5"; break;
3333 case '&': result+="_6"; break;
3334 case '|': result+="_7"; break;
3335 case '.': if (allowDots) result+='.'; else result+="_8"; break;
3336 case '!': result+="_9"; break;
3337 case ',': result+="_00"; break;
3338 case ' ': result+="_01"; break;
3339 case '{': result+="_02"; break;
3340 case '}': result+="_03"; break;
3341 case '?': result+="_04"; break;
3342 case '^': result+="_05"; break;
3343 case '%': result+="_06"; break;
3344 case '(': result+="_07"; break;
3345 case ')': result+="_08"; break;
3346 case '+': result+="_09"; break;
3347 case '=': result+="_0a"; break;
3348 case '$': result+="_0b"; break;
3349 case '\\': result+="_0c"; break;
3350 case '@': result+="_0d"; break;
3351 case ']': result+="_0e"; break;
3352 case '[': result+="_0f"; break;
3353 case '#': result+="_0g"; break;
3354 case '"': result+="_0h"; break;
3355 case '~': result+="_0i"; break;
3356 case '\'': result+="_0j"; break;
3357 case ';': result+="_0k"; break;
3358 case '`': result+="_0l"; break;
3359 default:
3360 if (c<0)
3361 {
3362 bool doEscape = true;
3363 if (allowUnicodeNames)
3364 {
3365 int charLen = getUTF8CharNumBytes(c);
3366 if (charLen>0)
3367 {
3368 result+=QCString(p-1,charLen);
3369 p+=charLen;
3370 doEscape = false;
3371 }
3372 }
3373 if (doEscape) // not a valid unicode char or escaping needed
3374 {
3375 char ids[5];
3376 unsigned char id = static_cast<unsigned char>(c);
3377 ids[0]='_';
3378 ids[1]='x';
3379 ids[2]=hex[id>>4];
3380 ids[3]=hex[id&0xF];
3381 ids[4]=0;
3382 result+=ids;
3383 }
3384 }
3385 else if (caseSenseNames || !isupper(c))
3386 {
3387 result+=c;
3388 }
3389 else
3390 {
3391 result+='_';
3392 result+=static_cast<char>(tolower(c));
3393 }
3394 break;
3395 }
3396 }
3397 return result;
3398}
bool getCaseSenseNames()
Definition util.cpp:3304

References Config_getBool, QCString::data(), getCaseSenseNames(), getUTF8CharNumBytes(), hex, QCString::isEmpty(), QCString::length(), and QCString::reserve().

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

◆ externalLinkTarget()

QCString externalLinkTarget ( const bool parent = false)

Definition at line 5708 of file util.cpp.

5709{
5710 bool extLinksInWindow = Config_getBool(EXT_LINKS_IN_WINDOW);
5711 if (extLinksInWindow)
5712 return "target=\"_blank\" ";
5713 else if (parent)
5714 return "target=\"_parent\" ";
5715 else
5716 return "";
5717}
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:1327

References Config_getBool, and parent().

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

◆ externalRef()

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

Definition at line 5756 of file util.cpp.

5757{
5758 QCString result;
5759 if (!ref.isEmpty())
5760 {
5761 auto it = Doxygen::tagDestinationMap.find(ref.str());
5763 {
5764 result = it->second;
5765 size_t l = result.length();
5766 if (!relPath.isEmpty() && l>0 && result.at(0)=='.')
5767 { // relative path -> prepend relPath.
5768 result.prepend(relPath);
5769 l+=relPath.length();
5770 }
5771 if (l>0 && result.at(l-1)!='/') result+='/';
5772 if (!href) result.append("\" ");
5773 }
5774 }
5775 else
5776 {
5777 result = relPath;
5778 }
5779 return result;
5780}
static StringMap tagDestinationMap
Definition doxygen.h:115
char & at(size_t i)
Returns a reference to the character at index i.
Definition qcstring.h:593
QCString & append(char c)
Definition qcstring.h:396

References QCString::append(), QCString::at(), end(), QCString::isEmpty(), QCString::length(), QCString::prepend(), QCString::str(), and Doxygen::tagDestinationMap.

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

◆ extractBeginRawStringDelimiter()

QCString extractBeginRawStringDelimiter ( const char * rawStart)

Definition at line 6937 of file util.cpp.

6938{
6939 QCString text=rawStart;
6940 int i = text.find('"');
6941 assert(i!=-1);
6942 return text.mid(i+1,text.length()-i-2); // text=...R"xyz( -> delimiter=xyz
6943}

References QCString::find(), QCString::length(), and QCString::mid().

◆ extractClassNameFromType()

int extractClassNameFromType ( const QCString & type,
int & pos,
QCString & name,
QCString & 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 4199 of file util.cpp.

4200{
4201 AUTO_TRACE("type='{}' name='{}' lang={}",type,name,lang);
4202 static const reg::Ex re_norm(R"(\a[\w:]*)");
4203 static const reg::Ex re_fortran(R"(\a[\w:()=]*)");
4204 const reg::Ex *re = &re_norm;
4205
4206 name.clear();
4207 templSpec.clear();
4208 if (type.isEmpty())
4209 {
4210 AUTO_TRACE_EXIT("empty type");
4211 return -1;
4212 }
4213 size_t typeLen=type.length();
4214 if (typeLen>0)
4215 {
4216 if (lang == SrcLangExt::Fortran)
4217 {
4218 if (type[pos]==',')
4219 {
4220 AUTO_TRACE_EXIT("comma");
4221 return -1;
4222 }
4223 if (!type.lower().startsWith("type"))
4224 {
4225 re = &re_fortran;
4226 }
4227 }
4228 std::string s = type.str();
4229 reg::Iterator it(s,*re,static_cast<int>(pos));
4231
4232 if (it!=end)
4233 {
4234 const auto &match = *it;
4235 size_t i = match.position();
4236 size_t l = match.length();
4237 size_t ts = i+l;
4238 size_t te = ts;
4239 size_t tl = 0;
4240
4241 while (ts<typeLen && type[static_cast<uint32_t>(ts)]==' ') { ts++; tl++; } // skip any whitespace
4242 if (ts<typeLen && type[static_cast<uint32_t>(ts)]=='<') // assume template instance
4243 {
4244 // locate end of template
4245 te=ts+1;
4246 int brCount=1;
4247 while (te<typeLen && brCount!=0)
4248 {
4249 if (type[static_cast<uint32_t>(te)]=='<')
4250 {
4251 if (te<typeLen-1 && type[static_cast<uint32_t>(te)+1]=='<') te++; else brCount++;
4252 }
4253 if (type[static_cast<uint32_t>(te)]=='>')
4254 {
4255 if (te<typeLen-1 && type[static_cast<uint32_t>(te)+1]=='>') te++; else brCount--;
4256 }
4257 te++;
4258 }
4259 }
4260 name = match.str();
4261 if (te>ts)
4262 {
4263 templSpec = QCString(type).mid(ts,te-ts);
4264 tl+=te-ts;
4265 pos=static_cast<int>(i+l+tl);
4266 }
4267 else // no template part
4268 {
4269 pos=static_cast<int>(i+l);
4270 }
4271 //printf("extractClassNameFromType([in] type=%s,[out] pos=%d,[out] name=%s,[out] templ=%s)=TRUE i=%d\n",
4272 // qPrint(type),pos,qPrint(name),qPrint(templSpec),i);
4273 AUTO_TRACE_EXIT("pos={} templSpec='{}' return={}",pos,templSpec,i);
4274 return static_cast<int>(i);
4275 }
4276 }
4277 pos = static_cast<int>(typeLen);
4278 //printf("extractClassNameFromType([in] type=%s,[out] pos=%d,[out] name=%s,[out] templ=%s)=FALSE\n",
4279 // qPrint(type),pos,qPrint(name),qPrint(templSpec));
4280 AUTO_TRACE_EXIT("not found");
4281 return -1;
4282}
bool startsWith(const char *s) const
Definition qcstring.h:507
QCString lower() const
Definition qcstring.h:249
void clear()
Definition qcstring.h:182
#define AUTO_TRACE(...)
Definition docnode.cpp:47
#define AUTO_TRACE_EXIT(...)
Definition docnode.cpp:49

References AUTO_TRACE, AUTO_TRACE_EXIT, QCString::clear(), end(), QCString::isEmpty(), QCString::length(), QCString::lower(), QCString::mid(), QCString::startsWith(), and QCString::str().

Referenced by extractCanonicalType(), and findUsedClassesForClass().

◆ extractDirection()

QCString extractDirection ( QCString & docs)

Strip the direction part from docs and return it as a string in canonical form The input docs string can start with e.g.

"[in]", "[in, out]", "[inout]", "[out,in]"...

Returns
either "[in,out]", "[in]", or "[out]" or the empty string.

Definition at line 6181 of file util.cpp.

6182{
6183 std::string s = docs.str();
6184 static const reg::Ex re(R"(\‍[([ inout,]+)\‍])");
6185 reg::Iterator it(s,re);
6187 if (it!=end)
6188 {
6189 const auto &match = *it;
6190 size_t p = match.position();
6191 size_t l = match.length();
6192 if (p==0 && l>2)
6193 {
6194 // make dir the part inside [...] without separators
6195 std::string dir = match[1].str();
6196 // strip , and ' ' from dir
6197 dir.erase(std::remove_if(dir.begin(),dir.end(),
6198 [](const char c) { return c==' ' || c==','; }
6199 ),dir.end());
6200 unsigned char ioMask=0;
6201 size_t inIndex = dir.find( "in");
6202 if ( inIndex!=std::string::npos) { dir.erase( inIndex,2); ioMask|=(1<<0); }
6203 size_t outIndex = dir.find("out");
6204 if (outIndex!=std::string::npos) { dir.erase(outIndex,3); ioMask|=(1<<1); }
6205 if (dir.empty() && ioMask!=0) // only in and/or out attributes found
6206 {
6207 docs = s.substr(l); // strip attributes
6208 if (ioMask==((1<<0)|(1<<1))) return "[in,out]";
6209 else if (ioMask==(1<<0)) return "[in]";
6210 else if (ioMask==(1<<1)) return "[out]";
6211 }
6212 }
6213 }
6214 return "";
6215}

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

Referenced by inlineArgListToDoc().

◆ extractEndRawStringDelimiter()

QCString extractEndRawStringDelimiter ( const char * rawEnd)

Definition at line 6945 of file util.cpp.

6946{
6947 QCString text=rawEnd;
6948 return text.mid(1,text.length()-2); // text=)xyz" -> delimiter=xyz
6949}

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

◆ extractNamespaceName()

void extractNamespaceName ( const QCString & scopeName,
QCString & className,
QCString & 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 3681 of file util.cpp.

3684{
3685 int i=0, p=0;
3686 QCString clName=scopeName;
3687 NamespaceDef *nd = nullptr;
3688 if (!clName.isEmpty() && (nd=getResolvedNamespace(clName)) && getClass(clName)==nullptr)
3689 { // the whole name is a namespace (and not a class)
3690 namespaceName=nd->name();
3691 className.clear();
3692 goto done;
3693 }
3694 p=static_cast<int>(clName.length())-2;
3695 while (p>=0 && (i=clName.findRev("::",p))!=-1)
3696 // see if the first part is a namespace (and not a class)
3697 {
3698 //printf("Trying %s\n",qPrint(clName.left(i)));
3699 if (i>0 && (nd=getResolvedNamespace(clName.left(i))) && getClass(clName.left(i))==nullptr)
3700 {
3701 //printf("found!\n");
3702 namespaceName=nd->name();
3703 className=clName.right(clName.length()-i-2);
3704 goto done;
3705 }
3706 p=i-2; // try a smaller piece of the scope
3707 }
3708 //printf("not found!\n");
3709
3710 // not found, so we just have to guess.
3711 className=scopeName;
3712 namespaceName.clear();
3713
3714done:
3715 if (className.isEmpty() && !namespaceName.isEmpty() && !allowEmptyClass)
3716 {
3717 // class and namespace with the same name, correct to return the class.
3718 className=namespaceName;
3719 namespaceName.clear();
3720 }
3721 //printf("extractNamespace '%s' => '%s|%s'\n",qPrint(scopeName),
3722 // qPrint(className),qPrint(namespaceName));
3723 if (className.endsWith("-p"))
3724 {
3725 className = className.left(className.length()-2);
3726 }
3727 return;
3728}
An abstract interface of a namespace symbol.
ClassDef * getClass(const QCString &n)
NamespaceDef * getResolvedNamespace(const QCString &name)

References QCString::clear(), QCString::endsWith(), QCString::findRev(), getClass(), getResolvedNamespace(), QCString::isEmpty(), QCString::left(), QCString::length(), Definition::name(), and QCString::right().

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

◆ fileToString()

QCString fileToString ( const QCString & name,
bool filter,
bool isSourceCode )

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

1475{
1476 if (name.isEmpty()) return QCString();
1477 bool fileOpened=false;
1478 if (name[0]=='-' && name[1]==0) // read from stdin
1479 {
1480 std::string contents;
1481 std::string line;
1482 while (getline(std::cin,line))
1483 {
1484 contents+=line+'\n';
1485 }
1486 return contents;
1487 }
1488 else // read from file
1489 {
1490 FileInfo fi(name.str());
1491 if (!fi.exists() || !fi.isFile())
1492 {
1493 err("file '{}' not found\n",name);
1494 return "";
1495 }
1496 std::string buf;
1497 fileOpened=readInputFile(name,buf,filter,isSourceCode);
1498 if (fileOpened)
1499 {
1500 addTerminalCharIfMissing(buf,'\n');
1501 return buf;
1502 }
1503 }
1504 if (!fileOpened)
1505 {
1506 err("cannot open file '{}' for reading\n",name);
1507 }
1508 return "";
1509}
void addTerminalCharIfMissing(std::string &s, char c)
Definition stringutil.h:84
bool readInputFile(const QCString &fileName, std::string &contents, bool filter, bool isSourceCode)
read a file name fileName and optionally filter and transcode it
Definition util.cpp:5533

References addTerminalCharIfMissing(), err, FileInfo::exists(), QCString::isEmpty(), FileInfo::isFile(), readInputFile(), and QCString::str().

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

◆ fileVisibleInIndex()

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

Definition at line 6092 of file util.cpp.

6093{
6094 bool allExternals = Config_getBool(ALLEXTERNALS);
6095 bool isDocFile = fd->isDocumentationFile();
6096 genSourceFile = !isDocFile && fd->generateSourceFile();
6097 return ( ((allExternals && fd->isLinkable()) ||
6099 ) &&
6100 !isDocFile
6101 );
6102}
virtual bool isLinkable() const =0
virtual bool isLinkableInProject() const =0
virtual bool generateSourceFile() const =0
virtual bool isDocumentationFile() const =0

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

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

◆ filterTitle()

QCString filterTitle ( const QCString & title)

Definition at line 5613 of file util.cpp.

5614{
5615 std::string tf;
5616 std::string t = title.str();
5617 static const reg::Ex re(R"(%[a-z_A-Z]+)");
5618 reg::Iterator it(t,re);
5620 size_t p = 0;
5621 for (; it!=end ; ++it)
5622 {
5623 const auto &match = *it;
5624 size_t i = match.position();
5625 size_t l = match.length();
5626 if (i>p) tf+=t.substr(p,i-p);
5627 tf+=match.str().substr(1); // skip %
5628 p=i+l;
5629 }
5630 tf+=t.substr(p);
5631 return tf;
5632}

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

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

◆ findAndRemoveWord()

bool findAndRemoveWord ( QCString & 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 4970 of file util.cpp.

4971{
4972 static reg::Ex re(R"(\s*(<\a+>)\s*)");
4973 std::string s = sentence.str();
4974 reg::Iterator it(s,re);
4976 std::string result;
4977 bool found=false;
4978 size_t p=0;
4979 for ( ; it!=end ; ++it)
4980 {
4981 const auto match = *it;
4982 std::string part = match[1].str();
4983 if (part!=word)
4984 {
4985 size_t i = match.position();
4986 size_t l = match.length();
4987 result+=s.substr(p,i-p);
4988 result+=match.str();
4989 p=i+l;
4990 }
4991 else
4992 {
4993 found=true;
4994 size_t i = match[1].position();
4995 size_t l = match[1].length();
4996 result+=s.substr(p,i-p);
4997 p=i+l;
4998 }
4999 }
5000 result+=s.substr(p);
5001 sentence = QCString(result).simplifyWhiteSpace();
5002 return found;
5003}
QCString simplifyWhiteSpace() const
return a copy of this string with leading and trailing whitespace removed and multiple whitespace cha...
Definition qcstring.cpp:190

References end(), QCString::simplifyWhiteSpace(), and QCString::str().

Referenced by isVarWithConstructor().

◆ findFileDef()

FileDef * findFileDef ( const FileNameLinkedMap * fnMap,
const QCString & n,
bool & ambig )

Definition at line 2874 of file util.cpp.

2875{
2876 ambig=FALSE;
2877 if (n.isEmpty()) return nullptr;
2878
2879
2880 const int maxAddrSize = 20;
2881 char addr[maxAddrSize];
2882 qsnprintf(addr,maxAddrSize,"%p:",reinterpret_cast<const void*>(fnMap));
2883 QCString key = addr;
2884 key+=n;
2885
2886 std::lock_guard<std::mutex> lock(g_findFileDefMutex);
2887 FindFileCacheElem *cachedResult = g_findFileDefCache.find(key.str());
2888 //printf("key=%s cachedResult=%p\n",qPrint(key),cachedResult);
2889 if (cachedResult)
2890 {
2891 ambig = cachedResult->isAmbig;
2892 //printf("cached: fileDef=%p\n",cachedResult->fileDef);
2893 return cachedResult->fileDef;
2894 }
2895 else
2896 {
2897 cachedResult = g_findFileDefCache.insert(key.str(),FindFileCacheElem(nullptr,FALSE));
2898 }
2899
2900 QCString name=Dir::cleanDirPath(n.str());
2901 QCString path;
2902 if (name.isEmpty()) return nullptr;
2903 int slashPos=std::max(name.findRev('/'),name.findRev('\\'));
2904 if (slashPos!=-1)
2905 {
2906 path=removeLongPathMarker(name.left(slashPos+1));
2907 name=name.right(name.length()-slashPos-1);
2908 }
2909 if (name.isEmpty()) return nullptr;
2910 const FileName *fn = fnMap->find(name);
2911 if (fn)
2912 {
2913 //printf("fn->size()=%zu\n",fn->size());
2914 if (fn->size()==1)
2915 {
2916 const std::unique_ptr<FileDef> &fd = fn->front();
2917 bool isSamePath = Portable::fileSystemIsCaseSensitive() ?
2918 fd->getPath().right(path.length())==path :
2919 fd->getPath().right(path.length()).lower()==path.lower();
2920 if (path.isEmpty() || isSamePath)
2921 {
2922 cachedResult->fileDef = fd.get();
2923 return fd.get();
2924 }
2925 }
2926 else // file name alone is ambiguous
2927 {
2928 int count=0;
2929 FileDef *lastMatch=nullptr;
2930 QCString pathStripped = stripFromIncludePath(path);
2931 for (const auto &fd_p : *fn)
2932 {
2933 FileDef *fd = fd_p.get();
2934 QCString fdStripPath = stripFromIncludePath(fd->getPath());
2935 if (path.isEmpty() ||
2936 (!pathStripped.isEmpty() && fdStripPath.endsWith(pathStripped)) ||
2937 (pathStripped.isEmpty() && fdStripPath.isEmpty()))
2938 {
2939 count++;
2940 lastMatch=fd;
2941 }
2942 }
2943
2944 ambig=(count>1);
2945 cachedResult->isAmbig = ambig;
2946 cachedResult->fileDef = lastMatch;
2947 return lastMatch;
2948 }
2949 }
2950 else
2951 {
2952 //printf("not found!\n");
2953 }
2954 return nullptr;
2955}
static std::string cleanDirPath(const std::string &path)
Definition dir.cpp:357
A model of a file symbol.
Definition filedef.h:99
virtual QCString getPath() const =0
Class representing all files with a certain base name.
Definition filename.h:30
bool fileSystemIsCaseSensitive()
Definition portable.cpp:471
#define qsnprintf
Definition qcstring.h:49
Cache element for the file name to FileDef mapping cache.
Definition util.cpp:2864
FileDef * fileDef
Definition util.cpp:2866
QCString stripFromIncludePath(const QCString &path)
Definition util.cpp:330
static Cache< std::string, FindFileCacheElem > g_findFileDefCache(5000)
static std::mutex g_findFileDefMutex
Definition util.cpp:2872
QCString removeLongPathMarker(QCString path)
Definition util.cpp:288

References Dir::cleanDirPath(), QCString::endsWith(), FALSE, FindFileCacheElem::fileDef, Portable::fileSystemIsCaseSensitive(), LinkedMap< T, Hash, KeyEqual, Map >::find(), QCString::findRev(), g_findFileDefCache, g_findFileDefMutex, FileDef::getPath(), FindFileCacheElem::isAmbig, QCString::isEmpty(), QCString::left(), QCString::length(), QCString::lower(), qsnprintf, removeLongPathMarker(), QCString::right(), QCString::str(), and stripFromIncludePath().

Referenced by addIncludeFile(), buildFileList(), checkMarkdownMainfile(), DocParser::findAndCopyImage(), DocParser::findDocsForMemberOrCompound(), findFilePath(), generateFileRef(), generateFileSources(), DocParser::handleLinkedWord(), DocbookDocVisitor::operator()(), XmlDocVisitor::operator()(), DocDiaFile::parse(), DocDotFile::parse(), DocMscFile::parse(), DocPlantUmlFile::parse(), parseFilesMultiThreading(), parseFilesSingleThreading(), Markdown::Private::processLink(), readTextFileByName(), ModuleManager::resolveImports(), resolveLink(), ModuleManager::resolvePartitions(), and resolveRef().

◆ findFilePath()

QCString findFilePath ( const QCString & file,
bool & ambig )

Definition at line 2959 of file util.cpp.

2960{
2961 ambig=false;
2962 QCString result;
2963 bool found=false;
2964 if (!found)
2965 {
2966 FileInfo fi(file.str());
2967 if (fi.exists())
2968 {
2969 result=fi.absFilePath();
2970 found=true;
2971 }
2972 }
2973 if (!found)
2974 {
2975 const StringVector &examplePathList = Config_getList(EXAMPLE_PATH);
2976 for (const auto &s : examplePathList)
2977 {
2978 std::string absFileName = s+(Portable::pathSeparator()+file).str();
2979 FileInfo fi(absFileName);
2980 if (fi.exists())
2981 {
2982 result=fi.absFilePath();
2983 found=true;
2984 }
2985 }
2986 }
2987
2988 if (!found)
2989 {
2990 // as a fallback we also look in the exampleNameDict
2992 if (fd && !ambig)
2993 {
2994 result=fd->absFilePath();
2995 }
2996 }
2997 return result;
2998}
static FileNameLinkedMap * exampleNameLinkedMap
Definition doxygen.h:102
virtual QCString absFilePath() const =0
QCString pathSeparator()
Definition portable.cpp:375
FileDef * findFileDef(const FileNameLinkedMap *fnMap, const QCString &n, bool &ambig)
Definition util.cpp:2874

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

Referenced by DocParser::readTextFileByName().

◆ findIndex() [1/2]

int findIndex ( const std::string & s,
const reg::Ex & re )

find the index of the first occurrence of pattern re in a string s returns -1 if the pattern could not be found

Definition at line 6665 of file util.cpp.

6666{
6668 return reg::search(s,match,re) ? static_cast<int>(match.position()) : -1;
6669}
Object representing the matching results.
Definition regex.h:151
bool search(std::string_view str, Match &match, const Ex &re, size_t pos)
Search in a given string str starting at position pos for a match against regular expression re.
Definition regex.cpp:844

References reg::search().

◆ findIndex() [2/2]

int findIndex ( const StringVector & sv,
const std::string & s )

find the index of a string in a vector of strings, returns -1 if the string could not be found

Definition at line 6657 of file util.cpp.

6658{
6659 auto it = std::find(sv.begin(),sv.end(),s);
6660 return it!=sv.end() ? static_cast<int>(it-sv.begin()) : -1;
6661}

Referenced by initUCF(), VhdlDocGen::parseForBinding(), VhdlDocGen::parseUCF(), DotFilePatcher::run(), and VhdlDocGen::writeFormatString().

◆ fixSpaces()

QCString fixSpaces ( const QCString & s)
inline

Definition at line 474 of file util.h.

474{ return substitute(s," ","&#160;"); }
QCString substitute(const QCString &s, const QCString &src, const QCString &dst)
substitute all occurrences of src in s by dst
Definition qcstring.cpp:571

References substitute().

Referenced by renderQuickLinksAsTabs(), renderQuickLinksAsTree(), writeClassMemberIndexFiltered(), writeFileMemberIndexFiltered(), writeModuleMemberIndexFiltered(), writeNamespaceMemberIndexFiltered(), and writeUserGroupStubPage().

◆ generateAnonymousAnchor()

QCString generateAnonymousAnchor ( const QCString & fileName,
int count )

Definition at line 3542 of file util.cpp.

3543{
3544 QCString fn = stripFromPath(fileName)+":"+QCString().setNum(count);
3545 const int sig_size=16;
3546 uint8_t md5_sig[sig_size];
3547 MD5Buffer(fn.data(),static_cast<unsigned int>(fn.length()),md5_sig);
3548 char result[sig_size*3+2];
3549 char *p = result;
3550 *p++='@';
3551 for (int i=0;i<sig_size;i++)
3552 {
3553 static const char oct[]="01234567";
3554 uint8_t byte = md5_sig[i];
3555 *p++=oct[(byte>>6)&7];
3556 *p++=oct[(byte>>3)&7];
3557 *p++=oct[(byte>>0)&7];
3558 }
3559 *p='\0';
3560 return result;
3561}
QCString & setNum(short n)
Definition qcstring.h:459
static QCString stripFromPath(const QCString &p, const StringVector &l)
Definition util.cpp:299

References QCString::data(), QCString::length(), QCString::setNum(), and stripFromPath().

◆ generateFileRef()

void generateFileRef ( OutputList & ol,
const QCString & name,
const QCString & linkTxt = QCString() )

Definition at line 2846 of file util.cpp.

2847{
2848 //printf("generateFileRef(%s,%s)\n",name,text);
2849 QCString linkText = text.isEmpty() ? text : name;
2850 //FileInfo *fi;
2851 bool ambig = false;
2853 if (fd && fd->isLinkable())
2854 // link to documented input file
2855 ol.writeObjectLink(fd->getReference(),fd->getOutputFileBase(),QCString(),linkText);
2856 else
2857 ol.docify(linkText);
2858}
static FileNameLinkedMap * inputNameLinkedMap
Definition doxygen.h:104
void writeObjectLink(const QCString &ref, const QCString &file, const QCString &anchor, const QCString &name)
Definition outputlist.h:439
void docify(const QCString &s)
Definition outputlist.h:437

References OutputList::docify(), findFileDef(), Definition::getOutputFileBase(), Definition::getReference(), Doxygen::inputNameLinkedMap, QCString::isEmpty(), Definition::isLinkable(), and OutputList::writeObjectLink().

◆ generateMarker()

QCString generateMarker ( int id)

Generate a place holder for a position in a list. Used for translators to be able to specify different elements orders depending on whether text flows from left to right or visa versa.

Definition at line 280 of file util.cpp.

281{
282 const int maxMarkerStrLen = 20;
283 char result[maxMarkerStrLen];
284 qsnprintf(result,maxMarkerStrLen,"@%d",id);
285 return result;
286}

References qsnprintf.

Referenced by TranslatorAfrikaans::trWriteList(), TranslatorArabic::trWriteList(), TranslatorArmenian::trWriteList(), TranslatorBrazilian::trWriteList(), TranslatorBulgarian::trWriteList(), TranslatorCatalan::trWriteList(), TranslatorChinese::trWriteList(), TranslatorChinesetraditional::trWriteList(), TranslatorCroatian::trWriteList(), TranslatorCzech::trWriteList(), TranslatorDanish::trWriteList(), TranslatorDutch::trWriteList(), TranslatorEnglish::trWriteList(), TranslatorEsperanto::trWriteList(), TranslatorFinnish::trWriteList(), TranslatorFrench::trWriteList(), TranslatorGerman::trWriteList(), TranslatorGreek::trWriteList(), TranslatorHindi::trWriteList(), TranslatorHungarian::trWriteList(), TranslatorIndonesian::trWriteList(), TranslatorItalian::trWriteList(), TranslatorJapanese::trWriteList(), TranslatorKorean::trWriteList(), TranslatorLatvian::trWriteList(), TranslatorLithuanian::trWriteList(), TranslatorMacedonian::trWriteList(), TranslatorNorwegian::trWriteList(), TranslatorPersian::trWriteList(), TranslatorPolish::trWriteList(), TranslatorPortuguese::trWriteList(), TranslatorRomanian::trWriteList(), TranslatorRussian::trWriteList(), TranslatorSerbian::trWriteList(), TranslatorSerbianCyrillic::trWriteList(), TranslatorSlovak::trWriteList(), TranslatorSlovene::trWriteList(), TranslatorSpanish::trWriteList(), TranslatorSwedish::trWriteList(), TranslatorTurkish::trWriteList(), TranslatorUkrainian::trWriteList(), and TranslatorVietnamese::trWriteList().

◆ getCaseSenseNames()

bool getCaseSenseNames ( )

Definition at line 3304 of file util.cpp.

3305{
3306 auto caseSenseNames = Config_getEnum(CASE_SENSE_NAMES);
3307
3308 if (caseSenseNames == CASE_SENSE_NAMES_t::YES) return true;
3309 else if (caseSenseNames == CASE_SENSE_NAMES_t::NO) return false;
3311}
#define Config_getEnum(name)
Definition config.h:35

References Config_getEnum, and Portable::fileSystemIsCaseSensitive().

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

◆ getDefs()

GetDefResult getDefs ( const GetDefInput & input)

Definition at line 2278 of file util.cpp.

2279{
2280 GetDefResult result;
2281 if (input.memberName.isEmpty()) return result;
2282 AUTO_TRACE("scopeName={},memberName={},forceEmptyScope={}",
2283 input.scopeName,input.memberName,input.forceEmptyScope);
2284
2285 //printf("@@ --- getDefsNew(%s,%s)-----------\n",qPrint(scName),qPrint(mbName));
2286 const Definition *scope = Doxygen::globalScope;
2287 SymbolResolver resolver;
2288 if (input.currentFile) resolver.setFileScope(input.currentFile);
2289 if (!input.scopeName.isEmpty() && !input.forceEmptyScope)
2290 {
2291 scope = resolver.resolveSymbol(scope,input.scopeName);
2292 }
2293 if (scope==Doxygen::globalScope)
2294 {
2295 scope = input.currentFile;
2296 }
2297 //printf("@@ -> found scope scope=%s member=%s out=%s\n",qPrint(input.scopeName),qPrint(input.memberName),qPrint(scope?scope->name():""));
2298 //
2299 const Definition *symbol = resolver.resolveSymbol(scope,input.memberName,input.args,input.checkCV,input.insideCode,true);
2300 //printf("@@ -> found symbol in=%s out=%s\n",qPrint(input.memberName),qPrint(symbol?symbol->qualifiedName():QCString()));
2301 if (symbol && symbol->definitionType()==Definition::TypeMember)
2302 {
2303 result.md = toMemberDef(symbol);
2304 result.cd = result.md->getClassDef();
2305 if (result.cd==nullptr) result.nd = result.md->getNamespaceDef();
2306 if (result.cd==nullptr && result.nd==nullptr) result.fd = result.md->getFileDef();
2307 result.gd = result.md->getGroupDef();
2308 result.found = true;
2309 }
2310 else if (symbol && symbol->definitionType()==Definition::TypeClass)
2311 {
2312 result.cd = toClassDef(symbol);
2313 result.found = true;
2314 }
2315 else if (symbol && symbol->definitionType()==Definition::TypeNamespace)
2316 {
2317 result.nd = toNamespaceDef(symbol);
2318 result.found = true;
2319 }
2320 else if (symbol && symbol->definitionType()==Definition::TypeConcept)
2321 {
2322 result.cnd = toConceptDef(symbol);
2323 result.found = true;
2324 }
2325 else if (symbol && symbol->definitionType()==Definition::TypeModule)
2326 {
2327 result.modd = toModuleDef(symbol);
2328 result.found = true;
2329 }
2330 return result;
2331}
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:120
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 QCString &name, const QCString &args=QCString(), 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:116
const FileDef * currentFile
Definition util.h:117
QCString scopeName
Definition util.h:113
bool insideCode
Definition util.h:119
bool checkCV
Definition util.h:118
QCString args
Definition util.h:115
QCString memberName
Definition util.h:114
const MemberDef * md
Definition util.h:125
const ConceptDef * cnd
Definition util.h:130
const FileDef * fd
Definition util.h:127
const ModuleDef * modd
Definition util.h:131
const GroupDef * gd
Definition util.h:129
bool found
Definition util.h:124
const ClassDef * cd
Definition util.h:126
const NamespaceDef * nd
Definition util.h:128

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

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

◆ getDotImageExtension()

QCString getDotImageExtension ( )

Definition at line 6292 of file util.cpp.

6293{
6294 QCString imgExt = Config_getEnumAsString(DOT_IMAGE_FORMAT);
6295 int i= imgExt.find(':'); // strip renderer part when using e.g. 'png:cairo:gd' as format
6296 return i==-1 ? imgExt : imgExt.left(i);
6297}
#define Config_getEnumAsString(name)
Definition config.h:36

References Config_getEnumAsString, QCString::find(), and QCString::left().

Referenced by RTFGenerator::endCallGraph(), RTFGenerator::endDirDepGraph(), RTFGenerator::endDotGraph(), RTFGenerator::endInclDepGraph(), DotGraph::generateCode(), DotGraph::imgName(), HtmlDocVisitor::operator()(), HtmlDocVisitor::operator()(), 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(), writeGraphInfo(), HtmlDocVisitor::writeMscFile(), and HtmlDocVisitor::writePlantUMLFile().

◆ getEncoding()

QCString getEncoding ( const FileInfo & fi)

Definition at line 5694 of file util.cpp.

5695{
5696 InputFileEncoding elem;
5697 auto getter = [](const InputFileEncoding &e) -> QCString { return e.pattern; };
5698 if (genericPatternMatch(fi,Doxygen::inputFileEncodingList,elem,getter)) // check for file specific encoding
5699 {
5700 return elem.encoding;
5701 }
5702 else // fall back to default encoding
5703 {
5704 return Config_getString(INPUT_ENCODING);
5705 }
5706}
static InputFileEncodingList inputFileEncodingList
Definition doxygen.h:139
#define Config_getString(name)
Definition config.h:32
QCString encoding
Definition doxygen.h:70
bool genericPatternMatch(const FileInfo &fi, const PatternList &patList, PatternElem &elem, PatternGet getter)
Definition util.cpp:5637

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

Referenced by readCodeFragment(), and readInputFile().

◆ getFileFilter()

QCString getFileFilter ( const QCString & 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 1402 of file util.cpp.

1403{
1404 // sanity check
1405 if (name.isEmpty()) return "";
1406
1407 const StringVector& filterSrcList = Config_getList(FILTER_SOURCE_PATTERNS);
1408 const StringVector& filterList = Config_getList(FILTER_PATTERNS);
1409
1410 QCString filterName;
1411 bool found=FALSE;
1412 if (isSourceCode && !filterSrcList.empty())
1413 { // first look for source filter pattern list
1414 filterName = getFilterFromList(name,filterSrcList,found);
1415 }
1416 if (!found && filterName.isEmpty())
1417 { // then look for filter pattern list
1418 filterName = getFilterFromList(name,filterList,found);
1419 }
1420 if (!found)
1421 { // then use the generic input filter
1422 return Config_getString(INPUT_FILTER);
1423 }
1424 else
1425 {
1426 /* remove surrounding double quotes */
1427 if (filterName.length()>=2 && filterName[0]=='"' && filterName[static_cast<int>(filterName.length())-1]=='"')
1428 {
1429 filterName = filterName.mid(1,filterName.length()-2);
1430 }
1431 return filterName;
1432 }
1433}
static QCString getFilterFromList(const QCString &name, const StringVector &filterList, bool &found)
Definition util.cpp:1361

References Config_getList, Config_getString, FALSE, getFilterFromList(), QCString::isEmpty(), QCString::length(), and QCString::mid().

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

◆ getFileNameExtension()

◆ getLanguageFromCodeLang()

SrcLangExt getLanguageFromCodeLang ( QCString & fileName)

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

Definition at line 5212 of file util.cpp.

5213{
5214 // try the extension
5215 auto lang = getLanguageFromFileName(fileName, SrcLangExt::Unknown);
5216 if (lang == SrcLangExt::Unknown)
5217 {
5218 // try the language names
5219 QCString langName = fileName.lower();
5220 if (langName.at(0)=='.') langName = langName.mid(1);
5221 auto it = std::find_if(g_lang2extMap.begin(),g_lang2extMap.end(),
5222 [&langName](const auto &info) { return info.langName==langName; });
5223 if (it != g_lang2extMap.end())
5224 {
5225 lang = it->parserId;
5226 fileName = it->defExt;
5227 }
5228 else // default to C++
5229 {
5230 return SrcLangExt::Cpp;
5231 }
5232 }
5233 return lang;
5234}
SrcLangExt getLanguageFromFileName(const QCString &fileName, SrcLangExt defLang)
Definition util.cpp:5194
static std::vector< Lang2ExtMap > g_lang2extMap
Definition util.cpp:5065

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

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

◆ getLanguageFromFileName()

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

Definition at line 5194 of file util.cpp.

5195{
5196 FileInfo fi(fileName.str());
5197 // we need only the part after the last ".", newer implementations of FileInfo have 'suffix()' for this.
5198 QCString extName = QCString(fi.extension(FALSE)).lower();
5199 if (extName.isEmpty()) extName=".no_extension";
5200 if (extName.at(0)!='.') extName.prepend(".");
5201 auto it = g_extLookup.find(extName.str());
5202 if (it!=g_extLookup.end()) // listed extension
5203 {
5204 //printf("getLanguageFromFileName(%s)=%x\n",qPrint(fi.extension()),*pVal);
5205 return it->second;
5206 }
5207 //printf("getLanguageFromFileName(%s) not found!\n",qPrint(fileName));
5208 return defLang; // not listed => assume C-ish language.
5209}
static std::unordered_map< std::string, SrcLangExt > g_extLookup
Definition util.cpp:5055

References QCString::at(), FileInfo::extension(), FALSE, g_extLookup, QCString::isEmpty(), QCString::lower(), QCString::prepend(), and QCString::str().

Referenced by MemberDefImpl::_writeMultiLineInitializer(), ClassDefImpl::ClassDefImpl(), DocRef::DocRef(), FileDefImpl::FileDefImpl(), generateExampleDocs(), getLanguageFromCodeLang(), guessSection(), FileDefImpl::isDocumentationFile(), 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(), validatingParseDoc(), and writeXMLCodeBlock().

◆ getLanguageSpecificSeparator()

QCString getLanguageSpecificSeparator ( SrcLangExt lang,
bool classScope = FALSE )

Returns the scope separator to use given the programming language lang.

Definition at line 5900 of file util.cpp.

5901{
5902 if (lang==SrcLangExt::Java || lang==SrcLangExt::CSharp || lang==SrcLangExt::VHDL || lang==SrcLangExt::Python)
5903 {
5904 return ".";
5905 }
5906 else if (lang==SrcLangExt::PHP && !classScope)
5907 {
5908 return "\\";
5909 }
5910 else
5911 {
5912 return "::";
5913 }
5914}

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

◆ getOverloadDocs()

QCString getOverloadDocs ( )

Returns the standard string that is generated when the \overload command is used.

Definition at line 4073 of file util.cpp.

4074{
4075 return theTranslator->trOverloadText();
4076 //"This is an overloaded member function, "
4077 // "provided for convenience. It differs from the above "
4078 // "function only in what argument(s) it accepts.";
4079}
Translator * theTranslator
Definition language.cpp:71

References theTranslator.

Referenced by addMemberDocs(), addOverloaded(), and CommentScanner::parseCommentBlock().

◆ getPrefixIndex()

int getPrefixIndex ( const QCString & 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 3215 of file util.cpp.

3216{
3217 if (name.isEmpty()) return 0;
3218 const StringVector &sl = Config_getList(IGNORE_PREFIX);
3219 for (const auto &s : sl)
3220 {
3221 const char *ps=s.c_str();
3222 const char *pd=name.data();
3223 int i=0;
3224 while (*ps!=0 && *pd!=0 && *ps==*pd)
3225 {
3226 ps++;
3227 pd++;
3228 i++;
3229 }
3230 if (*ps==0 && *pd!=0)
3231 {
3232 return i;
3233 }
3234 }
3235 return 0;
3236}

References Config_getList, QCString::data(), and QCString::isEmpty().

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

◆ getProjectId()

QCString getProjectId ( )

Definition at line 6814 of file util.cpp.

6815{
6816 QCString projectCookie = Config_getString(HTML_PROJECT_COOKIE);
6817 if (projectCookie.isEmpty()) return QCString();
6818 uint8_t md5_sig[16];
6819 char sigStr[34];
6820 MD5Buffer(projectCookie.data(),static_cast<unsigned int>(projectCookie.length()),md5_sig);
6821 MD5SigToString(md5_sig,sigStr);
6822 sigStr[32]='_'; sigStr[33]=0;
6823 return sigStr;
6824}

References Config_getString, QCString::data(), QCString::isEmpty(), and QCString::length().

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

◆ getScopeFragment()

int getScopeFragment ( const QCString & 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 4623 of file util.cpp.

4624{
4625 int sl=static_cast<int>(s.length());
4626 int sp=p;
4627 int count=0;
4628 bool done=false;
4629 if (sp>=sl) return -1;
4630 while (sp<sl)
4631 {
4632 char c=s.at(sp);
4633 if (c==':')
4634 {
4635 sp++;
4636 p++;
4637 }
4638 else
4639 {
4640 break;
4641 }
4642 }
4643 while (sp<sl)
4644 {
4645 char c=s.at(sp);
4646 switch (c)
4647 {
4648 case ':': // found next part
4649 goto found;
4650 case '<': // skip template specifier
4651 count=1;sp++;
4652 done=false;
4653 while (sp<sl && !done)
4654 {
4655 // TODO: deal with << and >> operators!
4656 c=s.at(sp++);
4657 switch(c)
4658 {
4659 case '<': count++; break;
4660 case '>': count--; if (count==0) done=true; break;
4661 default: break;
4662 }
4663 }
4664 break;
4665 default:
4666 sp++;
4667 break;
4668 }
4669 }
4670found:
4671 *l=sp-p;
4672 //printf("getScopeFragment(%s,%d)=%s\n",qPrint(s),p,qPrint(s.mid(p,*l)));
4673 return p;
4674}

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

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

◆ guessSection()

EntryType guessSection ( const QCString & name)

try to determine if name is a source or a header file name by looking at the extension. A number of variations is allowed in both upper and lower case) If anyone knows or uses another extension please let me know :-)

Definition at line 339 of file util.cpp.

340{
341 QCString n=name.lower();
342 static const std::unordered_set<std::string> sourceExt = {
343 "c","cc","cxx","cpp","c++","cppm","ccm","cxxm","c++m", // C/C++
344 "java", // Java
345 "cs", // C#
346 "m","mm", // Objective-C
347 "ii","ixx","ipp","i++","inl", // C/C++ inline
348 "xml","lex","sql" // others
349 };
350 static const std::unordered_set<std::string> headerExt = {
351 "h", "hh", "hxx", "hpp", "h++", "ixx", // C/C++ header
352 "idl", "ddl", "pidl", "ice" // IDL like
353 };
354 int lastDot = n.findRev('.');
355 if (lastDot!=-1)
356 {
357 QCString extension = n.mid(lastDot+1); // part after the last dot
358 if (sourceExt.find(extension.str())!=sourceExt.end())
359 {
360 return EntryType::makeSource();
361 }
362 if (headerExt.find(extension.str())!=headerExt.end())
363 {
364 return EntryType::makeHeader();
365 }
366 }
367 else
368 {
369 if (getLanguageFromFileName(name,SrcLangExt::Unknown) == SrcLangExt::Cpp) return EntryType::makeHeader();
370 }
371 return EntryType::makeEmpty();
372}

References QCString::findRev(), getLanguageFromFileName(), QCString::lower(), QCString::mid(), and QCString::str().

Referenced by addIncludeFile(), anonymous_namespace{tagreader.cpp}::TagFileParser::buildLists(), ClassDefImpl::ClassDefImpl(), computeClassRelations(), FileDefImpl::FileDefImpl(), FileDefImpl::generateSourceFile(), parseMain(), parseMain(), and warnUndocumentedNamespaces().

◆ initDefaultExtensionMapping()

void initDefaultExtensionMapping ( )

Definition at line 5121 of file util.cpp.

5122{
5123 // NOTE: when adding an extension, also add the extension in config.xml
5124 // extension parser id
5125 updateLanguageMapping(".dox", "c");
5126 updateLanguageMapping(".txt", "c"); // see bug 760836
5127 updateLanguageMapping(".doc", "c");
5128 updateLanguageMapping(".c", "c");
5129 updateLanguageMapping(".C", "c");
5130 updateLanguageMapping(".cc", "c");
5131 updateLanguageMapping(".CC", "c");
5132 updateLanguageMapping(".cxx", "c");
5133 updateLanguageMapping(".cpp", "c");
5134 updateLanguageMapping(".c++", "c");
5135 updateLanguageMapping(".cxxm", "c"); // C++20 modules
5136 updateLanguageMapping(".cppm", "c"); // C++20 modules
5137 updateLanguageMapping(".ccm", "c"); // C++20 modules
5138 updateLanguageMapping(".c++m", "c"); // C++20 modules
5139 updateLanguageMapping(".ii", "c");
5140 updateLanguageMapping(".ixx", "c");
5141 updateLanguageMapping(".ipp", "c");
5142 updateLanguageMapping(".i++", "c");
5143 updateLanguageMapping(".inl", "c");
5144 updateLanguageMapping(".h", "c");
5145 updateLanguageMapping(".H", "c");
5146 updateLanguageMapping(".hh", "c");
5147 updateLanguageMapping(".HH", "c");
5148 updateLanguageMapping(".hxx", "c");
5149 updateLanguageMapping(".hpp", "c");
5150 updateLanguageMapping(".h++", "c");
5151 updateLanguageMapping(".idl", "idl");
5152 updateLanguageMapping(".ddl", "idl");
5153 updateLanguageMapping(".odl", "idl");
5154 updateLanguageMapping(".java", "java");
5155 //updateLanguageMapping(".as", "javascript"); // not officially supported
5156 //updateLanguageMapping(".js", "javascript"); // not officially supported
5157 updateLanguageMapping(".cs", "csharp");
5158 updateLanguageMapping(".d", "d");
5159 updateLanguageMapping(".php", "php");
5160 updateLanguageMapping(".php4", "php");
5161 updateLanguageMapping(".php5", "php");
5162 updateLanguageMapping(".inc", "php");
5163 updateLanguageMapping(".phtml", "php");
5164 updateLanguageMapping(".m", "objective-c");
5165 updateLanguageMapping(".M", "objective-c");
5166 updateLanguageMapping(".mm", "c"); // see bug746361
5167 updateLanguageMapping(".py", "python");
5168 updateLanguageMapping(".pyw", "python");
5169 updateLanguageMapping(".f", "fortran");
5170 updateLanguageMapping(".for", "fortran");
5171 updateLanguageMapping(".f90", "fortran");
5172 updateLanguageMapping(".f95", "fortran");
5173 updateLanguageMapping(".f03", "fortran");
5174 updateLanguageMapping(".f08", "fortran");
5175 updateLanguageMapping(".f18", "fortran");
5176 updateLanguageMapping(".vhd", "vhdl");
5177 updateLanguageMapping(".vhdl", "vhdl");
5178 updateLanguageMapping(".ucf", "vhdl");
5179 updateLanguageMapping(".qsf", "vhdl");
5180 updateLanguageMapping(".md", "md");
5181 updateLanguageMapping(".markdown", "md");
5182 updateLanguageMapping(".ice", "slice");
5183 updateLanguageMapping(".l", "lex");
5184 updateLanguageMapping(".doxygen_lex_c", "c"); // this is a placeholder so we can map initializations
5185 // in the lex scanning to cpp
5186}

References updateLanguageMapping().

Referenced by initDoxygen().

◆ inlineArgListToDoc()

QCString inlineArgListToDoc ( const ArgumentList & al)

Definition at line 1189 of file util.cpp.

1190{
1191 QCString paramDocs;
1192 if (al.hasDocumentation())
1193 {
1194 for (const Argument &a : al)
1195 {
1196 if (a.hasDocumentation())
1197 {
1198 QCString docsWithoutDir = a.docs;
1199 QCString direction = extractDirection(docsWithoutDir);
1200 paramDocs+=" \\ilinebr @param"+direction+" "+a.name+" "+docsWithoutDir;
1201 }
1202 }
1203 }
1204 return paramDocs;
1205}
bool hasDocumentation() const
Definition arguments.cpp:22
QCString extractDirection(QCString &docs)
Strip the direction part from docs and return it as a string in canonical form The input docs string ...
Definition util.cpp:6181

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

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

◆ inlineTemplateArgListToDoc()

QCString inlineTemplateArgListToDoc ( const ArgumentList & al)

Definition at line 1207 of file util.cpp.

1208{
1209 QCString paramDocs;
1210 if (al.hasTemplateDocumentation())
1211 {
1212 for (const Argument &a : al)
1213 {
1214 if (!a.docs.isEmpty())
1215 {
1216 if (!a.name.isEmpty())
1217 {
1218 paramDocs+=" \\ilinebr @tparam "+a.name+" "+a.docs;
1219 }
1220 else if (!a.type.isEmpty())
1221 {
1222 QCString type = a.type;
1223 type.stripPrefix("class ");
1224 type.stripPrefix("typename ");
1225 type = type.stripWhiteSpace();
1226 paramDocs+=" \\ilinebr @tparam "+type+" "+a.docs;
1227 }
1228 }
1229 }
1230 }
1231 return paramDocs;
1232}
bool hasTemplateDocumentation() const
Definition arguments.cpp:30
bool stripPrefix(const QCString &prefix)
Definition qcstring.h:213

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

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

◆ insertTemplateSpecifierInScope()

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

Definition at line 3730 of file util.cpp.

3731{
3732 QCString result=scope;
3733 if (!templ.isEmpty() && scope.find('<')==-1)
3734 {
3735 int si=0, pi=0;
3736 ClassDef *cd=nullptr;
3737 while (
3738 (si=scope.find("::",pi))!=-1 && !getClass(scope.left(si)+templ) &&
3739 ((cd=getClass(scope.left(si)))==nullptr || cd->templateArguments().empty())
3740 )
3741 {
3742 //printf("Tried '%s'\n",qPrint((scope.left(si)+templ)));
3743 pi=si+2;
3744 }
3745 if (si==-1) // not nested => append template specifier
3746 {
3747 result+=templ;
3748 }
3749 else // nested => insert template specifier before after first class name
3750 {
3751 result=scope.left(si) + templ + scope.right(scope.length()-si);
3752 }
3753 }
3754 //printf("insertTemplateSpecifierInScope('%s','%s')=%s\n",
3755 // qPrint(scope),qPrint(templ),qPrint(result));
3756 return result;
3757}
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(), QCString::find(), getClass(), QCString::isEmpty(), QCString::left(), QCString::length(), QCString::right(), and ClassDef::templateArguments().

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

◆ integerToAlpha()

QCString integerToAlpha ( int n,
bool upper = true )

Definition at line 6685 of file util.cpp.

6686{
6687 QCString result;
6688 int residual = n;
6689
6690 char modVal[2];
6691 modVal[1] = 0;
6692 while (residual > 0)
6693 {
6694 modVal[0] = (upper ? 'A': 'a') + (residual-1)%26;
6695 result = modVal + result;
6696 residual = (residual-1) / 26;
6697 }
6698 return result;
6699}

Referenced by ManDocVisitor::operator()(), and RTFDocVisitor::operator()().

◆ integerToRoman()

QCString integerToRoman ( int n,
bool upper = true )

Definition at line 6701 of file util.cpp.

6702{
6703 static const char *str_romans_upper[] = { "M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I" };
6704 static const char *str_romans_lower[] = { "m", "cm", "d", "cd", "c", "xc", "l", "xl", "x", "ix", "v", "iv", "i" };
6705 static const int values[] = { 1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1 };
6706 static const char **str_romans = upper ? str_romans_upper : str_romans_lower;
6707
6708 QCString result;
6709 int residual = n;
6710
6711 for (int i = 0; i < 13; ++i)
6712 {
6713 while (residual - values[i] >= 0)
6714 {
6715 result += str_romans[i];
6716 residual -= values[i];
6717 }
6718 }
6719
6720 return result;
6721}

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

◆ isId()

◆ isIdJS()

bool isIdJS ( int c)
inline

Definition at line 212 of file util.h.

213{
214 return c>=128 || c<0 || isalnum(c);
215}

Referenced by SearchTerm::termEncoded().

◆ isURL()

bool isURL ( const QCString & url)

Checks whether the given url starts with a supported protocol.

Definition at line 5916 of file util.cpp.

5917{
5918 static const std::unordered_set<std::string> schemes = {
5919 "http", "https", "ftp", "ftps", "sftp", "file", "news", "irc", "ircs"
5920 };
5921 QCString loc_url = url.stripWhiteSpace();
5922 int colonPos = loc_url.find(':');
5923 return colonPos!=-1 && schemes.find(loc_url.left(colonPos).str())!=schemes.end();
5924}

References QCString::find(), QCString::left(), QCString::str(), and QCString::stripWhiteSpace().

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

◆ join()

std::string join ( const StringVector & s,
const std::string & delimiter )

create a string where the string in the vector are joined by the given delimiter

Definition at line 6672 of file util.cpp.

6673{
6674 std::string result;
6675 bool first=true;
6676 for (const auto &s : sv)
6677 {
6678 if (!first) result+=delimiter;
6679 first=false;
6680 result+=s;
6681 }
6682 return result;
6683}

◆ langToString()

QCString langToString ( SrcLangExt lang)

Returns a string representation of lang.

Definition at line 5894 of file util.cpp.

5895{
5896 return to_string(lang);
5897}
static constexpr const char * to_string(Protection prot) noexcept
Definition types.h:38

References to_string().

Referenced by buildNamespaceList(), findUsingDirectives(), generateXMLForClass(), generateXMLForFile(), and generateXMLForNamespace().

◆ leftScopeMatch()

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

Definition at line 882 of file util.cpp.

883{
884 size_t sl=scope.length();
885 size_t nl=name.length();
886 return (name==scope || // equal
887 (name.left(sl)==scope && // substring
888 nl>sl+1 && name.at(sl)==':' && name.at(sl+1)==':' // scope
889 )
890 );
891}

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

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

◆ lineBlock()

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

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

See also
routine extractBlock

Definition at line 5873 of file util.cpp.

5874{
5875 int result = 1;
5876
5877 // find the character positions of the first marker
5878 int m1 = text.find(marker);
5879 if (m1==-1) return result;
5880
5881 // find start line positions for the markers
5882 bool found=false;
5883 int p=0, i=0;
5884 while (!found && (i=text.find('\n',p))!=-1)
5885 {
5886 found = (p<=m1 && m1<i); // found the line with the start marker
5887 p=i+1;
5888 result++;
5889 }
5890 return result;
5891}

References QCString::find().

◆ linkifyText()

void linkifyText ( const TextGeneratorIntf & ol,
const Definition * scope,
const FileDef * fileScope,
const Definition * self,
const QCString & text,
bool autoBreak = FALSE,
bool external = TRUE,
bool keepSpaces = FALSE,
int indentLevel = 0,
size_t breakThreshold = 30 )

Definition at line 894 of file util.cpp.

898{
899 AUTO_TRACE("scope={} fileScope={} text={} autoBreak={} external={} keepSpaces={} indentLevel={}",
900 scope?scope->name():"",fileScope?fileScope->name():"",
901 text,autoBreak,external,keepSpaces,indentLevel);
902 if (text.isEmpty()) return;
903 //printf("linkify='%s'\n",qPrint(text));
904 std::string_view txtStr=text.view();
905 size_t strLen = txtStr.length();
906 if (strLen==0) return;
907
908 static const reg::Ex regExp(R"((::)?\a[\w~!\\.:$"]*)");
909 reg::Iterator it(txtStr,regExp);
911
912 //printf("linkifyText scope=%s fileScope=%s strtxt=%s strlen=%zu external=%d\n",
913 // scope ? qPrint(scope->name()):"<none>",
914 // fileScope ? qPrint(fileScope->name()) : "<none>",
915 // qPrint(txtStr),strLen,external);
916 size_t index=0;
917 size_t skipIndex=0;
918 size_t floatingIndex=0;
919 for (; it!=end ; ++it) // for each word from the text string
920 {
921 const auto &match = *it;
922 size_t newIndex = match.position();
923 size_t matchLen = match.length();
924 floatingIndex+=newIndex-skipIndex+matchLen;
925 if (newIndex>0 && txtStr.at(newIndex-1)=='0') // ignore hex numbers (match x00 in 0x00)
926 {
927 std::string_view part = txtStr.substr(skipIndex,newIndex+matchLen-skipIndex);
928 out.writeString(part,keepSpaces);
929 skipIndex=index=newIndex+matchLen;
930 continue;
931 }
932
933 // add non-word part to the result
934 bool insideString=FALSE;
935 for (size_t i=index;i<newIndex;i++)
936 {
937 if (txtStr.at(i)=='"') insideString=!insideString;
938 if (txtStr.at(i)=='\\') i++; // skip next character it is escaped
939 }
940
941 //printf("floatingIndex=%d strlen=%d autoBreak=%d\n",floatingIndex,strLen,autoBreak);
942 if (strLen>breakThreshold+5 && floatingIndex>breakThreshold && autoBreak) // try to insert a split point
943 {
944 std::string_view splitText = txtStr.substr(skipIndex,newIndex-skipIndex);
945 size_t splitLength = splitText.length();
946 size_t offset=1;
947 size_t i = splitText.find(',');
948 if (i==std::string::npos) { i=splitText.find('<'); if (i!=std::string::npos) offset=0; }
949 if (i==std::string::npos) { i=splitText.find("||"); if (i!=std::string::npos) offset=2; }
950 if (i==std::string::npos) { i=splitText.find("&&"); if (i!=std::string::npos) offset=2; }
951 if (i==std::string::npos) { i=splitText.find(">>"); if (i!=std::string::npos) offset=2; }
952 if (i==std::string::npos) i=splitText.find('>');
953 if (i==std::string::npos) i=splitText.find(' ');
954 //printf("splitText=[%s] len=%d i=%d offset=%d\n",qPrint(splitText),splitLength,i,offset);
955 if (i!=std::string::npos) // add a link-break at i in case of Html output
956 {
957 std::string_view part1 = splitText.substr(0,i+offset);
958 out.writeString(part1,keepSpaces);
959 out.writeBreak(indentLevel==0 ? 0 : indentLevel+1);
960 std::string_view part2 = splitText.substr(i+offset);
961 out.writeString(part2,keepSpaces);
962 floatingIndex=splitLength-i-offset+matchLen;
963 }
964 else
965 {
966 out.writeString(splitText,keepSpaces);
967 }
968 }
969 else
970 {
971 //ol.docify(txtStr.mid(skipIndex,newIndex-skipIndex));
972 std::string_view part = txtStr.substr(skipIndex,newIndex-skipIndex);
973 out.writeString(part,keepSpaces);
974 }
975 // get word from string
976 std::string_view word=txtStr.substr(newIndex,matchLen);
977 QCString matchWord = substitute(substitute(word,"\\","::"),".","::");
978 //printf("linkifyText word=%s matchWord=%s scope=%s\n",
979 // qPrint(word),qPrint(matchWord),scope ? qPrint(scope->name()) : "<none>");
980 bool found=FALSE;
981 if (!insideString)
982 {
983 const ClassDef *cd=nullptr;
984 const ConceptDef *cnd=nullptr;
985 const Definition *d=nullptr;
986 //printf("** Match word '%s'\n",qPrint(matchWord));
987
988 SymbolResolver resolver(fileScope);
989 cd=resolver.resolveClass(scope,matchWord);
990 const MemberDef *typeDef = resolver.getTypedef();
991 if (typeDef) // First look at typedef then class, see bug 584184.
992 {
993 if (external ? typeDef->isLinkable() : typeDef->isLinkableInProject())
994 {
995 if (typeDef->getOuterScope()!=self)
996 {
997 //printf("Found typedef %s word='%s'\n",qPrint(typeDef->name()),qPrint(word));
998 out.writeLink(typeDef->getReference(),
999 typeDef->getOutputFileBase(),
1000 typeDef->anchor(),
1001 word);
1002 found=TRUE;
1003 }
1004 }
1005 }
1006 auto writeCompoundName = [&](const auto *cd_) {
1007 if (external ? cd_->isLinkable() : cd_->isLinkableInProject())
1008 {
1009 if (self==nullptr || cd_->qualifiedName()!=self->qualifiedName())
1010 {
1011 //printf("Found compound %s word='%s'\n",qPrint(cd->name()),qPrint(word));
1012 out.writeLink(cd_->getReference(),cd_->getOutputFileBase(),cd_->anchor(),word);
1013 found=TRUE;
1014 }
1015 }
1016 };
1017
1018 if (found)
1019 {
1020 //printf(" -> skip\n");
1021 }
1022 else if ((cd=getClass(matchWord)))
1023 {
1024 writeCompoundName(cd);
1025 }
1026 else if ((cd=getClass(matchWord+"-p"))) // search for Obj-C protocols as well
1027 {
1028 writeCompoundName(cd);
1029 }
1030 else if ((cnd=getConcept(matchWord))) // search for concepts
1031 {
1032 writeCompoundName(cnd);
1033 }
1034 else if ((d=resolver.resolveSymbol(scope,matchWord)))
1035 {
1036 writeCompoundName(d);
1037 }
1038 else
1039 {
1040 //printf(" -> nothing\n");
1041 }
1042
1043 int m = matchWord.findRev("::");
1044 QCString scopeName;
1045 if (scope &&
1048 )
1049 )
1050 {
1051 scopeName=scope->name();
1052 }
1053 else if (m!=-1)
1054 {
1055 scopeName = matchWord.left(m);
1056 matchWord = matchWord.mid(m+2);
1057 }
1058
1059 //printf("ScopeName=%s\n",qPrint(scopeName));
1060 //if (!found) printf("Trying to link '%s' in '%s'\n",qPrint(word),qPrint(scopeName));
1061 if (!found)
1062 {
1063 GetDefInput input(scopeName,matchWord,QCString());
1064 GetDefResult result = getDefs(input);
1065 if (result.found && result.md &&
1066 (external ? result.md->isLinkable() : result.md->isLinkableInProject())
1067 )
1068 {
1069 //printf("Found ref scope=%s\n",d ? qPrint(d->name()) : "<global>");
1070 //ol.writeObjectLink(d->getReference(),d->getOutputFileBase(),
1071 // md->anchor(),word);
1072 if (result.md!=self && (self==nullptr || result.md->name()!=self->name()))
1073 // name check is needed for overloaded members, where getDefs just returns one
1074 {
1075 /* in case of Fortran scope and the variable is a non Fortran variable: don't link,
1076 * see also getLink in fortrancode.l
1077 */
1078 if (!(scope &&
1079 (scope->getLanguage() == SrcLangExt::Fortran) &&
1080 result.md->isVariable() &&
1081 (result.md->getLanguage() != SrcLangExt::Fortran)
1082 )
1083 )
1084 {
1085 //printf("found symbol %s word='%s'\n",qPrint(result.md->name()),qPrint(word));
1086 out.writeLink(result.md->getReference(),result.md->getOutputFileBase(),
1087 result.md->anchor(),word);
1088 found=TRUE;
1089 }
1090 }
1091 }
1092 }
1093 }
1094
1095 if (!found) // add word to the result
1096 {
1097 out.writeString(word,keepSpaces);
1098 }
1099 // set next start point in the string
1100 //printf("index=%d/%d\n",index,txtStr.length());
1101 skipIndex=index=newIndex+matchLen;
1102 }
1103 // add last part of the string to the result.
1104 //ol.docify(txtStr.right(txtStr.length()-skipIndex));
1105 std::string_view lastPart = txtStr.substr(skipIndex);
1106 out.writeString(lastPart,keepSpaces);
1107}
virtual SrcLangExt getLanguage() const =0
Returns the programming language this definition was written in.
virtual QCString anchor() const =0
virtual QCString qualifiedName() const =0
virtual Definition * getOuterScope() const =0
virtual bool isVariable() const =0
std::string_view view() const
Definition qcstring.h:174
ConceptDef * getConcept(const QCString &n)
GetDefResult getDefs(const GetDefInput &input)
Definition util.cpp:2278

References Definition::anchor(), AUTO_TRACE, Definition::definitionType(), end(), FALSE, QCString::findRev(), GetDefResult::found, getClass(), getConcept(), getDefs(), Definition::getLanguage(), Definition::getOuterScope(), Definition::getOutputFileBase(), Definition::getReference(), SymbolResolver::getTypedef(), QCString::isEmpty(), Definition::isLinkable(), Definition::isLinkableInProject(), MemberDef::isVariable(), QCString::left(), GetDefResult::md, QCString::mid(), Definition::name(), Definition::qualifiedName(), SymbolResolver::resolveClass(), SymbolResolver::resolveSymbol(), substitute(), TRUE, Definition::TypeClass, Definition::TypeNamespace, QCString::view(), TextGeneratorIntf::writeBreak(), TextGeneratorIntf::writeLink(), and TextGeneratorIntf::writeString().

Referenced by MemberDefImpl::_writeTemplatePrefix(), generateSqlite3ForMember(), generateXMLForClass(), generateXMLForConcept(), generateXMLForMember(), insertMemberFunctionParams(), MemberDefImpl::writeDeclaration(), writeDefArgumentList(), MemberDefImpl::writeDocumentation(), writeExceptionListImpl(), MemberDefImpl::writeMemberDocSimple(), writeTemplateArgumentList(), ClassDefImpl::writeTemplateSpec(), and writeTypeConstraints().

◆ linkToText()

QCString linkToText ( SrcLangExt lang,
const QCString & link,
bool isFileName )

Definition at line 2678 of file util.cpp.

2679{
2680 //bool optimizeOutputJava = Config_getBool(OPTIMIZE_OUTPUT_JAVA);
2681 QCString result=link;
2682 if (!result.isEmpty())
2683 {
2684 // replace # by ::
2685 result=substitute(result,"#","::");
2686 // replace . by ::
2687 if (!isFileName && result.find('<')==-1) result=substitute(result,".","::",3);
2688 // strip leading :: prefix if present
2689 if (result.at(0)==':' && result.at(1)==':')
2690 {
2691 result=result.right(result.length()-2);
2692 }
2694 if (sep!="::")
2695 {
2696 result=substitute(result,"::",sep);
2697 }
2698 }
2699 //printf("linkToText(%s,lang=%d)=%s\n",qPrint(link),lang,qPrint(result));
2700 return result;
2701}
QCString getLanguageSpecificSeparator(SrcLangExt lang, bool classScope)
Returns the scope separator to use given the programming language lang.
Definition util.cpp:5900

References QCString::at(), QCString::find(), getLanguageSpecificSeparator(), QCString::isEmpty(), QCString::length(), QCString::right(), and substitute().

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

◆ mainPageHasTitle()

bool mainPageHasTitle ( )

Definition at line 6287 of file util.cpp.

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

References Doxygen::mainPage.

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

◆ makeBaseName()

◆ mangleCSharpGenericName()

QCString mangleCSharpGenericName ( const QCString & name)

Definition at line 6916 of file util.cpp.

6917{
6918 int idx = name.find('<');
6919 if (idx!=-1)
6920 {
6921 return name.left(idx)+"-"+QCString().setNum(name.contains(",")+1)+"-g";
6922 }
6923 return name;
6924}
int contains(char c, bool cs=TRUE) const
Definition qcstring.cpp:148

References QCString::contains(), QCString::find(), QCString::left(), and QCString::setNum().

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

◆ matchArguments2()

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

Definition at line 2001 of file util.cpp.

2004{
2005 ASSERT(srcScope!=nullptr && dstScope!=nullptr);
2006
2007 AUTO_TRACE("srcScope='{}' dstScope='{}' srcArgs='{}' dstArgs='{}' checkCV={} lang={}",
2008 srcScope->name(),dstScope->name(),srcAl?argListToString(*srcAl):"",dstAl?argListToString(*dstAl):"",checkCV,lang);
2009
2010 if (srcAl==nullptr || dstAl==nullptr)
2011 {
2012 bool match = srcAl==dstAl;
2013 if (match)
2014 {
2015 MATCH
2016 return TRUE;
2017 }
2018 else
2019 {
2020 NOMATCH
2021 return FALSE;
2022 }
2023 }
2024
2025 // handle special case with void argument
2026 if ( srcAl->empty() && dstAl->size()==1 && dstAl->front().type=="void" )
2027 { // special case for finding match between func() and func(void)
2028 Argument a;
2029 a.type = "void";
2030 const_cast<ArgumentList*>(srcAl)->push_back(a);
2031 MATCH
2032 return TRUE;
2033 }
2034 if ( dstAl->empty() && srcAl->size()==1 && srcAl->front().type=="void" )
2035 { // special case for finding match between func(void) and func()
2036 Argument a;
2037 a.type = "void";
2038 const_cast<ArgumentList*>(dstAl)->push_back(a);
2039 MATCH
2040 return TRUE;
2041 }
2042
2043 if (srcAl->size() != dstAl->size())
2044 {
2045 NOMATCH
2046 return FALSE; // different number of arguments -> no match
2047 }
2048
2049 if (checkCV)
2050 {
2051 if (srcAl->constSpecifier() != dstAl->constSpecifier())
2052 {
2053 NOMATCH
2054 return FALSE; // one member is const, the other not -> no match
2055 }
2056 if (srcAl->volatileSpecifier() != dstAl->volatileSpecifier())
2057 {
2058 NOMATCH
2059 return FALSE; // one member is volatile, the other not -> no match
2060 }
2061 }
2062
2063 if (srcAl->refQualifier() != dstAl->refQualifier())
2064 {
2065 NOMATCH
2066 return FALSE; // one member is has a different ref-qualifier than the other
2067 }
2068
2069 if (srcReturnType=="auto" && dstReturnType=="auto" && srcAl->trailingReturnType()!=dstAl->trailingReturnType())
2070 {
2071 NOMATCH
2072 return FALSE; // one member is has a different return type than the other
2073 }
2074
2075 // so far the argument list could match, so we need to compare the types of
2076 // all arguments.
2077 auto srcIt = srcAl->begin();
2078 auto dstIt = dstAl->begin();
2079 for (;srcIt!=srcAl->end() && dstIt!=dstAl->end();++srcIt,++dstIt)
2080 {
2081 Argument &srcA = const_cast<Argument&>(*srcIt);
2082 Argument &dstA = const_cast<Argument&>(*dstIt);
2083 if (!matchArgument2(srcScope,srcFileScope,srcA,
2084 dstScope,dstFileScope,dstA,
2085 lang)
2086 )
2087 {
2088 NOMATCH
2089 return FALSE;
2090 }
2091 }
2092 MATCH
2093 return TRUE; // all arguments match
2094}
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 MATCH
Definition util.cpp:1900
QCString argListToString(const ArgumentList &al, bool useCanonicalType, bool showDefVals)
Definition util.cpp:1234
#define NOMATCH
Definition util.cpp:1901
static bool matchArgument2(const Definition *srcScope, const FileDef *srcFileScope, Argument &srcA, const Definition *dstScope, const FileDef *dstFileScope, Argument &dstA, SrcLangExt lang)
Definition util.cpp:1935

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

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

◆ matchTemplateArguments()

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

Definition at line 2245 of file util.cpp.

2246{
2247 AUTO_TRACE("srcAl={} dstAl={}",argListToString(srcAl),argListToString(dstAl));
2248 if (srcAl.size()!=dstAl.size()) // different number of template parameters -> overload
2249 {
2250 AUTO_TRACE_EXIT("different number of parameters");
2251 return false;
2252 }
2253 auto isUnconstraintTemplate = [](const QCString &type)
2254 {
2255 return type=="typename" || type=="class" || type.startsWith("typename ") || type.startsWith("class ");
2256 };
2257 auto srcIt = srcAl.begin();
2258 auto dstIt = dstAl.begin();
2259 while (srcIt!=srcAl.end() && dstIt!=dstAl.end())
2260 {
2261 const Argument &srcA = *srcIt;
2262 const Argument &dstA = *dstIt;
2263 if ((!isUnconstraintTemplate(srcA.type) || !isUnconstraintTemplate(dstA.type)) && srcA.type!=dstA.type) // different constraints -> overload
2264 {
2265 AUTO_TRACE_EXIT("different constraints");
2266 return false;
2267 }
2268 ++srcIt;
2269 ++dstIt;
2270 }
2271 AUTO_TRACE_EXIT("same");
2272 // no overload with respect to the template parameters
2273 return true;
2274}

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

Referenced by buildFunctionList().

◆ mergeArguments()

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

Definition at line 2101 of file util.cpp.

2102{
2103 AUTO_TRACE("srcAl='{}',dstAl='{}',forceNameOverwrite={}",
2104 qPrint(argListToString(srcAl)),qPrint(argListToString(dstAl)),forceNameOverwrite);
2105
2106 if (srcAl.size()!=dstAl.size())
2107 {
2108 return; // invalid argument lists -> do not merge
2109 }
2110
2111 auto srcIt=srcAl.begin();
2112 auto dstIt=dstAl.begin();
2113 while (srcIt!=srcAl.end() && dstIt!=dstAl.end())
2114 {
2115 Argument &srcA = *srcIt;
2116 Argument &dstA = *dstIt;
2117
2118 AUTO_TRACE_ADD("before merge: src=[type='{}',name='{}',def='{}'] dst=[type='{}',name='{}',def='{}']",
2119 srcA.type,srcA.name,srcA.defval,
2120 dstA.type,dstA.name,dstA.defval);
2121 if (srcA.defval.isEmpty() && !dstA.defval.isEmpty())
2122 {
2123 //printf("Defval changing '%s'->'%s'\n",qPrint(srcA.defval),qPrint(dstA.defval));
2124 srcA.defval=dstA.defval;
2125 }
2126 else if (!srcA.defval.isEmpty() && dstA.defval.isEmpty())
2127 {
2128 //printf("Defval changing '%s'->'%s'\n",qPrint(dstA.defval),qPrint(srcA.defval));
2129 dstA.defval=srcA.defval;
2130 }
2131
2132 // fix wrongly detected const or volatile specifiers before merging.
2133 // example: "const A *const" is detected as type="const A *" name="const"
2134 if (srcA.name=="const" || srcA.name=="volatile")
2135 {
2136 srcA.type+=" "+srcA.name;
2137 srcA.name.clear();
2138 }
2139 if (dstA.name=="const" || dstA.name=="volatile")
2140 {
2141 dstA.type+=" "+dstA.name;
2142 dstA.name.clear();
2143 }
2144
2145 if (srcA.type==dstA.type)
2146 {
2147 //printf("1. merging %s:%s <-> %s:%s\n",qPrint(srcA.type),qPrint(srcA.name),qPrint(dstA.type),qPrint(dstA.name));
2148 if (srcA.name.isEmpty() && !dstA.name.isEmpty())
2149 {
2150 //printf("type: '%s':='%s'\n",qPrint(srcA.type),qPrint(dstA.type));
2151 //printf("name: '%s':='%s'\n",qPrint(srcA.name),qPrint(dstA.name));
2152 srcA.type = dstA.type;
2153 srcA.name = dstA.name;
2154 }
2155 else if (!srcA.name.isEmpty() && dstA.name.isEmpty())
2156 {
2157 //printf("type: '%s':='%s'\n",qPrint(dstA.type),qPrint(srcA.type));
2158 //printf("name: '%s':='%s'\n",qPrint(dstA.name),qPrint(srcA.name));
2159 dstA.type = srcA.type;
2160 dstA.name = srcA.name;
2161 }
2162 else if (!srcA.name.isEmpty() && !dstA.name.isEmpty())
2163 {
2164 //printf("srcA.name=%s dstA.name=%s\n",qPrint(srcA.name),qPrint(dstA.name));
2165 if (forceNameOverwrite)
2166 {
2167 srcA.name = dstA.name;
2168 }
2169 else
2170 {
2171 if (srcA.docs.isEmpty() && !dstA.docs.isEmpty())
2172 {
2173 srcA.name = dstA.name;
2174 }
2175 else if (!srcA.docs.isEmpty() && dstA.docs.isEmpty())
2176 {
2177 dstA.name = srcA.name;
2178 }
2179 }
2180 }
2181 }
2182 else
2183 {
2184 //printf("2. merging '%s':'%s' <-> '%s':'%s'\n",qPrint(srcA.type),qPrint(srcA.name),qPrint(dstA.type),qPrint(dstA.name));
2185 srcA.type=srcA.type.stripWhiteSpace();
2186 dstA.type=dstA.type.stripWhiteSpace();
2187 if (srcA.type+" "+srcA.name==dstA.type) // "unsigned long:int" <-> "unsigned long int:bla"
2188 {
2189 srcA.type+=" "+srcA.name;
2190 srcA.name=dstA.name;
2191 }
2192 else if (dstA.type+" "+dstA.name==srcA.type) // "unsigned long int bla" <-> "unsigned long int"
2193 {
2194 dstA.type+=" "+dstA.name;
2195 dstA.name=srcA.name;
2196 }
2197 else if (srcA.name.isEmpty() && !dstA.name.isEmpty())
2198 {
2199 srcA.name = dstA.name;
2200 }
2201 else if (dstA.name.isEmpty() && !srcA.name.isEmpty())
2202 {
2203 dstA.name = srcA.name;
2204 }
2205 }
2206 int i1=srcA.type.find("::"),
2207 i2=dstA.type.find("::"),
2208 j1=static_cast<int>(srcA.type.length())-i1-2,
2209 j2=static_cast<int>(dstA.type.length())-i2-2;
2210 if (i1!=-1 && i2==-1 && srcA.type.right(j1)==dstA.type)
2211 {
2212 //printf("type: '%s':='%s'\n",qPrint(dstA.type),qPrint(srcA.type));
2213 //printf("name: '%s':='%s'\n",qPrint(dstA.name),qPrint(srcA.name));
2214 dstA.type = srcA.type.left(i1+2)+dstA.type;
2215 dstA.name = srcA.name;
2216 }
2217 else if (i1==-1 && i2!=-1 && dstA.type.right(j2)==srcA.type)
2218 {
2219 //printf("type: '%s':='%s'\n",qPrint(srcA.type),qPrint(dstA.type));
2220 //printf("name: '%s':='%s'\n",qPrint(dstA.name),qPrint(srcA.name));
2221 srcA.type = dstA.type.left(i2+2)+srcA.type;
2222 srcA.name = dstA.name;
2223 }
2224 if (srcA.docs.isEmpty() && !dstA.docs.isEmpty())
2225 {
2226 srcA.docs = dstA.docs;
2227 }
2228 else if (dstA.docs.isEmpty() && !srcA.docs.isEmpty())
2229 {
2230 dstA.docs = srcA.docs;
2231 }
2232 //printf("Merge argument '%s|%s' '%s|%s'\n",
2233 // qPrint(srcA.type), qPrint(srcA.name),
2234 // qPrint(dstA.type), qPrint(dstA.name));
2235 ++srcIt;
2236 ++dstIt;
2237 AUTO_TRACE_ADD("after merge: src=[type='{}',name='{}',def='{}'] dst=[type='{}',name='{}',def='{}']",
2238 srcA.type,srcA.name,srcA.defval,
2239 dstA.type,dstA.name,dstA.defval);
2240 }
2241}
#define AUTO_TRACE_ADD(...)
Definition docnode.cpp:48
QCString docs
Definition arguments.h:47

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

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

◆ mergeMemberOverrideOptions()

void mergeMemberOverrideOptions ( MemberDefMutable * md1,
MemberDefMutable * md2 )

Definition at line 6864 of file util.cpp.

6865{
6866 if (Config_getBool(CALL_GRAPH) !=md1->hasCallGraph()) md2->overrideCallGraph(md1->hasCallGraph());
6867 if (Config_getBool(CALLER_GRAPH)!=md1->hasCallerGraph()) md2->overrideCallerGraph(md1->hasCallerGraph());
6868 if (Config_getBool(CALL_GRAPH) !=md2->hasCallGraph()) md1->overrideCallGraph( md2->hasCallGraph());
6869 if (Config_getBool(CALLER_GRAPH)!=md2->hasCallerGraph()) md1->overrideCallerGraph(md2->hasCallerGraph());
6870
6871 if (Config_getBool(SHOW_ENUM_VALUES) !=md1->hasEnumValues()) md2->overrideEnumValues(md1->hasEnumValues());
6872 if (Config_getBool(SHOW_ENUM_VALUES) !=md2->hasEnumValues()) md1->overrideEnumValues( md2->hasEnumValues());
6873
6874 if (Config_getBool(REFERENCED_BY_RELATION)!=md1->hasReferencedByRelation()) md2->overrideReferencedByRelation(md1->hasReferencedByRelation());
6875 if (Config_getBool(REFERENCES_RELATION) !=md1->hasReferencesRelation()) md2->overrideReferencesRelation(md1->hasReferencesRelation());
6876 if (Config_getBool(REFERENCED_BY_RELATION)!=md2->hasReferencedByRelation()) md1->overrideReferencedByRelation(md2->hasReferencedByRelation());
6877 if (Config_getBool(REFERENCES_RELATION) !=md2->hasReferencesRelation()) md1->overrideReferencesRelation(md2->hasReferencesRelation());
6878
6879 if (Config_getBool(INLINE_SOURCES)!=md1->hasInlineSource()) md2->overrideInlineSource(md1->hasInlineSource());
6880 if (Config_getBool(INLINE_SOURCES)!=md2->hasInlineSource()) md1->overrideInlineSource(md2->hasInlineSource());
6881}
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(), MemberDefMutable::overrideCallerGraph(), MemberDefMutable::overrideCallGraph(), MemberDefMutable::overrideEnumValues(), MemberDefMutable::overrideInlineSource(), MemberDefMutable::overrideReferencedByRelation(), and MemberDefMutable::overrideReferencesRelation().

Referenced by combineDeclarationAndDefinition(), and findFriends().

◆ mergeScopes()

QCString mergeScopes ( const QCString & leftScope,
const QCString & 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 4578 of file util.cpp.

4579{
4580 AUTO_TRACE("leftScope='{}' rightScope='{}'",leftScope,rightScope);
4581 // case leftScope=="A" rightScope=="A::B" => result = "A::B"
4582 if (leftScopeMatch(leftScope,rightScope))
4583 {
4584 AUTO_TRACE_EXIT("case1={}",rightScope);
4585 return rightScope;
4586 }
4587 QCString result;
4588 int i=0,p=static_cast<int>(leftScope.length());
4589
4590 // case leftScope=="A::B" rightScope=="B::C" => result = "A::B::C"
4591 // case leftScope=="A::B" rightScope=="B" => result = "A::B"
4592 bool found=FALSE;
4593 while ((i=leftScope.findRev("::",p))>0)
4594 {
4595 if (leftScopeMatch(rightScope,leftScope.right(leftScope.length()-i-2)))
4596 {
4597 result = leftScope.left(i+2)+rightScope;
4598 found=TRUE;
4599 }
4600 p=i-1;
4601 }
4602 if (found)
4603 {
4604 AUTO_TRACE_EXIT("case2={}",result);
4605 return result;
4606 }
4607
4608 // case leftScope=="A" rightScope=="B" => result = "A::B"
4609 result=leftScope;
4610 if (!result.isEmpty() && !rightScope.isEmpty()) result+="::";
4611 result+=rightScope;
4612 AUTO_TRACE_EXIT("case3={}",result);
4613 return result;
4614}
bool leftScopeMatch(const QCString &scope, const QCString &name)
Definition util.cpp:882

References AUTO_TRACE, AUTO_TRACE_EXIT, FALSE, QCString::findRev(), QCString::isEmpty(), QCString::left(), leftScopeMatch(), QCString::length(), QCString::right(), and TRUE.

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

◆ nextUtf8CharPosition()

int nextUtf8CharPosition ( const QCString & utf8Str,
uint32_t len,
uint32_t startPos )

◆ normalizeNonTemplateArgumentsInString()

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

Definition at line 4284 of file util.cpp.

4288{
4289 // skip until <
4290 int p=name.find('<');
4291 if (p==-1) return name;
4292 p++;
4293 QCString result = name.left(p);
4294
4295 std::string s = name.mid(p).str();
4296 static const reg::Ex re(R"([\a:][\w:]*)");
4297 reg::Iterator it(s,re);
4299 size_t pi=0;
4300 // for each identifier in the template part (e.g. B<T> -> T)
4301 for (; it!=end ; ++it)
4302 {
4303 const auto &match = *it;
4304 size_t i = match.position();
4305 size_t l = match.length();
4306 result += s.substr(pi,i-pi);
4307 QCString n(match.str());
4308 bool found=FALSE;
4309 for (const Argument &formArg : formalArgs)
4310 {
4311 if (formArg.name == n)
4312 {
4313 found=TRUE;
4314 break;
4315 }
4316 }
4317 if (!found)
4318 {
4319 // try to resolve the type
4320 SymbolResolver resolver;
4321 const ClassDef *cd = resolver.resolveClass(context,n);
4322 if (cd)
4323 {
4324 result+=cd->name();
4325 }
4326 else
4327 {
4328 result+=n;
4329 }
4330 }
4331 else
4332 {
4333 result+=n;
4334 }
4335 pi=i+l;
4336 }
4337 result+=s.substr(pi);
4338 //printf("normalizeNonTemplateArgumentInString(%s)=%s\n",qPrint(name),qPrint(result));
4339 return removeRedundantWhiteSpace(result);
4340}
const ClassDef * resolveClass(const Definition *scope, const QCString &name, bool maybeUnlinkable=false, bool mayBeHidden=false)
Find the class definition matching name within the scope set.

References end(), FALSE, QCString::find(), QCString::left(), QCString::mid(), Definition::name(), removeRedundantWhiteSpace(), SymbolResolver::resolveClass(), QCString::str(), and TRUE.

Referenced by findUsedClassesForClass().

◆ openOutputFile()

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

Definition at line 6299 of file util.cpp.

6300{
6301 assert(!f.is_open());
6302 bool fileOpened=FALSE;
6303 bool writeToStdout=outFile=="-";
6304 if (writeToStdout) // write to stdout
6305 {
6306 f.basic_ios<char>::rdbuf(std::cout.rdbuf());
6307 fileOpened = true;
6308 }
6309 else // write to file
6310 {
6311 FileInfo fi(outFile.str());
6312 if (fi.exists()) // create a backup
6313 {
6314 Dir dir;
6315 FileInfo backup(fi.filePath()+".bak");
6316 if (backup.exists()) // remove existing backup
6317 dir.remove(backup.filePath());
6318 dir.rename(fi.filePath(),fi.filePath()+".bak");
6319 }
6320 f = Portable::openOutputStream(outFile);
6321 fileOpened = f.is_open();
6322 }
6323 return fileOpened;
6324}
bool rename(const std::string &orgName, const std::string &newName, bool acceptsAbsPath=true) const
Definition dir.cpp:321
std::ofstream openOutputStream(const QCString &name, bool append=false)
Definition portable.cpp:649

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

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

◆ parseCommentAsHtml()

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

Definition at line 5408 of file util.cpp.

5409{
5410 std::lock_guard lock(g_docCacheMutex);
5411 auto it = g_docCache.find(doc.str());
5412 if (it != g_docCache.end())
5413 {
5414 //printf("Cache: [%s]->[%s]\n",qPrint(doc),qPrint(it->second));
5415 return it->second;
5416 }
5417 auto parser { createDocParser() };
5418 auto ast { validatingParseTitle(*parser.get(),fileName,lineNr,doc) };
5419 auto astImpl = dynamic_cast<const DocNodeAST*>(ast.get());
5420 QCString result;
5421 if (astImpl)
5422 {
5423 TextStream t;
5424 OutputCodeList codeList;
5425 codeList.add<HtmlCodeGenerator>(&t);
5426 HtmlDocVisitor visitor(t,codeList,scope,fileName);
5427 std::visit(visitor,astImpl->root);
5428 result = t.str();
5429 }
5430 else // fallback, should not happen
5431 {
5432 result = filterTitle(doc);
5433 }
5434 //printf("Conversion: [%s]->[%s]\n",qPrint(doc),qPrint(result));
5435 g_docCache.insert(std::make_pair(doc.str(),result));
5436 return result;
5437}
Class representing the abstract syntax tree of a documentation block.
Definition docnode.h:1463
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:165
void add(OutputCodeIntfPtr &&p)
Definition outputlist.h:195
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:216
IDocParserPtr createDocParser()
factory function to create a parser
Definition docparser.cpp:55
IDocNodeASTPtr validatingParseTitle(IDocParser &parserIntf, const QCString &fileName, int lineNr, const QCString &input)
static std::unordered_map< std::string, QCString > g_docCache
Definition util.cpp:5406
QCString filterTitle(const QCString &title)
Definition util.cpp:5613
static std::mutex g_docCacheMutex
Definition util.cpp:5405

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

Referenced by PageDefImpl::addSectionsToIndex(), SearchTerm::makeTitle(), DefinitionImpl::navigationPathAsString(), writeGroupTreeNode(), writeIndex(), writeJavasScriptSearchDataPage(), and writePages().

◆ parseCommentAsText()

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

Definition at line 5352 of file util.cpp.

5354{
5355 if (doc.isEmpty()) return "";
5356 //printf("parseCommentAsText(%s)\n",qPrint(doc));
5357 TextStream t;
5358 auto parser { createDocParser() };
5359 auto ast { validatingParseDoc(*parser.get(),
5360 fileName,
5361 lineNr,
5362 scope,
5363 md,
5364 doc,
5365 DocOptions()
5366 .setAutolinkSupport(false))
5367 };
5368 auto astImpl = dynamic_cast<const DocNodeAST*>(ast.get());
5369 if (astImpl)
5370 {
5371 TextDocVisitor visitor(t);
5372 std::visit(visitor,astImpl->root);
5373 }
5375 int i=0;
5376 int charCnt=0;
5377 int l=static_cast<int>(result.length());
5378 while ((i=nextUTF8CharPosition(result,l,i))<l)
5379 {
5380 charCnt++;
5381 if (charCnt>=80) break;
5382 }
5383 if (charCnt>=80) // try to truncate the string
5384 {
5385 while ((i=nextUTF8CharPosition(result,l,i))<l && charCnt<100)
5386 {
5387 charCnt++;
5388 if (result.at(i)==',' ||
5389 result.at(i)=='.' ||
5390 result.at(i)=='!' ||
5391 result.at(i)=='?' ||
5392 result.at(i)=='}') // good for UTF-16 characters and } otherwise also a good point to stop the string
5393 {
5394 i++; // we want to be "behind" last inspected character
5395 break;
5396 }
5397 }
5398 }
5399 if ( i < l) result=result.left(i)+"...";
5400 return result.data();
5401}
Concrete visitor implementation for TEXT output.
IDocNodeASTPtr validatingParseDoc(IDocParser &parserIntf, const QCString &fileName, int startLine, const Definition *ctx, const MemberDef *md, const QCString &input, const DocOptions &options)
static int nextUTF8CharPosition(const QCString &utf8Str, uint32_t len, uint32_t startPos)
Definition util.cpp:5308

References QCString::at(), convertCharEntitiesToUTF8(), createDocParser(), QCString::data(), QCString::isEmpty(), QCString::left(), QCString::length(), nextUTF8CharPosition(), TextStream::str(), QCString::stripWhiteSpace(), and validatingParseDoc().

Referenced by RequirementManager::addRequirement(), PageDefImpl::addSectionsToIndex(), DefinitionImpl::computeTooltip(), GroupDefImpl::setGroupTitleLocal(), writeGroupTreeNode(), writeIndex(), writePages(), and RequirementManager::writeRef().

◆ patternMatch()

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

Definition at line 5687 of file util.cpp.

5688{
5689 std::string elem;
5690 auto getter = [](std::string s) -> QCString { return s; };
5691 return genericPatternMatch(fi,patList,elem,getter);
5692}

References genericPatternMatch().

Referenced by readDir().

◆ processMarkup()

QCString processMarkup ( const QCString & s)

◆ projectLogoFile()

QCString projectLogoFile ( )

Definition at line 3124 of file util.cpp.

3125{
3126 QCString projectLogo = Config_getString(PROJECT_LOGO);
3127 if (!projectLogo.isEmpty())
3128 {
3129 // check for optional width= and height= specifier
3130 int wi = projectLogo.find(" width=");
3131 if (wi!=-1) // and strip them
3132 {
3133 projectLogo = projectLogo.left(wi);
3134 }
3135 int hi = projectLogo.find(" height=");
3136 if (hi!=-1)
3137 {
3138 projectLogo = projectLogo.left(hi);
3139 }
3140 }
3141 //printf("projectlogo='%s'\n",qPrint(projectLogo));
3142 return projectLogo;
3143}

References Config_getString, QCString::find(), QCString::isEmpty(), and QCString::left().

Referenced by copyLogo(), and substituteKeywords().

◆ protectionLevelVisible()

bool protectionLevelVisible ( Protection prot)

Definition at line 5940 of file util.cpp.

5941{
5942 bool extractPrivate = Config_getBool(EXTRACT_PRIVATE);
5943 bool extractPackage = Config_getBool(EXTRACT_PACKAGE);
5944
5945 return (prot!=Protection::Private && prot!=Protection::Package) ||
5946 (prot==Protection::Private && extractPrivate) ||
5947 (prot==Protection::Package && extractPackage);
5948}

References Config_getBool.

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

◆ readInputFile()

bool readInputFile ( const QCString & fileName,
std::string & contents,
bool filter = TRUE,
bool isSourceCode = FALSE )

read a file name fileName and optionally filter and transcode it

Definition at line 5533 of file util.cpp.

5534{
5535 // try to open file
5536 FileInfo fi(fileName.str());
5537 if (!fi.exists()) return FALSE;
5538 QCString filterName = getFileFilter(fileName,isSourceCode);
5539 if (filterName.isEmpty() || !filter)
5540 {
5541 std::ifstream f = Portable::openInputStream(fileName,true);
5542 if (!f.is_open())
5543 {
5544 err("could not open file {}\n",fileName);
5545 return FALSE;
5546 }
5547 // read the file
5548 auto fileSize = fi.size();
5549 contents.resize(fileSize);
5550 f.read(contents.data(),fileSize);
5551 if (f.fail())
5552 {
5553 err("problems while reading file {}\n",fileName);
5554 return FALSE;
5555 }
5556 }
5557 else
5558 {
5559 QCString cmd=filterName+" \""+fileName+"\"";
5560 Debug::print(Debug::ExtCmd,0,"Executing popen(`{}`)\n",cmd);
5561 FILE *f=Portable::popen(cmd,"r");
5562 if (!f)
5563 {
5564 err("could not execute filter {}\n",filterName);
5565 return FALSE;
5566 }
5567 const int bufSize=4096;
5568 char buf[bufSize];
5569 int numRead = 0;
5570 while ((numRead=static_cast<int>(fread(buf,1,bufSize,f)))>0)
5571 {
5572 //printf(">>>>>>>>Reading %d bytes\n",numRead);
5573 contents.append(buf,numRead);
5574 }
5576 Debug::print(Debug::FilterOutput, 0, "Filter output\n");
5577 Debug::print(Debug::FilterOutput,0,"-------------\n{}\n-------------\n",contents);
5578 }
5579
5580 if (contents.size()>=2 &&
5581 static_cast<uint8_t>(contents[0])==0xFF &&
5582 static_cast<uint8_t>(contents[1])==0xFE // Little endian BOM
5583 ) // UCS-2LE encoded file
5584 {
5585 transcodeCharacterBuffer(fileName,contents,"UCS-2LE","UTF-8");
5586 }
5587 else if (contents.size()>=2 &&
5588 static_cast<uint8_t>(contents[0])==0xFE &&
5589 static_cast<uint8_t>(contents[1])==0xFF // big endian BOM
5590 ) // UCS-2BE encoded file
5591 {
5592 transcodeCharacterBuffer(fileName,contents,"UCS-2BE","UTF-8");
5593 }
5594 else if (contents.size()>=3 &&
5595 static_cast<uint8_t>(contents[0])==0xEF &&
5596 static_cast<uint8_t>(contents[1])==0xBB &&
5597 static_cast<uint8_t>(contents[2])==0xBF
5598 ) // UTF-8 encoded file
5599 {
5600 contents.erase(0,3); // remove UTF-8 BOM: no translation needed
5601 }
5602 else // transcode according to the INPUT_ENCODING setting
5603 {
5604 // do character transcoding if needed.
5605 transcodeCharacterBuffer(fileName,contents,getEncoding(fi),"UTF-8");
5606 }
5607
5608 filterCRLF(contents);
5609 return true;
5610}
@ 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:76
std::ifstream openInputStream(const QCString &name, bool binary=false, bool openAtEnd=false)
Definition portable.cpp:660
FILE * popen(const QCString &name, const QCString &type)
Definition portable.cpp:480
int pclose(FILE *stream)
Definition portable.cpp:489
static void filterCRLF(std::string &contents)
Definition util.cpp:1335
static void transcodeCharacterBuffer(const QCString &fileName, std::string &contents, const QCString &inputEncoding, const QCString &outputEncoding)
Definition util.cpp:5497
QCString getEncoding(const FileInfo &fi)
Definition util.cpp:5694
QCString getFileFilter(const QCString &name, bool isSourceCode)
Definition util.cpp:1402

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

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

◆ recodeString()

QCString recodeString ( const QCString & str,
const char * fromEncoding,
const char * toEncoding )

References FALSE, parent(), and TRUE.

◆ recognizeFixedForm()

bool recognizeFixedForm ( const QCString & contents,
FortranFormat format )

Definition at line 6346 of file util.cpp.

6347{
6348 int column=0;
6349 bool skipLine=FALSE;
6350
6351 if (format == FortranFormat::Fixed) return TRUE;
6352 if (format == FortranFormat::Free) return FALSE;
6353
6354 int tabSize=Config_getInt(TAB_SIZE);
6355 size_t sizCont = contents.length();
6356 for (size_t i=0;i<sizCont;i++)
6357 {
6358 column++;
6359
6360 switch(contents.at(i))
6361 {
6362 case '\n':
6363 column=0;
6364 skipLine=FALSE;
6365 break;
6366 case '\t':
6367 column += tabSize-1;
6368 break;
6369 case ' ':
6370 break;
6371 case '\000':
6372 return FALSE;
6373 case '#':
6374 skipLine=TRUE;
6375 break;
6376 case 'C':
6377 case 'c':
6378 if (column==1)
6379 {
6380 return !keyWordsFortranC(contents.data()+i);
6381 }
6382 // fallthrough
6383 case '*':
6384 if (column==1) return TRUE;
6385 if (skipLine) break;
6386 return FALSE;
6387 case '!':
6388 if (column!=6) skipLine=TRUE;
6389 break;
6390 default:
6391 if (skipLine) break;
6392 if (column>=7) return TRUE;
6393 return FALSE;
6394 }
6395 }
6396 return FALSE;
6397}
static bool keyWordsFortranC(const char *contents)
Definition util.cpp:6326

References QCString::at(), Config_getInt, QCString::data(), FALSE, Fixed, Free, keyWordsFortranC(), QCString::length(), and TRUE.

Referenced by FortranCodeParser::parseCode(), and parseMain().

◆ relativePathToRoot()

QCString relativePathToRoot ( const QCString & name)

Definition at line 3563 of file util.cpp.

3564{
3565 QCString result;
3566 if (Config_getBool(CREATE_SUBDIRS))
3567 {
3568 if (name.isEmpty())
3569 {
3570 return REL_PATH_TO_ROOT;
3571 }
3572 else
3573 {
3574 int i = name.findRev('/');
3575 if (i!=-1)
3576 {
3577 result=REL_PATH_TO_ROOT;
3578 }
3579 }
3580 }
3581 return result;
3582}
#define REL_PATH_TO_ROOT
Definition util.cpp:95

References Config_getBool, QCString::findRev(), QCString::isEmpty(), and REL_PATH_TO_ROOT.

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

◆ removeAnonymousScopes()

QCString removeAnonymousScopes ( const QCString & 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 162 of file util.cpp.

163{
164 std::string result;
165 if (str.isEmpty()) return result;
166
167 // helper to check if the found delimiter starts with a colon
168 auto startsWithColon = [](const std::string &del)
169 {
170 for (size_t i=0;i<del.size();i++)
171 {
172 if (del[i]=='@') return false;
173 else if (del[i]==':') return true;
174 }
175 return false;
176 };
177
178 // helper to check if the found delimiter ends with a colon
179 auto endsWithColon = [](const std::string &del)
180 {
181 for (int i=static_cast<int>(del.size())-1;i>=0;i--)
182 {
183 if (del[i]=='@') return false;
184 else if (del[i]==':') return true;
185 }
186 return false;
187 };
188
189 static const reg::Ex re(R"([\s:]*@\d+[\s:]*)");
190 std::string s = str.str();
191 reg::Iterator iter(s,re);
193 size_t p=0;
194 size_t sl=s.length();
195 bool needsSeparator=false;
196 for ( ; iter!=end ; ++iter)
197 {
198 const auto &match = *iter;
199 size_t i = match.position();
200 if (i>p) // add non-matching prefix
201 {
202 if (needsSeparator) result+="::";
203 needsSeparator=false;
204 result+=s.substr(p,i-p);
205 }
206 std::string delim = match.str();
207 needsSeparator = needsSeparator || (startsWithColon(delim) && endsWithColon(delim));
208 p = match.position()+match.length();
209 }
210 if (p<sl) // add trailing remainder
211 {
212 if (needsSeparator) result+="::";
213 result+=s.substr(p);
214 }
215 return result;
216}

References end(), QCString::isEmpty(), and QCString::str().

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

◆ removeEmptyLines()

QCString removeEmptyLines ( const QCString & s)

Definition at line 6589 of file util.cpp.

6590{
6591 std::string out;
6592 out.reserve(s.length());
6593 const char *p=s.data();
6594 if (p)
6595 {
6596 char c = 0;
6597 while ((c=*p++))
6598 {
6599 if (c=='\n')
6600 {
6601 const char *e = p;
6602 while (*e==' ' || *e=='\t') e++;
6603 if (*e=='\n')
6604 {
6605 p=e;
6606 }
6607 else out+=c;
6608 }
6609 else
6610 {
6611 out+=c;
6612 }
6613 }
6614 }
6615 //printf("removeEmptyLines(%s)=%s\n",qPrint(s),qPrint(out));
6616 return out;
6617}

References QCString::data(), QCString::length(), and QCString::reserve().

Referenced by substituteHtmlKeywords(), and substituteLatexKeywords().

◆ removeLongPathMarker()

QCString removeLongPathMarker ( QCString path)

Definition at line 288 of file util.cpp.

289{
290#if defined(_WIN32)
291 if (path.startsWith("//?/")) // strip leading "\\?\" part from path
292 {
293 path=path.mid(4);
294 }
295#endif
296 return path;
297}

References QCString::mid(), and QCString::startsWith().

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

◆ removeRedundantWhiteSpace()

QCString removeRedundantWhiteSpace ( const QCString & s)

Definition at line 568 of file util.cpp.

569{
570 bool cliSupport = Config_getBool(CPP_CLI_SUPPORT);
571 bool vhdl = Config_getBool(OPTIMIZE_OUTPUT_VHDL);
572
573 if (s.isEmpty() || vhdl) return s;
574
575 // We use a static character array to
576 // improve the performance of this function
577 // and thread_local is needed to make it multi-thread safe
578 static THREAD_LOCAL char *growBuf = nullptr;
579 static THREAD_LOCAL size_t growBufLen = 0;
580 if (s.length()*3>growBufLen) // For input character we produce at most 3 output characters,
581 {
582 growBufLen = s.length()*3;
583 growBuf = static_cast<char *>(realloc(growBuf,growBufLen+1)); // add 1 for 0-terminator
584 }
585 if (growBuf==nullptr) return s; // should not happen, only we run out of memory
586
587 const char *src=s.data();
588 char *dst=growBuf;
589
590 size_t i=0;
591 size_t l=s.length();
592 size_t csp=0;
593 size_t vosp=0;
594 size_t vsp=0;
595 size_t osp=0;
596 char pc=0;
597 // skip leading whitespace
598 while (i<l && isspace(static_cast<uint8_t>(src[i])))
599 {
600 i++;
601 }
602 for (;i<l;i++)
603 {
604 char c=src[i];
605 char nc=i+1<l ? src[i+1] : ' ';
606
607 auto searchForKeyword = [&](const char *kw,size_t &matchLen,size_t totalLen)
608 {
609 if (matchLen<=totalLen && c==kw[matchLen] && // character matches substring kw
610 (matchLen>0 || // inside search string
611 i==0 || // if it is the first character
612 !isId(pc) // the previous may not be a digit
613 )
614 )
615 matchLen++;
616 else // reset counter
617 matchLen=0;
618 };
619 searchForKeyword(constScope, csp, 5); // keyword: const
620 searchForKeyword(volatileScope, vosp, 8); // keyword: volatile
621 searchForKeyword(virtualScope, vsp, 7); // keyword: virtual
622
623 // search for "operator"
624 if (osp<11 && (osp>=8 || c==operatorScope[osp]) && // character matches substring "operator" followed by 3 arbitrary characters
625 (osp>0 || // inside search string
626 i==0 || // if it is the first character
627 !isId(pc) // the previous may not be a digit
628 )
629 )
630 osp++;
631 else // reset counter
632 osp=0;
633
634 switch(c)
635 {
636 case '"': // quoted string
637 {
638 *dst++=c;
639 i++;
640 for (;i<l;i++) // find end of string
641 {
642 c = src[i];
643 *dst++=c;
644 if (c=='\\' && i+1<l)
645 {
646 i++;
647 c = src[i];
648 *dst++=c;
649 }
650 else if (c=='"')
651 {
652 break;
653 }
654 }
655 }
656 break;
657 case '<': // current char is a <
658 *dst++=c;
659 if (i+1<l &&
660 (isId(nc)) && // next char is an id char
661 (osp<8) // string in front is not "operator"
662 )
663 {
664 *dst++=' '; // add extra space
665 }
666 break;
667 case '>': // current char is a >
668 if (i>0 && !isspace(static_cast<uint8_t>(pc)) &&
669 (isId(pc) || pc=='*' || pc=='&' || pc=='.' || pc=='>') && // prev char is an id char or space or *&.
670 (osp<8 || (osp==8 && pc!='-')) // string in front is not "operator>" or "operator->"
671 )
672 {
673 *dst++=' '; // add extra space in front
674 }
675 *dst++=c;
676 if (i+1<l && (nc=='-' || nc=='&')) // '>-' -> '> -'
677 {
678 *dst++=' '; // add extra space after
679 }
680 break;
681 case ',': // current char is a ,
682 *dst++=c;
683 if (i>0 && !isspace(static_cast<uint8_t>(pc)) &&
684 ((i+1<l && (isId(nc) || nc=='[')) || // the [ is for attributes (see bug702170)
685 (i+2<l && nc=='$' && isId(src[i+2])) || // for PHP: ',$name' -> ', $name'
686 (i+3<l && nc=='&' && src[i+2]=='$' && isId(src[i+3])) // for PHP: ',&$name' -> ', &$name'
687 )
688 )
689 {
690 *dst++=' '; // add extra space after
691 }
692 break;
693 case '^': // CLI 'Type^name' -> 'Type^ name'
694 case '%': // CLI 'Type%name' -> 'Type% name'
695 *dst++=c;
696 if (cliSupport && i+1<l && (isId(nc) || nc=='-'))
697 {
698 *dst++=' '; // add extra space after
699 }
700 break;
701 case ')': // current char is a ) -> ')name' -> ') name'
702 *dst++=c;
703 if (i+1<l && (isId(nc) || nc=='-'))
704 {
705 *dst++=' '; // add extra space after
706 }
707 break;
708 case '*':
709 if (i>0 && pc!=' ' && pc!='\t' && pc!=':' &&
710 pc!='*' && pc!='&' && pc!='(' && pc!='/' && pc!='[' &&
711 pc!='.' && osp<9
712 )
713 // avoid splitting &&, **, .*, operator*, operator->*
714 {
715 *dst++=' ';
716 }
717 *dst++=c;
718 break;
719 case '&':
720 if (i>0 && isId(pc) && osp<9)
721 {
722 if (nc != '=')
723 // avoid splitting operator&=
724 {
725 *dst++=' ';
726 }
727 }
728 *dst++=c;
729 break;
730 case '$': // '$name' -> ' $name'
731 // 'name$name' -> 'name$name'
732 if (isId(pc))
733 {
734 *dst++=c;
735 break;
736 }
737 // else fallthrough
738 case '@': // '@name' -> ' @name'
739 case '\'': // ''name' -> '' name'
740 if (i>0 && i+1<l && pc!='=' && pc!=':' && !isspace(static_cast<uint8_t>(pc)) &&
741 isId(nc) && osp<8) // ")id" -> ") id"
742 {
743 *dst++=' ';
744 }
745 *dst++=c;
746 break;
747 case ':': // current char is a :
748 if (csp==6) // replace const::A by const ::A
749 {
750 *dst++=' ';
751 csp=0;
752 }
753 else if (vosp==9) // replace volatile::A by volatile ::A
754 {
755 *dst++=' ';
756 vosp=0;
757 }
758 else if (vsp==8) // replace virtual::A by virtual ::A
759 {
760 *dst++=' ';
761 vsp=0;
762 }
763 *dst++=c;
764 break;
765 case ' ': // fallthrough
766 case '\n': // fallthrough
767 case '\t':
768 {
769 if (g_charAroundSpace.charMap[static_cast<uint8_t>(pc)].before &&
770 g_charAroundSpace.charMap[static_cast<uint8_t>(nc)].after &&
771 !(pc==',' && nc=='.') &&
772 (osp<8 || (osp>=8 && isId(pc) && isId(nc)))
773 // e.g. 'operator >>' -> 'operator>>',
774 // 'operator "" _x' -> 'operator""_x',
775 // but not 'operator int' -> 'operatorint'
776 )
777 { // keep space
778 *dst++=' ';
779 }
780 else if ((pc=='*' || pc=='&' || pc=='.') && nc=='>')
781 {
782 *dst++=' ';
783 }
784 }
785 break;
786 default:
787 *dst++=c;
788 auto correctKeywordAllowedInsideScope = [&](char cc,size_t &matchLen,size_t totalLen) {
789 if (c==cc && matchLen==totalLen)
790 {
791 if ((i+2<l && src[i+1] == ':' && src[i+2] == ':') || // keyword::
792 ((i>matchLen && src[i-matchLen] == ':' && src[i-matchLen-1] == ':')) // ::keyword
793 ) matchLen = 0;
794 };
795 };
796 correctKeywordAllowedInsideScope('t',csp, 5); // keyword: const
797 correctKeywordAllowedInsideScope('e',vosp,8); // keyword: volatile
798 correctKeywordAllowedInsideScope('l',vsp, 7); // keyword: virtual
799
800 auto correctKeywordNotPartOfScope = [&](char cc,size_t &matchLen,size_t totalLen)
801 {
802 if (c==cc && matchLen==totalLen && i+1<l && // found matching keyword
803 !(isId(nc) || nc==')' || nc==',' || qisspace(nc))
804 ) // prevent keyword ::A from being converted to keyword::A
805 {
806 *dst++=' ';
807 matchLen=0;
808 }
809 };
810 correctKeywordNotPartOfScope('t',csp, 5); // keyword: const
811 correctKeywordNotPartOfScope('e',vosp,8); // keyword: volatile
812 correctKeywordNotPartOfScope('l',vsp, 7); // keyword: virtual
813 break;
814 }
815 pc=c;
816 }
817 *dst++='\0';
818 //printf("removeRedundantWhitespace(%s)->%s\n",qPrint(s),growBuf);
819 return growBuf;
820}
#define THREAD_LOCAL
Definition doxygen.h:30
Token literal values and constants.
Definition CharStream.h:12
bool qisspace(char c)
Definition qcstring.h:81
static const char constScope[]
Definition util.cpp:521
static const char virtualScope[]
Definition util.cpp:523
static const char volatileScope[]
Definition util.cpp:522
static CharAroundSpace g_charAroundSpace
Definition util.cpp:565
static const char operatorScope[]
Definition util.cpp:524

References Config_getBool, constScope, QCString::data(), g_charAroundSpace, QCString::isEmpty(), isId(), QCString::length(), operatorScope, qisspace(), THREAD_LOCAL, virtualScope, and volatileScope.

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

◆ replaceAnonymousScopes()

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

Definition at line 219 of file util.cpp.

220{
221 if (s.isEmpty()) return s;
222 static const reg::Ex marker(R"(@\d+)");
223 std::string result = reg::replace(s.str(),marker,
224 !replacement.isEmpty() ? replacement.data() : "__anonymous__");
225 //printf("replaceAnonymousScopes('%s')='%s'\n",qPrint(s),qPrint(result));
226 return result;
227}
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:866

References QCString::data(), QCString::isEmpty(), reg::replace(), and QCString::str().

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

◆ replaceColorMarkers()

QCString replaceColorMarkers ( const QCString & 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 5809 of file util.cpp.

5810{
5811 if (str.isEmpty()) return QCString();
5812 std::string result;
5813 std::string s=str.str();
5814 static const reg::Ex re(R"(##[0-9A-Fa-f][0-9A-Fa-f])");
5815 reg::Iterator it(s,re);
5817 int hue = Config_getInt(HTML_COLORSTYLE_HUE);
5818 int sat = Config_getInt(HTML_COLORSTYLE_SAT);
5819 int gamma = Config_getInt(HTML_COLORSTYLE_GAMMA);
5820 size_t sl=s.length();
5821 size_t p=0;
5822 for (; it!=end ; ++it)
5823 {
5824 const auto &match = *it;
5825 size_t i = match.position();
5826 size_t l = match.length();
5827 if (i>p) result+=s.substr(p,i-p);
5828 std::string lumStr = match.str().substr(2);
5829#define HEXTONUM(x) (((x)>='0' && (x)<='9') ? ((x)-'0') : \
5830 ((x)>='a' && (x)<='f') ? ((x)-'a'+10) : \
5831 ((x)>='A' && (x)<='F') ? ((x)-'A'+10) : 0)
5832
5833 double r = 0,g = 0,b = 0;
5834 int level = HEXTONUM(lumStr[0])*16+HEXTONUM(lumStr[1]);
5835 ColoredImage::hsl2rgb(hue/360.0,sat/255.0,
5836 pow(level/255.0,gamma/100.0),&r,&g,&b);
5837 int red = static_cast<int>(r*255.0);
5838 int green = static_cast<int>(g*255.0);
5839 int blue = static_cast<int>(b*255.0);
5840 char colStr[8];
5841 colStr[0]='#';
5842 colStr[1]=hex[red>>4];
5843 colStr[2]=hex[red&0xf];
5844 colStr[3]=hex[green>>4];
5845 colStr[4]=hex[green&0xf];
5846 colStr[5]=hex[blue>>4];
5847 colStr[6]=hex[blue&0xf];
5848 colStr[7]=0;
5849 //printf("replacing %s->%s (level=%d)\n",qPrint(lumStr),colStr,level);
5850 result+=colStr;
5851 p=i+l;
5852 }
5853 if (p<sl) result+=s.substr(p);
5854 return result;
5855}
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, end(), hex, HEXTONUM, ColoredImage::hsl2rgb(), QCString::isEmpty(), and QCString::str().

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

◆ resolveLink()

bool resolveLink ( const QCString & scName,
const QCString & lr,
bool inSeeBlock,
const Definition ** resContext,
QCString & resAnchor,
SrcLangExt lang,
const QCString & prefix = QCString() )

Definition at line 2704 of file util.cpp.

2712{
2713 *resContext=nullptr;
2714
2715 QCString linkRef=lr;
2716 if (lang==SrcLangExt::CSharp)
2717 {
2718 linkRef = mangleCSharpGenericName(linkRef);
2719 }
2720 QCString linkRefWithoutTemplates = stripTemplateSpecifiersFromScope(linkRef,FALSE);
2721 AUTO_TRACE("scName='{}',ref='{}'",scName,lr);
2722 const FileDef *fd = nullptr;
2723 const GroupDef *gd = nullptr;
2724 const PageDef *pd = nullptr;
2725 const ClassDef *cd = nullptr;
2726 const DirDef *dir = nullptr;
2727 const ConceptDef *cnd = nullptr;
2728 const ModuleDef *modd = nullptr;
2729 const NamespaceDef *nd = nullptr;
2730 const SectionInfo *si = nullptr;
2731 bool ambig = false;
2732 if (linkRef.isEmpty()) // no reference name!
2733 {
2734 AUTO_TRACE_EXIT("no_ref");
2735 return FALSE;
2736 }
2737 else if ((pd=Doxygen::pageLinkedMap->find(linkRef))) // link to a page
2738 {
2739 gd = pd->getGroupDef();
2740 if (gd)
2741 {
2742 if (!pd->name().isEmpty()) si=SectionManager::instance().find(pd->name());
2743 *resContext=gd;
2744 if (si) resAnchor = si->label();
2745 }
2746 else
2747 {
2748 *resContext=pd;
2749 }
2750 AUTO_TRACE_EXIT("page");
2751 return TRUE;
2752 }
2753 else if ((si=SectionManager::instance().find(prefix+linkRef)))
2754 {
2755 *resContext=si->definition();
2756 resAnchor = si->label();
2757 AUTO_TRACE_EXIT("section anchor={} def={}",resAnchor,si->definition()?si->definition()->name():"<none>");
2758 return TRUE;
2759 }
2760 else if (!prefix.isEmpty() && (si=SectionManager::instance().find(linkRef)))
2761 {
2762 *resContext=si->definition();
2763 resAnchor = si->label();
2764 AUTO_TRACE_EXIT("section anchor={} def={}",resAnchor,si->definition()?si->definition()->name():"<none>");
2765 return TRUE;
2766 }
2767 else if ((pd=Doxygen::exampleLinkedMap->find(linkRef))) // link to an example
2768 {
2769 *resContext=pd;
2770 AUTO_TRACE_EXIT("example");
2771 return TRUE;
2772 }
2773 else if ((gd=Doxygen::groupLinkedMap->find(linkRef))) // link to a group
2774 {
2775 *resContext=gd;
2776 AUTO_TRACE_EXIT("group");
2777 return TRUE;
2778 }
2779 else if ((fd=findFileDef(Doxygen::inputNameLinkedMap,linkRef,ambig)) // file link
2780 && fd->isLinkable())
2781 {
2782 *resContext=fd;
2783 AUTO_TRACE_EXIT("file");
2784 return TRUE;
2785 }
2786 else if ((cd=getClass(linkRef))) // class link
2787 {
2788 *resContext=cd;
2789 resAnchor=cd->anchor();
2790 AUTO_TRACE_EXIT("class");
2791 return TRUE;
2792 }
2793 else if (lang==SrcLangExt::Java &&
2794 (cd=getClass(linkRefWithoutTemplates))) // Java generic class link
2795 {
2796 *resContext=cd;
2797 resAnchor=cd->anchor();
2798 AUTO_TRACE_EXIT("generic");
2799 return TRUE;
2800 }
2801 else if ((cd=getClass(linkRef+"-p"))) // Obj-C protocol link
2802 {
2803 *resContext=cd;
2804 resAnchor=cd->anchor();
2805 AUTO_TRACE_EXIT("protocol");
2806 return TRUE;
2807 }
2808 else if ((cnd=getConcept(linkRef))) // C++20 concept definition
2809 {
2810 *resContext=cnd;
2811 resAnchor=cnd->anchor();
2812 AUTO_TRACE_EXIT("concept");
2813 return TRUE;
2814 }
2815 else if ((modd=ModuleManager::instance().modules().find(linkRef)))
2816 {
2817 *resContext=modd;
2818 resAnchor=modd->anchor();
2819 AUTO_TRACE_EXIT("module");
2820 return TRUE;
2821 }
2822 else if ((nd=Doxygen::namespaceLinkedMap->find(linkRef)))
2823 {
2824 *resContext=nd;
2825 AUTO_TRACE_EXIT("namespace");
2826 return TRUE;
2827 }
2828 else if ((dir=Doxygen::dirLinkedMap->find(FileInfo(linkRef.str()).absFilePath()+"/"))
2829 && dir->isLinkable()) // TODO: make this location independent like filedefs
2830 {
2831 *resContext=dir;
2832 AUTO_TRACE_EXIT("directory");
2833 return TRUE;
2834 }
2835 else // probably a member reference
2836 {
2837 const MemberDef *md = nullptr;
2838 bool res = resolveRef(scName,lr,TRUE,resContext,&md,lang);
2839 if (md) resAnchor=md->anchor();
2840 AUTO_TRACE_EXIT("member? res={}",res);
2841 return res;
2842 }
2843}
A model of a directory symbol.
Definition dirdef.h:110
static NamespaceLinkedMap * namespaceLinkedMap
Definition doxygen.h:114
static PageLinkedMap * exampleLinkedMap
Definition doxygen.h:98
static DirLinkedMap * dirLinkedMap
Definition doxygen.h:128
static GroupLinkedMap * groupLinkedMap
Definition doxygen.h:113
std::string absFilePath() const
Definition fileinfo.cpp:101
A model of a group of symbols.
Definition groupdef.h:52
static ModuleManager & instance()
virtual const GroupDef * getGroupDef() const =0
QCString label() const
Definition section.h:69
Definition * definition() const
Definition section.h:77
bool resolveRef(const QCString &scName, const QCString &name, bool inSeeBlock, const Definition **resContext, const MemberDef **resMember, SrcLangExt lang, bool lookForSpecialization, const FileDef *currentFile, bool checkScope)
Definition util.cpp:2422
QCString mangleCSharpGenericName(const QCString &name)
Definition util.cpp:6916
QCString stripTemplateSpecifiersFromScope(const QCString &fullName, bool parentOnly, QCString *pLastScopeStripped, QCString scopeName, bool allowArtificial)
Definition util.cpp:4511

References FileInfo::absFilePath(), Definition::anchor(), AUTO_TRACE, AUTO_TRACE_EXIT, SectionInfo::definition(), Doxygen::dirLinkedMap, Doxygen::exampleLinkedMap, FALSE, LinkedMap< T, Hash, KeyEqual, Map >::find(), findFileDef(), getClass(), getConcept(), PageDef::getGroupDef(), Doxygen::groupLinkedMap, Doxygen::inputNameLinkedMap, ModuleManager::instance(), SectionManager::instance(), QCString::isEmpty(), Definition::isLinkable(), SectionInfo::label(), mangleCSharpGenericName(), Definition::name(), Doxygen::namespaceLinkedMap, Doxygen::pageLinkedMap, prefix, resolveRef(), QCString::str(), stripTemplateSpecifiersFromScope(), and TRUE.

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

◆ resolveRef()

bool resolveRef ( const QCString & scName,
const QCString & name,
bool inSeeBlock,
const Definition ** resContext,
const MemberDef ** resMember,
SrcLangExt lang,
bool lookForSpecialization,
const FileDef * currentFile,
bool checkScope )

Returns an object to reference to given its name and context

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

Definition at line 2422 of file util.cpp.

2432{
2433 AUTO_TRACE("scope={} name={} inSeeBlock={} lang={} lookForSpecialization={} currentFile={} checkScope={}",
2434 scName,name,inSeeBlock,lang,lookForSpecialization,currentFile ? currentFile->name() : "", checkScope);
2435 //printf("resolveRef(scope=%s,name=%s,inSeeBlock=%d)\n",qPrint(scName),qPrint(name),inSeeBlock);
2436 QCString tsName = name;
2437 //bool memberScopeFirst = tsName.find('#')!=-1;
2438 QCString fullName = substitute(tsName,"#","::");
2439 if (fullName.find("anonymous_namespace{")==-1)
2440 {
2441 fullName = removeRedundantWhiteSpace(substitute(fullName,".","::",3));
2442 }
2443 else
2444 {
2445 fullName = removeRedundantWhiteSpace(fullName);
2446 }
2447
2448 int templStartPos;
2449 if (lang==SrcLangExt::CSharp && (templStartPos=fullName.find('<'))!=-1)
2450 {
2451 int templEndPos = fullName.findRev('>');
2452 if (templEndPos!=-1)
2453 {
2454 fullName = mangleCSharpGenericName(fullName.left(templEndPos+1))+fullName.mid(templEndPos+1);
2455 AUTO_TRACE_ADD("C# mangled name='{}'",fullName);
2456 }
2457 }
2458
2459 int bracePos=findParameterList(fullName);
2460 int endNamePos=bracePos!=-1 ? bracePos : static_cast<int>(fullName.length());
2461 int scopePos=fullName.findRev("::",endNamePos);
2462 bool explicitScope = fullName.startsWith("::") && // ::scope or #scope
2463 (scopePos>2 || // ::N::A
2464 tsName.startsWith("::") || // ::foo in local scope
2465 scName==nullptr // #foo in global scope
2466 );
2467 bool allowTypeOnly=false;
2468
2469 // default result values
2470 *resContext=nullptr;
2471 *resMember=nullptr;
2472
2473 if (bracePos==-1) // simple name
2474 {
2475 // the following if() was commented out for releases in the range
2476 // 1.5.2 to 1.6.1, but has been restored as a result of bug report 594787.
2477 if (!inSeeBlock && scopePos==-1 && isLowerCase(tsName))
2478 { // link to lower case only name => do not try to autolink
2479 AUTO_TRACE_ADD("false");
2480 return FALSE;
2481 }
2482
2483 ClassDef *cd=nullptr;
2484 NamespaceDef *nd=nullptr;
2485 ConceptDef *cnd=nullptr;
2486 ModuleDef *modd=nullptr;
2487
2488 //printf("scName=%s fullName=%s\n",qPrint(scName),qPrint(fullName));
2489
2490 // check if this is a class or namespace reference
2491 if (scName!=fullName && getScopeDefs(scName,fullName,cd,cnd,nd,modd))
2492 {
2493 //printf("found scopeDef\n");
2494 if (cd) // scope matches that of a class
2495 {
2496 *resContext = cd;
2497 }
2498 else if (cnd)
2499 {
2500 *resContext = cnd;
2501 }
2502 else if (modd)
2503 {
2504 *resContext = modd;
2505 }
2506 else // scope matches that of a namespace
2507 {
2508 ASSERT(nd!=nullptr);
2509 *resContext = nd;
2510 }
2511 AUTO_TRACE_ADD("true");
2512 return TRUE;
2513 }
2514 else if (scName==fullName || (!inSeeBlock && scopePos==-1))
2515 // nothing to link => output plain text
2516 {
2517 //printf("found scName=%s fullName=%s scName==fullName=%d "
2518 // "inSeeBlock=%d scopePos=%d!\n",
2519 // qPrint(scName),qPrint(fullName),scName==fullName,inSeeBlock,scopePos);
2520
2521 // at this point we have a bare word that is not a class or namespace
2522 // we should also allow typedefs or enums to be linked, but not for instance member
2523 // functions, otherwise 'Foo' would always link to the 'Foo()' constructor instead of the
2524 // 'Foo' class. So we use this flag as a filter.
2525 allowTypeOnly=true;
2526 }
2527
2528 // continue search...
2529 }
2530
2531 // extract userscope+name
2532 QCString nameStr=fullName.left(endNamePos);
2533 if (explicitScope) nameStr=nameStr.mid(2);
2534
2535
2536 // extract arguments
2537 QCString argsStr;
2538 if (bracePos!=-1) argsStr=fullName.right(fullName.length()-bracePos);
2539
2540 // strip template specifier
2541 // TODO: match against the correct partial template instantiation
2542 int templPos=nameStr.find('<');
2543 bool tryUnspecializedVersion = FALSE;
2544 if (templPos!=-1 && nameStr.find("operator")==-1)
2545 {
2546 int endTemplPos=nameStr.findRev('>');
2547 if (endTemplPos!=-1)
2548 {
2549 if (!lookForSpecialization)
2550 {
2551 nameStr=nameStr.left(templPos)+nameStr.right(nameStr.length()-endTemplPos-1);
2552 }
2553 else
2554 {
2555 tryUnspecializedVersion = TRUE;
2556 }
2557 }
2558 }
2559
2560 QCString scopeStr=scName;
2561 if (!explicitScope && nameStr.length()>scopeStr.length() && leftScopeMatch(scopeStr,nameStr))
2562 {
2563 nameStr=nameStr.mid(scopeStr.length()+2);
2564 }
2565
2566 const GroupDef *gd = nullptr;
2567 const ConceptDef *cnd = nullptr;
2568 const ModuleDef *modd = nullptr;
2569
2570 // check if nameStr is a member or global.
2571 //printf("getDefs(scope=%s,name=%s,args=%s checkScope=%d)\n",
2572 // qPrint(scopeStr), qPrint(nameStr), qPrint(argsStr),checkScope);
2573 GetDefInput input(scopeStr,nameStr,argsStr);
2574 input.forceEmptyScope = explicitScope;
2575 input.currentFile = currentFile;
2576 input.checkCV = true;
2577 GetDefResult result = getDefs(input);
2578 if (result.found)
2579 {
2580 //printf("after getDefs checkScope=%d nameStr=%s\n",checkScope,qPrint(nameStr));
2581 if (checkScope && result.md && result.md->getOuterScope()==Doxygen::globalScope &&
2582 !result.md->isStrongEnumValue() &&
2583 (!scopeStr.isEmpty() || nameStr.find("::")>0))
2584 {
2585 // we did find a member, but it is a global one while we were explicitly
2586 // looking for a scoped variable. See bug 616387 for an example why this check is needed.
2587 // note we do need to support autolinking to "::symbol" hence the >0
2588 //printf("not global member!\n");
2589 *resContext=nullptr;
2590 *resMember=nullptr;
2591 AUTO_TRACE_ADD("false");
2592 return FALSE;
2593 }
2594 //printf("after getDefs md=%p cd=%p fd=%p nd=%p gd=%p\n",md,cd,fd,nd,gd);
2595 if (result.md)
2596 {
2597 if (!allowTypeOnly || result.md->isTypedef() || result.md->isEnumerate())
2598 {
2599 *resMember=result.md;
2600 *resContext=result.md;
2601 }
2602 else // md is not a type, but we explicitly expect one
2603 {
2604 *resContext=nullptr;
2605 *resMember=nullptr;
2606 AUTO_TRACE_ADD("false");
2607 return FALSE;
2608 }
2609 }
2610 else if (result.cd) *resContext=result.cd;
2611 else if (result.nd) *resContext=result.nd;
2612 else if (result.fd) *resContext=result.fd;
2613 else if (result.gd) *resContext=result.gd;
2614 else if (result.cnd) *resContext=result.cnd;
2615 else if (result.modd) *resContext=result.modd;
2616 else
2617 {
2618 *resContext=nullptr; *resMember=nullptr;
2619 AUTO_TRACE_ADD("false");
2620 return FALSE;
2621 }
2622 //printf("member=%s (md=%p) anchor=%s linkable()=%d context=%s\n",
2623 // qPrint(md->name()), md, qPrint(md->anchor()), md->isLinkable(), qPrint((*resContext)->name()));
2624 AUTO_TRACE_ADD("true");
2625 return TRUE;
2626 }
2627 else if (inSeeBlock && !nameStr.isEmpty() && (gd=Doxygen::groupLinkedMap->find(nameStr)))
2628 { // group link
2629 *resContext=gd;
2630 AUTO_TRACE_ADD("true");
2631 return TRUE;
2632 }
2633 else if ((cnd=Doxygen::conceptLinkedMap->find(nameStr)))
2634 {
2635 *resContext=cnd;
2636 AUTO_TRACE_ADD("true");
2637 return TRUE;
2638 }
2639 else if ((modd=ModuleManager::instance().modules().find(nameStr)))
2640 {
2641 *resContext=modd;
2642 AUTO_TRACE_ADD("true");
2643 return TRUE;
2644 }
2645 else if (tsName.find('.')!=-1) // maybe a link to a file
2646 {
2647 bool ambig = false;
2648 const FileDef *fd=findFileDef(Doxygen::inputNameLinkedMap,tsName,ambig);
2649 if (fd && !ambig)
2650 {
2651 *resContext=fd;
2652 AUTO_TRACE_ADD("true");
2653 return TRUE;
2654 }
2655 }
2656
2657 if (tryUnspecializedVersion)
2658 {
2659 bool b = resolveRef(scName,name,inSeeBlock,resContext,resMember,lang,FALSE,nullptr,checkScope);
2660 AUTO_TRACE_ADD("{}",b);
2661 return b;
2662 }
2663 if (bracePos!=-1) // Try without parameters as well, could be a constructor invocation
2664 {
2665 *resContext=getClass(fullName.left(bracePos));
2666 if (*resContext)
2667 {
2668 AUTO_TRACE_ADD("true");
2669 return TRUE;
2670 }
2671 }
2672 //printf("resolveRef: %s not found!\n",qPrint(name));
2673
2674 AUTO_TRACE_ADD("false");
2675 return FALSE;
2676}
static ConceptLinkedMap * conceptLinkedMap
Definition doxygen.h:97
virtual bool isStrongEnumValue() const =0
virtual bool isEnumerate() const =0
static bool isLowerCase(QCString &s)
Definition util.cpp:2410
int findParameterList(const QCString &name)
Returns the position in the string where a function parameter list begins, or -1 if one is not found.
Definition util.cpp:826
static bool getScopeDefs(const QCString &docScope, const QCString &scope, ClassDef *&cd, ConceptDef *&cnd, NamespaceDef *&nd, ModuleDef *&modd)
Definition util.cpp:2348

References ASSERT, AUTO_TRACE, AUTO_TRACE_ADD, GetDefResult::cd, GetDefInput::checkCV, GetDefResult::cnd, Doxygen::conceptLinkedMap, GetDefInput::currentFile, FALSE, GetDefResult::fd, QCString::find(), findFileDef(), findParameterList(), QCString::findRev(), GetDefInput::forceEmptyScope, GetDefResult::found, GetDefResult::gd, getClass(), getDefs(), Definition::getOuterScope(), getScopeDefs(), Doxygen::globalScope, Doxygen::groupLinkedMap, Doxygen::inputNameLinkedMap, ModuleManager::instance(), QCString::isEmpty(), MemberDef::isEnumerate(), isLowerCase(), MemberDef::isStrongEnumValue(), MemberDef::isTypedef(), QCString::left(), leftScopeMatch(), QCString::length(), mangleCSharpGenericName(), GetDefResult::md, QCString::mid(), GetDefResult::modd, Definition::name(), GetDefResult::nd, removeRedundantWhiteSpace(), resolveRef(), QCString::right(), QCString::startsWith(), substitute(), and TRUE.

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

◆ resolveTypeDef()

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

Definition at line 374 of file util.cpp.

376{
377 AUTO_TRACE("context='{}' qualifiedName='{}'",context?context->name():"",qualifiedName);
378 QCString result;
379 if (qualifiedName.isEmpty())
380 {
381 AUTO_TRACE_EXIT("empty name");
382 return result;
383 }
384
385 const Definition *mContext=context;
386 if (typedefContext) *typedefContext=context;
387
388 // see if the qualified name has a scope part
389 if (qualifiedName.find('<')!=-1)
390 {
391 AUTO_TRACE_EXIT("template");
392 return result;
393 }
394 int scopeIndex = qualifiedName.findRev("::");
395 QCString resName=qualifiedName;
396 if (scopeIndex!=-1) // strip scope part for the name
397 {
398 resName=qualifiedName.right(qualifiedName.length()-scopeIndex-2);
399 if (resName.isEmpty())
400 {
401 AUTO_TRACE_EXIT("invalid format");
402 return result;
403 }
404 }
405 const MemberDef *md=nullptr;
406 while (mContext && md==nullptr)
407 {
408 // step 1: get the right scope
409 const Definition *resScope=mContext;
410 if (scopeIndex!=-1)
411 {
412 // split-off scope part
413 QCString resScopeName = qualifiedName.left(scopeIndex);
414 //printf("resScopeName='%s'\n",qPrint(resScopeName));
415
416 // look-up scope in context
417 int is=0,ps=0,l=0;
418 while ((is=getScopeFragment(resScopeName,ps,&l))!=-1)
419 {
420 QCString qualScopePart = resScopeName.mid(is,l);
421 QCString tmp = resolveTypeDef(mContext,qualScopePart);
422 if (!tmp.isEmpty()) qualScopePart=tmp;
423 resScope = resScope->findInnerCompound(qualScopePart);
424 //printf("qualScopePart='%s' resScope=%p\n",qPrint(qualScopePart),resScope);
425 if (resScope==nullptr) break;
426 ps=is+l;
427 }
428 }
429 AUTO_TRACE_ADD("resScope='{}' resName='{}'",resScope?resScope->name():"",resName);
430
431 // step 2: get the member
432 if (resScope) // no scope or scope found in the current context
433 {
434 //printf("scope found: %s, look for typedef %s\n",
435 // qPrint(resScope->qualifiedName()),qPrint(resName));
436 MemberNameLinkedMap *mnd=nullptr;
437 bool searchRelated=false;
438 bool mustBeRelated=false;
439 if (resScope->definitionType()==Definition::TypeClass)
440 {
442 }
443 else
444 {
446 searchRelated=true;
447 }
448 MemberName *mn=mnd->find(resName);
449 if (mn==0 && searchRelated)
450 {
451 mn=Doxygen::memberNameLinkedMap->find(resName);
452 mustBeRelated=true;
453 }
454 if (mn)
455 {
456 int minDist=-1;
457 for (const auto &tmd_p : *mn)
458 {
459 const MemberDef *tmd = tmd_p.get();
460 AUTO_TRACE_ADD("found candidate member '{}' isTypeDef={}' isRelated={} mustBeRelated={}",
461 tmd->name(),tmd->isTypedef(),tmd->isRelated(),mustBeRelated);
462 //printf("Found member %s resScope=%s outerScope=%s mContext=%p\n",
463 // qPrint(tmd->name()),qPrint( resScope->name()),
464 // qPrint(tmd->getOuterScope()->name()), mContext);
465 if (tmd->isTypedef())
466 {
467 if (resScope==Doxygen::globalScope && tmd->isRelated() && mustBeRelated)
468 {
469 md = tmd;
470 }
471 else
472 {
473 SymbolResolver resolver;
474 int dist=resolver.isAccessibleFrom(resScope,tmd);
475 if (dist!=-1 && (md==nullptr || dist<minDist))
476 {
477 md = tmd;
478 minDist = dist;
479 }
480 }
481 }
482 }
483 }
484 }
485 mContext=mContext->getOuterScope();
486 }
487
488 AUTO_TRACE_ADD("md='{}'",md?md->name():"");
489 // step 3: get the member's type
490 if (md)
491 {
492 //printf(">>resolveTypeDef: Found typedef name '%s' in scope '%s' value='%s' args='%s'\n",
493 // qPrint(qualifiedName),qPrint(context->name()),qPrint(md->typeString()),qPrint(md->argsString())
494 // );
495 result=md->typeString();
496 QCString args = md->argsString();
497 if (args.find(")(")!=-1) // typedef of a function/member pointer
498 {
499 result+=args;
500 }
501 else if (args.find('[')!=-1) // typedef of an array
502 {
503 result+=args;
504 }
505 if (typedefContext) *typedefContext=md->getOuterScope();
506 }
507 else
508 {
509 //printf(">>resolveTypeDef: Typedef '%s' not found in scope '%s'!\n",
510 // qPrint(qualifiedName),context ? qPrint(context->name()) : "<global>");
511 }
512 AUTO_TRACE_EXIT("result='{}'",result);
513 return result;
514}
virtual const Definition * findInnerCompound(const QCString &name) const =0
static MemberNameLinkedMap * functionNameLinkedMap
Definition doxygen.h:111
static MemberNameLinkedMap * memberNameLinkedMap
Definition doxygen.h:110
virtual QCString typeString() const =0
virtual bool isRelated() const =0
virtual QCString argsString() 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.
QCString resolveTypeDef(const Definition *context, const QCString &qualifiedName, const Definition **typedefContext)
Definition util.cpp:374
int getScopeFragment(const QCString &s, int p, int *l)
Definition util.cpp:4623

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

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

◆ rightScopeMatch()

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

Definition at line 871 of file util.cpp.

872{
873 size_t sl=scope.length();
874 size_t nl=name.length();
875 return (name==scope || // equal
876 (scope.right(nl)==name && // substring
877 sl>1+nl && scope.at(sl-nl-1)==':' && scope.at(sl-nl-2)==':' // scope
878 )
879 );
880}

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

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

◆ selectBlocks()

QCString selectBlocks ( const QCString & 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 6412 of file util.cpp.

6413{
6414 if (s.isEmpty()) return s;
6415
6416 // helper to find the end of a block
6417 auto skipBlock = [&markerInfo](const char *p,const SelectionBlock &blk)
6418 {
6419 char c = 0;
6420 while ((c=*p))
6421 {
6422 if (c==markerInfo.markerChar && qstrncmp(p,markerInfo.endStr,markerInfo.endLen)==0) // end marker
6423 {
6424 size_t len = markerInfo.endLen;
6425 bool negate = *(p+markerInfo.endLen)=='!';
6426 if (negate) len++;
6427 size_t blkNameLen = qstrlen(blk.name);
6428 if (qstrncmp(p+len,blk.name,blkNameLen)==0 && // matching marker name
6429 qstrncmp(p+len+blkNameLen,markerInfo.closeStr,markerInfo.closeLen)==0) // matching marker closing
6430 {
6431 //printf("Found end marker %s enabled=%d negate=%d\n",blk.name,blk.enabled,negate);
6432 return p+len+blkNameLen+markerInfo.closeLen;
6433 }
6434 else // not the right marker id
6435 {
6436 p++;
6437 }
6438 }
6439 else // not and end marker
6440 {
6441 p++;
6442 }
6443 }
6444 return p;
6445 };
6446
6447 QCString result;
6448 result.reserve(s.length());
6449 const char *p = s.data();
6450 char c = 0;
6451 while ((c=*p))
6452 {
6453 if (c==markerInfo.markerChar) // potential start of marker
6454 {
6455 if (qstrncmp(p,markerInfo.beginStr,markerInfo.beginLen)==0) // start of begin marker
6456 {
6457 bool found = false;
6458 size_t len = markerInfo.beginLen;
6459 bool negate = *(p+len)=='!';
6460 if (negate) len++;
6461 for (const auto &blk : blockList)
6462 {
6463 size_t blkNameLen = qstrlen(blk.name);
6464 if (qstrncmp(p+len,blk.name,blkNameLen)==0 && // matching marker name
6465 qstrncmp(p+len+blkNameLen,markerInfo.closeStr,markerInfo.closeLen)==0) // matching marker closing
6466 {
6467 bool blockEnabled = blk.enabled!=negate;
6468 //printf("Found start marker %s enabled=%d negate=%d\n",blk.name,blk.enabled,negate);
6469 p+=len+blkNameLen+markerInfo.closeLen;
6470 if (!blockEnabled) // skip until the end of the block
6471 {
6472 //printf("skipping block\n");
6473 p=skipBlock(p,blk);
6474 }
6475 found=true;
6476 break;
6477 }
6478 }
6479 if (!found) // unknown marker id
6480 {
6481 result+=c;
6482 p++;
6483 }
6484 }
6485 else if (qstrncmp(p,markerInfo.endStr,markerInfo.endLen)==0) // start of end marker
6486 {
6487 bool found = false;
6488 size_t len = markerInfo.endLen;
6489 bool negate = *(p+len)=='!';
6490 if (negate) len++;
6491 for (const auto &blk : blockList)
6492 {
6493 size_t blkNameLen = qstrlen(blk.name);
6494 if (qstrncmp(p+len,blk.name,blkNameLen)==0 && // matching marker name
6495 qstrncmp(p+len+blkNameLen,markerInfo.closeStr,markerInfo.closeLen)==0) // matching marker closing
6496 {
6497 //printf("Found end marker %s enabled=%d negate=%d\n",blk.name,blk.enabled,negate);
6498 p+=len+blkNameLen+markerInfo.closeLen;
6499 found=true;
6500 break;
6501 }
6502 }
6503 if (!found) // unknown marker id
6504 {
6505 result+=c;
6506 p++;
6507 }
6508 }
6509 else // not a start or end marker
6510 {
6511 result+=c;
6512 p++;
6513 }
6514 }
6515 else // not a marker character
6516 {
6517 result+=c;
6518 p++;
6519 }
6520 }
6521 //printf("====\n%s\n-----\n%s\n~~~~\n",qPrint(s),qPrint(result));
6522 return result;
6523}
uint32_t qstrlen(const char *str)
Returns the length of string str, or 0 if a null pointer is passed.
Definition qcstring.h:58

References SelectionMarkerInfo::beginLen, SelectionMarkerInfo::beginStr, SelectionMarkerInfo::closeLen, SelectionMarkerInfo::closeStr, QCString::data(), SelectionMarkerInfo::endLen, SelectionMarkerInfo::endStr, QCString::isEmpty(), QCString::length(), SelectionMarkerInfo::markerChar, qstrlen(), qstrncmp(), and QCString::reserve().

Referenced by substituteHtmlKeywords(), and substituteLatexKeywords().

◆ showFileDefMatches()

QCString showFileDefMatches ( const FileNameLinkedMap * fnMap,
const QCString & n )

Definition at line 3002 of file util.cpp.

3003{
3004 QCString result;
3005 QCString name=Dir::cleanDirPath(n.str());
3006 QCString path;
3007 int slashPos=std::max(name.findRev('/'),name.findRev('\\'));
3008 if (slashPos!=-1)
3009 {
3010 path=removeLongPathMarker(name.left(slashPos+1));
3011 name=name.right(name.length()-slashPos-1);
3012 }
3013 const FileName *fn=fnMap->find(name);
3014 if (fn)
3015 {
3016 bool first = true;
3017 QCString pathStripped = stripFromIncludePath(path);
3018 for (const auto &fd_p : *fn)
3019 {
3020 FileDef *fd = fd_p.get();
3021 QCString fdStripPath = stripFromIncludePath(fd->getPath());
3022 if (path.isEmpty() ||
3023 (!pathStripped.isEmpty() && fdStripPath.endsWith(pathStripped)) ||
3024 (pathStripped.isEmpty() && fdStripPath.isEmpty()))
3025 {
3026 if (!first) result += "\n";
3027 else first = false;
3028 result+=" "+fd->absFilePath();
3029 }
3030 }
3031
3032 }
3033 return result;
3034}

References FileDef::absFilePath(), Dir::cleanDirPath(), QCString::endsWith(), LinkedMap< T, Hash, KeyEqual, Map >::find(), QCString::findRev(), FileDef::getPath(), QCString::isEmpty(), QCString::left(), QCString::length(), removeLongPathMarker(), QCString::right(), QCString::str(), and stripFromIncludePath().

Referenced by addIncludeFile(), buildFileList(), DocParser::findAndCopyImage(), DocDiaFile::parse(), DocDotFile::parse(), DocMscFile::parse(), DocPlantUmlFile::parse(), readIncludeFile(), DocParser::readTextFileByName(), and readTextFileByName().

◆ split() [1/2]

StringVector split ( const std::string & s,
const reg::Ex & delimiter )

split input string s by regular expression delimiter delimiter.

returns a vector of non-empty strings that are between the delimiters

Definition at line 6638 of file util.cpp.

6639{
6640 StringVector result;
6641 reg::Iterator iter(s, delimiter);
6643 size_t p=0;
6644 for ( ; iter != end; ++iter)
6645 {
6646 const auto &match = *iter;
6647 size_t i=match.position();
6648 size_t l=match.length();
6649 if (i>p) result.push_back(s.substr(p,i-p));
6650 p=i+l;
6651 }
6652 if (p<s.length()) result.push_back(s.substr(p));
6653 return result;
6654}

References end().

◆ split() [2/2]

StringVector split ( const std::string & s,
const std::string & delimiter )

split input string s by string delimiter delimiter.

returns a vector of non-empty strings that are between the delimiters

Definition at line 6621 of file util.cpp.

6622{
6623 StringVector result;
6624 size_t prev = 0, pos = 0, len = s.length();
6625 do
6626 {
6627 pos = s.find(delimiter, prev);
6628 if (pos == std::string::npos) pos = len;
6629 if (pos>prev) result.push_back(s.substr(prev,pos-prev));
6630 prev = pos + delimiter.length();
6631 }
6632 while (pos<len && prev<len);
6633 return result;
6634}

Referenced by VHDLOutlineParser::addProto(), VHDLOutlineParser::addVhdlType(), FlowChart::alignCommentNode(), anonymous_namespace{tagreader.cpp}::TagFileParser::buildLists(), VHDLOutlineParser::checkInlineCode(), checkVhdlString(), VHDLOutlineParser::createFunction(), VhdlDocGen::findArchitecture(), CitationManager::generatePage(), getFilteredImageAttributes(), VhdlDocGen::getIndexWord(), DocPara::handleCite(), DocPara::handleCommand(), DocParser::handleImage(), DocPara::handleInclude(), Qhp::initialize(), VhdlDocGen::parseForBinding(), VhdlDocGen::parseForConfig(), VhdlDocGen::writeInlineClassLink(), and VhdlDocGen::writeRecUnitDocu().

◆ stackTrace()

void stackTrace ( )

Definition at line 5469 of file util.cpp.

5470{
5471#ifdef TRACINGSUPPORT
5472 void *backtraceFrames[128];
5473 int frameCount = backtrace(backtraceFrames, 128);
5474 const size_t cmdLen = 40960;
5475 static char cmd[cmdLen];
5476 char *p = cmd;
5477 p += qsnprintf(p,cmdLen,"/usr/bin/atos -p %d ", (int)getpid());
5478 for (int x = 0; x < frameCount; x++)
5479 {
5480 p += qsnprintf(p,cmdLen,"%p ", backtraceFrames[x]);
5481 }
5482 fprintf(stderr,"========== STACKTRACE START ==============\n");
5483 if (FILE *fp = Portable::popen(cmd, "r"))
5484 {
5485 char resBuf[512];
5486 while (size_t len = fread(resBuf, 1, sizeof(resBuf), fp))
5487 {
5488 fwrite(resBuf, 1, len, stderr);
5489 }
5490 Portable::pclose(fp);
5491 }
5492 fprintf(stderr,"============ STACKTRACE END ==============\n");
5493 //fprintf(stderr,"%s\n", frameStrings[x]);
5494#endif
5495}

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

◆ stripAnonymousNamespaceScope()

QCString stripAnonymousNamespaceScope ( const QCString & s)

Definition at line 231 of file util.cpp.

232{
233 int i=0,p=0,l=0;
234 QCString newScope;
235 int sl = static_cast<int>(s.length());
236 while ((i=getScopeFragment(s,p,&l))!=-1)
237 {
238 //printf("Scope fragment %s\n",qPrint(s.mid(i,l)));
239 if (Doxygen::namespaceLinkedMap->find(s.left(i+l))!=nullptr)
240 {
241 if (s.at(i)!='@')
242 {
243 if (!newScope.isEmpty()) newScope+="::";
244 newScope+=s.mid(i,l);
245 }
246 }
247 else if (i<sl)
248 {
249 if (!newScope.isEmpty()) newScope+="::";
250 newScope+=s.right(sl-i);
251 goto done;
252 }
253 p=i+l;
254 }
255done:
256 //printf("stripAnonymousNamespaceScope('%s')='%s'\n",qPrint(s),qPrint(newScope));
257 return newScope;
258}

References QCString::at(), getScopeFragment(), QCString::isEmpty(), QCString::left(), QCString::length(), QCString::mid(), Doxygen::namespaceLinkedMap, and QCString::right().

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

◆ stripExtension()

◆ stripExtensionGeneral()

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

◆ stripFromIncludePath()

QCString stripFromIncludePath ( const QCString & path)

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

Definition at line 330 of file util.cpp.

331{
332 return stripFromPath(path,Config_getList(STRIP_FROM_INC_PATH));
333}

References Config_getList, and stripFromPath().

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

◆ stripFromPath()

QCString stripFromPath ( const QCString & path)

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

Definition at line 322 of file util.cpp.

323{
324 return stripFromPath(path,Config_getList(STRIP_FROM_PATH));
325}

References Config_getList, and stripFromPath().

◆ stripIndentation()

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

Definition at line 5952 of file util.cpp.

5953{
5954 if (s.isEmpty()) return s; // empty string -> we're done
5955
5956 //printf("stripIndentation:\n%s\n------\n",qPrint(s));
5957 // compute minimum indentation over all lines
5958 const char *p=s.data();
5959 char c=0;
5960 int indent=0;
5961 int minIndent=1000000; // "infinite"
5962 bool searchIndent=true;
5963 int tabSize=Config_getInt(TAB_SIZE);
5964 bool skipFirst = skipFirstLine;
5965 while ((c=*p++))
5966 {
5967 if (c=='\t') { indent+=tabSize - (indent%tabSize); }
5968 else if (c=='\n') { indent=0; searchIndent=true; skipFirst=false; }
5969 else if (c==' ') { indent++; }
5970 else if (searchIndent && !skipFirst)
5971 {
5972 searchIndent=false;
5973 if (indent<minIndent) minIndent=indent;
5974 }
5975 }
5976
5977 // no indent to remove -> we're done
5978 if (minIndent==0) return substitute(s,"@ilinebr","\\ilinebr");
5979
5980 // remove minimum indentation for each line
5981 TextStream result;
5982 p=s.data();
5983 indent=0;
5984 skipFirst=skipFirstLine;
5985 while ((c=*p++))
5986 {
5987 if (c=='\n') // start of new line
5988 {
5989 indent=0;
5990 result << c;
5991 skipFirst=false;
5992 }
5993 else if (indent<minIndent && !skipFirst) // skip until we reach minIndent
5994 {
5995 if (c=='\t')
5996 {
5997 int newIndent = indent+tabSize-(indent%tabSize);
5998 int i=newIndent;
5999 while (i>minIndent) // if a tab crosses the minIndent boundary fill the rest with spaces
6000 {
6001 result << ' ';
6002 i--;
6003 }
6004 indent=newIndent;
6005 }
6006 else // space
6007 {
6008 indent++;
6009 }
6010 }
6011 else if (c=='\\' && literal_at(p,"ilinebr "))
6012 // we also need to remove the indentation after a \ilinebr command at the end of a line
6013 {
6014 result << "\\ilinebr ";
6015 p+=8;
6016 int skipAmount=0;
6017 for (int j=0;j<minIndent;j++) if (*(p+j)==' ') skipAmount++; // test to see if we have the indent
6018 if (skipAmount==minIndent)
6019 {
6020 p+=skipAmount; // remove the indent
6021 }
6022 }
6023 else if (c=='@' && literal_at(p,"ilinebr"))
6024 {
6025 result << "\\ilinebr";
6026 p+=7;
6027 }
6028 else // copy anything until the end of the line
6029 {
6030 result << c;
6031 }
6032 }
6033
6034 //printf("stripIndentation: result=\n%s\n------\n",qPrint(result.str()));
6035
6036 return result.str();
6037}

References Config_getInt, QCString::data(), QCString::isEmpty(), literal_at(), TextStream::str(), and substitute().

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

◆ stripIndentationVerbatim()

void stripIndentationVerbatim ( QCString & doc,
const int indentationLevel,
bool skipFirstLine = true )

Definition at line 6041 of file util.cpp.

6042{
6043 //printf("stripIndentationVerbatim(level=%d):\n%s\n------\n",indentationLevel,qPrint(doc));
6044 if (indentationLevel <= 0 || doc.isEmpty()) return; // nothing to strip
6045
6046 // by stripping content the string will only become shorter so we write the results
6047 // back into the input string and then resize it at the end.
6048 char c = 0;
6049 const char *src = doc.data();
6050 char *dst = doc.rawData();
6051 bool insideIndent = !skipFirstLine; // skip the initial line from stripping
6052 int cnt = 0;
6053 if (!skipFirstLine) cnt = indentationLevel;
6054 while ((c=*src++))
6055 {
6056 // invariant: dst<=src
6057 switch(c)
6058 {
6059 case '\n':
6060 *dst++ = c;
6061 insideIndent = true;
6062 cnt = indentationLevel;
6063 break;
6064 case ' ':
6065 if (insideIndent)
6066 {
6067 if (cnt>0) // count down the spacing until the end of the indent
6068 {
6069 cnt--;
6070 }
6071 else // reached the end of the indent, start of the part of the line to keep
6072 {
6073 insideIndent = false;
6074 *dst++ = c;
6075 }
6076 }
6077 else // part after indent, copy to the output
6078 {
6079 *dst++ = c;
6080 }
6081 break;
6082 default:
6083 insideIndent = false;
6084 *dst++ = c;
6085 break;
6086 }
6087 }
6088 doc.resize(static_cast<uint32_t>(dst-doc.data()));
6089 //printf("stripIndentationVerbatim: result=\n%s\n------\n",qPrint(doc));
6090}
char * rawData()
Returns a writable pointer to the data.
Definition qcstring.h:178
void resize(size_t newlen)
Definition qcstring.h:180

References QCString::data(), QCString::isEmpty(), QCString::rawData(), and QCString::resize().

Referenced by MemberDefImpl::setInitializer().

◆ stripLeadingAndTrailingEmptyLines()

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

Special version of QCString::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 5013 of file util.cpp.

5014{
5015 if (s.isEmpty()) return QCString();
5016 const char *p = s.data();
5017
5018 // search for leading empty lines
5019 int i=0,li=-1,l=static_cast<int>(s.length());
5020 char c = 0;
5021 while ((c=*p))
5022 {
5023 if (c==' ' || c=='\t' || c=='\r') { i++; p++; }
5024 else if (c=='\\' && literal_at(p,"\\ilinebr")) { i+=8; li=i; p+=8; }
5025 else if (c=='\n') { i++; li=i; docLine++; p++; }
5026 else break;
5027 }
5028
5029 // search for trailing empty lines
5030 int b=l-1,bi=-1;
5031 p=s.data()+b;
5032 while (b>=0)
5033 {
5034 c=*p;
5035 if (c==' ' || c=='\t' || c=='\r') { b--; p--; }
5036 else if (c=='r' && b>=7 && literal_at(p-7,"\\ilinebr")) { bi=b-7; b-=8; p-=8; }
5037 else if (c=='>' && b>=11 && literal_at(p-11,"\\ilinebr<br>")) { bi=b-11; b-=12; p-=12; }
5038 else if (c=='\n') { bi=b; b--; p--; }
5039 else break;
5040 }
5041
5042 // return whole string if no leading or trailing lines where found
5043 if (li==-1 && bi==-1) return s;
5044
5045 // return substring
5046 if (bi==-1) bi=l;
5047 if (li==-1) li=0;
5048 if (bi<=li) return QCString(); // only empty lines
5049 //printf("docLine='%s' len=%d li=%d bi=%d\n",qPrint(s),s.length(),li,bi);
5050 return s.mid(li,bi-li);
5051}

References QCString::data(), QCString::isEmpty(), QCString::length(), literal_at(), and QCString::mid().

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

◆ stripPath()

QCString stripPath ( const QCString & s)

Definition at line 4932 of file util.cpp.

4933{
4934 QCString result=s;
4935 int i=result.findRev('/');
4936 if (i!=-1)
4937 {
4938 result=result.mid(i+1);
4939 }
4940 i=result.findRev('\\');
4941 if (i!=-1)
4942 {
4943 result=result.mid(i+1);
4944 }
4945 return result;
4946}

References QCString::findRev(), and QCString::mid().

Referenced by LatexGenerator::addLabel(), anonymous_namespace{tagreader.cpp}::TagFileParser::buildLists(), RTFGenerator::endDoxyAnchor(), LatexGenerator::endIndexItem(), LatexGenerator::endIndexValue(), LatexGenerator::endTitleHead(), makeBaseName(), objectLinkToString(), objectLinkToString(), objectLinkToString(), DocbookDocVisitor::operator()(), DocbookDocVisitor::operator()(), DocbookDocVisitor::operator()(), DocbookDocVisitor::operator()(), DocbookDocVisitor::operator()(), DocbookDocVisitor::operator()(), DocbookDocVisitor::operator()(), DocbookDocVisitor::operator()(), DocbookDocVisitor::operator()(), 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()(), 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()(), DotFilePatcher::run(), SearchIndexExternal::setCurrentDoc(), DocbookGenerator::startDoxyAnchor(), LatexGenerator::startDoxyAnchor(), DocbookGenerator::startFile(), LatexGenerator::startFile(), RTFGenerator::startFile(), DocbookDocVisitor::startLink(), LatexDocVisitor::startLink(), RTFDocVisitor::startLink(), LatexDocVisitor::startPlantUmlFile(), DocbookGenerator::startSection(), LatexGenerator::startSection(), LatexGenerator::startTextLink(), RTFGenerator::startTextLink(), substituteHtmlKeywords(), substituteKeywords(), LatexGenerator::writeAnchor(), RTFGenerator::writeAnchor(), LatexCodeGenerator::writeCodeLink(), RTFCodeGenerator::writeCodeLink(), DocbookCodeGenerator::writeCodeLinkLine(), MemberList::writeDeclarations(), DocbookDocVisitor::writeDiaFile(), writeDocbookLink(), LatexCodeGenerator::writeLineNumber(), RTFCodeGenerator::writeLineNumber(), DocbookDocVisitor::writePlantUMLFile(), LatexDocVisitor::writePlantUMLFile(), RTFGenerator::writeRTFReference(), and RTFGenerator::writeStartAnnoItem().

◆ stripScope()

QCString stripScope ( const QCString & 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 3763 of file util.cpp.

3764{
3765 QCString result = name;
3766 int l = static_cast<int>(result.length());
3767 int p = 0;
3768 bool done = FALSE;
3769 bool skipBracket=FALSE; // if brackets do not match properly, ignore them altogether
3770 int count=0;
3771 int round=0;
3772
3773 do
3774 {
3775 p=l-1; // start at the end of the string
3776 while (p>=0 && count>=0)
3777 {
3778 char c=result.at(p);
3779 switch (c)
3780 {
3781 case ':':
3782 // only exit in the case of ::
3783 //printf("stripScope(%s)=%s\n",name,qPrint(result.right(l-p-1)));
3784 if (p>0 && result.at(p-1)==':' && (count==0 || skipBracket))
3785 {
3786 return result.right(l-p-1);
3787 }
3788 p--;
3789 break;
3790 case '>':
3791 if (skipBracket) // we don't care about brackets
3792 {
3793 p--;
3794 }
3795 else // count open/close brackets
3796 {
3797 if (p>0 && result.at(p-1)=='>') // skip >> operator
3798 {
3799 p-=2;
3800 break;
3801 }
3802 count=1;
3803 //printf("pos < = %d\n",p);
3804 p--;
3805 bool foundMatch=false;
3806 while (p>=0 && !foundMatch)
3807 {
3808 c=result.at(p--);
3809 switch (c)
3810 {
3811 case ')':
3812 round++;
3813 break;
3814 case '(':
3815 round--;
3816 break;
3817 case '>': // ignore > inside (...) to support e.g. (sizeof(T)>0) inside template parameters
3818 if (round==0) count++;
3819 break;
3820 case '<':
3821 if (round==0)
3822 {
3823 if (p>0)
3824 {
3825 if (result.at(p-1) == '<') // skip << operator
3826 {
3827 p--;
3828 break;
3829 }
3830 }
3831 count--;
3832 foundMatch = count==0;
3833 }
3834 break;
3835 default:
3836 //printf("c=%c count=%d\n",c,count);
3837 break;
3838 }
3839 }
3840 }
3841 //printf("pos > = %d\n",p+1);
3842 break;
3843 default:
3844 p--;
3845 }
3846 }
3847 done = count==0 || skipBracket; // reparse if brackets do not match
3848 skipBracket=TRUE;
3849 }
3850 while (!done); // if < > unbalanced repeat ignoring them
3851 //printf("stripScope(%s)=%s\n",name,name);
3852 return name;
3853}

References QCString::at(), FALSE, QCString::length(), QCString::right(), and TRUE.

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

◆ stripTemplateSpecifiersFromScope()

QCString stripTemplateSpecifiersFromScope ( const QCString & fullName,
bool parentOnly,
QCString * pLastScopeStripped,
QCString 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 4511 of file util.cpp.

4516{
4517 //printf("stripTemplateSpecifiersFromScope(name=%s,scopeName=%s)\n",qPrint(fullName),qPrint(scopeName));
4518 int i=fullName.find('<');
4519 if (i==-1) return fullName;
4520 QCString result;
4521 int p=0;
4522 int l=static_cast<int>(fullName.length());
4523 while (i!=-1)
4524 {
4525 //printf("1:result+=%s\n",qPrint(fullName.mid(p,i-p)));
4526 int e=i+1;
4527 int count=1;
4528 int round=0;
4529 while (e<l && count>0)
4530 {
4531 char c=fullName.at(e++);
4532 switch (c)
4533 {
4534 case '(': round++; break;
4535 case ')': if (round>0) round--; break;
4536 case '<': if (round==0) count++; break;
4537 case '>': if (round==0) count--; break;
4538 default:
4539 break;
4540 }
4541 }
4542 int si= fullName.find("::",e);
4543
4544 if (parentOnly && si==-1) break;
4545 // we only do the parent scope, so we stop here if needed
4546
4547 result+=fullName.mid(p,i-p);
4548 //printf(" trying %s\n",qPrint(mergeScopes(scopeName,result+fullName.mid(i,e-i))));
4549 ClassDef *cd = getClass(mergeScopes(scopeName,result+fullName.mid(i,e-i)));
4550 if (cd!=nullptr && (allowArtificial || !cd->isArtificial()))
4551 {
4552 result+=fullName.mid(i,e-i);
4553 //printf(" 2:result+=%s\n",qPrint(fullName.mid(i,e-i-1)));
4554 }
4555 else if (pLastScopeStripped)
4556 {
4557 //printf(" last stripped scope '%s'\n",qPrint(fullName.mid(i,e-i)));
4558 *pLastScopeStripped=fullName.mid(i,e-i);
4559 }
4560 p=e;
4561 i=fullName.find('<',p);
4562 }
4563 result+=fullName.right(l-p);
4564 //printf("3:result+=%s\n",qPrint(fullName.right(l-p)));
4565 //printf("end result=%s\n",qPrint(result));
4566 return result;
4567}
virtual bool isArtificial() const =0
QCString mergeScopes(const QCString &leftScope, const QCString &rightScope)
Definition util.cpp:4578

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

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

◆ substituteClassNames()

QCString substituteClassNames ( const QCString & s)

◆ substituteKeywords() [1/2]

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

Definition at line 3038 of file util.cpp.

3039{
3040 std::string substRes;
3041 int line = 1;
3042 const char *p = s.data();
3043 if (p)
3044 {
3045 // reserve some room for expansion
3046 substRes.reserve(s.length()+1024);
3047 char c = 0;
3048 while ((c=*p))
3049 {
3050 bool found = false;
3051 if (c=='$')
3052 {
3053 for (const auto &kw : keywords)
3054 {
3055 size_t keyLen = qstrlen(kw.keyword);
3056 if (qstrncmp(p,kw.keyword,keyLen)==0)
3057 {
3058 const char *startArg = p+keyLen;
3059 bool expectParam = std::holds_alternative<KeywordSubstitution::GetValueWithParam>(kw.getValueVariant);
3060 //printf("%s: expectParam=%d *startArg=%c\n",kw.keyword,expectParam,*startArg);
3061 if (expectParam && *startArg=='(') // $key(value)
3062 {
3063 size_t j=1;
3064 const char *endArg = nullptr;
3065 while ((c=*(startArg+j)) && c!=')' && c!='\n' && c!=0) j++;
3066 if (c==')') endArg=startArg+j;
3067 if (endArg)
3068 {
3069 QCString value = QCString(startArg+1).left(endArg-startArg-1);
3070 auto &&getValue = std::get<KeywordSubstitution::GetValueWithParam>(kw.getValueVariant);
3071 substRes+=getValue(value).str();
3072 p=endArg+1;
3073 //printf("found '%s'->'%s'\n",kw.keyword,qPrint(getValue(value)));
3074 }
3075 else
3076 {
3077 //printf("missing argument\n");
3078 warn(file,line,"Missing argument for '{}'",kw.keyword);
3079 p+=keyLen;
3080 }
3081 }
3082 else if (!expectParam) // $key
3083 {
3084 auto &&getValue = std::get<KeywordSubstitution::GetValue>(kw.getValueVariant);
3085 substRes+=getValue().str();
3086 //printf("found '%s'->'%s'\n",kw.keyword,qPrint(getValue()));
3087 p+=keyLen;
3088 }
3089 else
3090 {
3091 //printf("%s %d Expected arguments, none specified '%s'\n",qPrint(file), line, qPrint(kw.keyword));
3092 warn(file,line,"Expected arguments for '{}' but none were specified",kw.keyword);
3093 p+=keyLen;
3094 }
3095 found = true;
3096 break;
3097 }
3098 }
3099 }
3100 if (!found) // copy
3101 {
3102 if (c=='\n') line++;
3103 substRes+=c;
3104 p++;
3105 }
3106 }
3107 }
3108 return substRes;
3109}

References QCString::data(), QCString::left(), QCString::length(), qstrlen(), qstrncmp(), and warn.

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

◆ substituteKeywords() [2/2]

QCString substituteKeywords ( const QCString & file,
const QCString & s,
const QCString & title,
const QCString & projName,
const QCString & projNum,
const QCString & projBrief )

Definition at line 3190 of file util.cpp.

3192{
3193 return substituteKeywords(file,s,
3194 {
3195 // keyword value getter
3196 { "$title", [&]() { return !title.isEmpty() ? title : projName; } },
3197 { "$doxygenversion", [&]() { return getDoxygenVersion(); } },
3198 { "$projectname", [&]() { return projName; } },
3199 { "$projectnumber", [&]() { return projNum; } },
3200 { "$projectbrief", [&]() { return projBrief; } },
3201 { "$projectlogo", [&]() { return stripPath(projectLogoFile()); } },
3202 { "$logosize", [&]() { return projectLogoSize(); } },
3203 { "$projecticon", [&]() { return stripPath(Config_getString(PROJECT_ICON)); } },
3204 { "$langISO", [&]() { return theTranslator->trISOLang(); } },
3205 { "$showdate", [&](const QCString &fmt) { return showDate(fmt); } }
3206 });
3207}
Definition message.h:144
QCString substituteKeywords(const QCString &file, const QCString &s, const KeywordSubstitutionList &keywords)
Definition util.cpp:3038
QCString projectLogoFile()
Definition util.cpp:3124
static QCString projectLogoSize()
Definition util.cpp:3145
static QCString showDate(const QCString &fmt)
Definition util.cpp:3111

References Config_getString, QCString::isEmpty(), projectLogoFile(), projectLogoSize(), showDate(), stripPath(), substituteKeywords(), and theTranslator.

◆ substituteTemplateArgumentsInString()

QCString substituteTemplateArgumentsInString ( const QCString & nm,
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 4349 of file util.cpp.

4353{
4354 AUTO_TRACE("name={} formalArgs={} actualArgs={}",nm,argListToString(formalArgs),actualArgs ? argListToString(*actualArgs) : QCString());
4355 if (formalArgs.empty()) return nm;
4356 QCString result;
4357
4358 static const reg::Ex re(R"(\a\w*)");
4359 std::string name = nm.str();
4360 reg::Iterator it(name,re);
4362 size_t p=0;
4363
4364 for (; it!=end ; ++it)
4365 {
4366 const auto &match = *it;
4367 size_t i = match.position();
4368 size_t l = match.length();
4369 if (i>p) result += name.substr(p,i-p);
4370 QCString n(match.str());
4372 if (actualArgs)
4373 {
4374 actIt = actualArgs->begin();
4375 }
4376 //printf(": name=%s\n",qPrint(name));
4377
4378 // if n is a template argument, then we substitute it
4379 // for its template instance argument.
4380 bool found=FALSE;
4381 for (auto formIt = formalArgs.begin();
4382 formIt!=formalArgs.end() && !found;
4383 ++formIt
4384 )
4385 {
4386 Argument formArg = *formIt;
4387 Argument actArg;
4388 if (actualArgs && actIt!=actualArgs->end())
4389 {
4390 actArg = *actIt;
4391 }
4392 if (formArg.type.startsWith("class ") && formArg.name.isEmpty())
4393 {
4394 formArg.name = formArg.type.mid(6);
4395 formArg.type = "class";
4396 }
4397 else if (formArg.type.startsWith("typename ") && formArg.name.isEmpty())
4398 {
4399 formArg.name = formArg.type.mid(9);
4400 formArg.type = "typename";
4401 }
4402 else if (formArg.type.startsWith("class...")) // match 'class... name' to 'name...'
4403 {
4404 formArg.name += "...";
4405 formArg.type = formArg.type.left(5)+formArg.type.mid(8);
4406 }
4407 else if (formArg.type.startsWith("typename...")) // match 'typename... name' to 'name...'
4408 {
4409 formArg.name += "...";
4410 formArg.type = formArg.type.left(8)+formArg.type.mid(11);
4411 }
4412 //printf(": n=%s formArg->type='%s' formArg->name='%s' formArg->defval='%s' actArg->type='%s' actArg->name='%s' \n",
4413 // qPrint(n),qPrint(formArg.type),qPrint(formArg.name),qPrint(formArg.defval),qPrint(actArg.type),qPrint(actArg.name));
4414 if (formArg.type=="class" || formArg.type=="typename" || formArg.type.startsWith("template"))
4415 {
4416 if (formArg.name==n && actualArgs && actIt!=actualArgs->end() && !actArg.type.isEmpty()) // base class is a template argument
4417 {
4418 static constexpr auto hasRecursion = [](const QCString &prefix,const QCString &nameArg,const QCString &subst) -> bool
4419 {
4420 int ii=0;
4421 int pp=0;
4422
4423 ii = subst.find('<');
4424 //printf("prefix='%s' subst='%s'\n",qPrint(prefix.mid(prefix.length()-ii-2,ii+1)),qPrint(subst.left(ii+1)));
4425 if (ii!=-1 && static_cast<int>(prefix.length())>=ii+2 && prefix.mid(prefix.length()-ii-2,ii+1)==subst.left(ii+1))
4426 {
4427 return true; // don't replace 'A< ' with 'A< A<...', see issue #10951
4428 }
4429
4430 while ((ii=subst.find(nameArg,pp))!=-1)
4431 {
4432 bool beforeNonWord = ii==0 || !isId(subst.at(ii-1));
4433 bool afterNonWord = subst.length()==ii+nameArg.length() || !isId(subst.at(ii+nameArg.length()));
4434 if (beforeNonWord && afterNonWord)
4435 {
4436 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
4437 }
4438 pp=ii+static_cast<int>(nameArg.length());
4439 }
4440 return false;
4441 };
4442 // replace formal argument with the actual argument of the instance
4443 AUTO_TRACE_ADD("result={} n={} type={} hasRecursion={}",result,n,actArg.type,hasRecursion(result,n,actArg.type));
4444 if (!hasRecursion(result,n,actArg.type))
4445 // the scope guard is to prevent recursive lockup for
4446 // template<class A> class C : public<A::T>,
4447 // where A::T would become A::T::T here,
4448 // since n==A and actArg->type==A::T
4449 // see bug595833 for an example
4450 //
4451 // Also prevent recursive substitution if n is part of actArg.type, i.e.
4452 // n='A' in argType='S< A >' would produce 'S< S< A > >'
4453 {
4454 if (actArg.name.isEmpty())
4455 {
4456 result += actArg.type;
4457 }
4458 else
4459 // for case where the actual arg is something like "unsigned int"
4460 // the "int" part is in actArg->name.
4461 {
4462 result += actArg.type+" "+actArg.name;
4463 }
4464 found=TRUE;
4465 }
4466 }
4467 else if (formArg.name==n &&
4468 (actualArgs==nullptr || actIt==actualArgs->end()) &&
4469 !formArg.defval.isEmpty() &&
4470 formArg.defval!=nm /* to prevent recursion */
4471 )
4472 {
4473 result += substituteTemplateArgumentsInString(formArg.defval,formalArgs,actualArgs);
4474 found=TRUE;
4475 }
4476 }
4477 else if (formArg.name==n &&
4478 (actualArgs==nullptr || actIt==actualArgs->end()) &&
4479 !formArg.defval.isEmpty() &&
4480 formArg.defval!=nm /* to prevent recursion */
4481 )
4482 {
4483 result += substituteTemplateArgumentsInString(formArg.defval,formalArgs,actualArgs);
4484 found=TRUE;
4485 }
4486 if (actualArgs && actIt!=actualArgs->end())
4487 {
4488 actIt++;
4489 }
4490 }
4491 if (!found)
4492 {
4493 result += n;
4494 }
4495 p=i+l;
4496 }
4497 result+=name.substr(p);
4498 result=result.simplifyWhiteSpace();
4499 AUTO_TRACE_EXIT("result={}",result);
4500 return result.stripWhiteSpace();
4501}
typename Vec::const_iterator const_iterator
Definition arguments.h:69
QCString substituteTemplateArgumentsInString(const QCString &nm, const ArgumentList &formalArgs, const ArgumentList *actualArgs)
Definition util.cpp:4349

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

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

◆ tempArgListToString()

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

Definition at line 1279 of file util.cpp.

1280{
1281 QCString result;
1282 if (al.empty()) return result;
1283 result="<";
1284 bool first=true;
1285 for (const auto &a : al)
1286 {
1287 if (a.defval.isEmpty() || includeDefault)
1288 {
1289 if (!first) result+=", ";
1290 if (!a.name.isEmpty()) // add template argument name
1291 {
1292 if (lang==SrcLangExt::Java || lang==SrcLangExt::CSharp)
1293 {
1294 result+=a.type+" ";
1295 }
1296 result+=a.name;
1297 }
1298 else // extract name from type
1299 {
1300 int i = static_cast<int>(a.type.length())-1;
1301 while (i>=0 && isId(a.type.at(i))) i--;
1302 if (i>0)
1303 {
1304 result+=a.type.right(a.type.length()-i-1);
1305 if (a.type.find("...")!=-1)
1306 {
1307 result+="...";
1308 }
1309 }
1310 else // nothing found -> take whole name
1311 {
1312 result+=a.type;
1313 }
1314 }
1315 if (!a.typeConstraint.isEmpty() && lang==SrcLangExt::Java)
1316 {
1317 result+=" extends "; // TODO: now Java specific, C# has where...
1318 result+=a.typeConstraint;
1319 }
1320 first=false;
1321 }
1322 }
1323 result+=">";
1324 return removeRedundantWhiteSpace(result);
1325}

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

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

◆ transcodeCharacterStringToUTF8()

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

Definition at line 1436 of file util.cpp.

1437{
1438 const char *outputEncoding = "UTF-8";
1439 if (inputEncoding==nullptr || qstricmp(inputEncoding,outputEncoding)==0) return true;
1440 size_t inputSize=input.length();
1441 size_t outputSize=inputSize*4;
1442 QCString output(outputSize, QCString::ExplicitSize);
1443 void *cd = portable_iconv_open(outputEncoding,inputEncoding);
1444 if (cd==reinterpret_cast<void *>(-1))
1445 {
1446 return false;
1447 }
1448 bool ok=true;
1449 size_t iLeft=inputSize;
1450 size_t oLeft=outputSize;
1451 const char *inputPtr = input.data();
1452 char *outputPtr = output.rawData();
1453 if (!portable_iconv(cd, &inputPtr, &iLeft, &outputPtr, &oLeft))
1454 {
1455 outputSize-=static_cast<int>(oLeft);
1456 output.resize(outputSize);
1457 output.at(outputSize)='\0';
1458 // replace input
1459 input=output.str();
1460 //printf("iconv: input size=%d output size=%d\n[%s]\n",size,newSize,qPrint(srcBuf));
1461 }
1462 else
1463 {
1464 ok=false;
1465 }
1467 return ok;
1468}
@ ExplicitSize
Definition qcstring.h:146
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)
int qstricmp(const char *s1, const char *s2)
Definition qcstring.cpp:530

References QCString::at(), QCString::ExplicitSize, portable_iconv(), portable_iconv_close(), portable_iconv_open(), qstricmp(), QCString::rawData(), QCString::resize(), and QCString::str().

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

◆ unescapeCharsInString()

QCString unescapeCharsInString ( const QCString & s)

Definition at line 3400 of file util.cpp.

3401{
3402 if (s.isEmpty()) return s;
3403 bool caseSenseNames = getCaseSenseNames();
3404 QCString result;
3405 result.reserve(s.length());
3406 const char *p = s.data();
3407 if (p)
3408 {
3409 char c = 0;
3410 while ((c=*p++))
3411 {
3412 if (c=='_') // 2 or 3 character escape
3413 {
3414 switch (*p)
3415 {
3416 case '_': result+=c; p++; break; // __ -> '_'
3417 case '1': result+=':'; p++; break; // _1 -> ':'
3418 case '2': result+='/'; p++; break; // _2 -> '/'
3419 case '3': result+='<'; p++; break; // _3 -> '<'
3420 case '4': result+='>'; p++; break; // _4 -> '>'
3421 case '5': result+='*'; p++; break; // _5 -> '*'
3422 case '6': result+='&'; p++; break; // _6 -> '&'
3423 case '7': result+='|'; p++; break; // _7 -> '|'
3424 case '8': result+='.'; p++; break; // _8 -> '.'
3425 case '9': result+='!'; p++; break; // _9 -> '!'
3426 case '0': // 3 character escape
3427 switch (*(p+1))
3428 {
3429 case '0': result+=','; p+=2; break; // _00 -> ','
3430 case '1': result+=' '; p+=2; break; // _01 -> ' '
3431 case '2': result+='{'; p+=2; break; // _02 -> '{'
3432 case '3': result+='}'; p+=2; break; // _03 -> '}'
3433 case '4': result+='?'; p+=2; break; // _04 -> '?'
3434 case '5': result+='^'; p+=2; break; // _05 -> '^'
3435 case '6': result+='%'; p+=2; break; // _06 -> '%'
3436 case '7': result+='('; p+=2; break; // _07 -> '('
3437 case '8': result+=')'; p+=2; break; // _08 -> ')'
3438 case '9': result+='+'; p+=2; break; // _09 -> '+'
3439 case 'a': result+='='; p+=2; break; // _0a -> '='
3440 case 'b': result+='$'; p+=2; break; // _0b -> '$'
3441 case 'c': result+='\\'; p+=2; break;// _0c -> '\'
3442 case 'd': result+='@'; p+=2; break; // _0d -> '@'
3443 case 'e': result+=']'; p+=2; break; // _0e -> ']'
3444 case 'f': result+='['; p+=2; break; // _0f -> '['
3445 case 'g': result+='#'; p+=2; break; // _0g -> '#'
3446 case 'h': result+='"'; p+=2; break; // _0h -> '"'
3447 case 'i': result+='~'; p+=2; break; // _0i -> '~'
3448 case 'j': result+='\''; p+=2; break;// _0j -> '\'
3449 case 'k': result+=';'; p+=2; break; // _0k -> ';'
3450 case 'l': result+='`'; p+=2; break; // _0l -> '`'
3451 default: // unknown escape, just pass underscore character as-is
3452 result+=c;
3453 break;
3454 }
3455 break;
3456 default:
3457 if (!caseSenseNames && c>='a' && c<='z') // lower to upper case escape, _a -> 'A'
3458 {
3459 result+=static_cast<char>(toupper(*p));
3460 p++;
3461 }
3462 else // unknown escape, pass underscore character as-is
3463 {
3464 result+=c;
3465 }
3466 break;
3467 }
3468 }
3469 else // normal character; pass as is
3470 {
3471 result+=c;
3472 }
3473 }
3474 }
3475 return result;
3476}

References QCString::data(), getCaseSenseNames(), QCString::isEmpty(), QCString::length(), and QCString::reserve().

◆ updateColumnCount()

size_t updateColumnCount ( const char * s,
size_t col )

Definition at line 6883 of file util.cpp.

6884{
6885 if (s)
6886 {
6887 const int tabSize = Config_getInt(TAB_SIZE);
6888 char c;
6889 while ((c=*s++))
6890 {
6891 switch(c)
6892 {
6893 case '\t': col+=tabSize - (col%tabSize);
6894 break;
6895 case '\n': col=0;
6896 break;
6897 default:
6898 col++;
6899 if (c<0) // multi-byte character
6900 {
6901 int numBytes = getUTF8CharNumBytes(c);
6902 for (int i=0;i<numBytes-1 && (c=*s++);i++) {} // skip over extra chars
6903 if (c==0) return col; // end of string half way a multibyte char
6904 }
6905 break;
6906 }
6907 }
6908 }
6909 return col;
6910}

References Config_getInt, and getUTF8CharNumBytes().

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

◆ updateLanguageMapping()

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

Definition at line 5089 of file util.cpp.

5090{
5091 QCString langName = language.lower();
5092 auto it1 = std::find_if(g_lang2extMap.begin(),g_lang2extMap.end(),
5093 [&langName](const auto &info) { return info.langName==langName; });
5094 if (it1 == g_lang2extMap.end()) return false;
5095
5096 // found the language
5097 SrcLangExt parserId = it1->parserId;
5098 QCString extName = extension.lower();
5099 if (extName.isEmpty()) return FALSE;
5100 if (extName.at(0)!='.') extName.prepend(".");
5101 auto it2 = g_extLookup.find(extName.str());
5102 if (it2!=g_extLookup.end())
5103 {
5104 g_extLookup.erase(it2); // language was already register for this ext
5105 }
5106 //printf("registering extension %s\n",qPrint(extName));
5107 g_extLookup.emplace(extName.str(),parserId);
5108 if (!Doxygen::parserManager->registerExtension(extName,it1->parserName))
5109 {
5110 err("Failed to assign extension {} to parser {} for language {}\n",
5111 extName.data(),it1->parserName,language);
5112 }
5113 else
5114 {
5115 //msg("Registered extension {} to language parser {}...\n",
5116 // extName,language);
5117 }
5118 return TRUE;
5119}
SrcLangExt
Definition types.h:207

References QCString::at(), QCString::data(), err, FALSE, g_extLookup, g_lang2extMap, QCString::isEmpty(), QCString::lower(), Doxygen::parserManager, QCString::prepend(), QCString::str(), and TRUE.

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

◆ writeColoredImgData()

void writeColoredImgData ( const QCString & dir,
ColoredImgDataItem data[] )

Writes the intensity only bitmap represented by data as an image to directory dir using the colors defined by HTML_COLORSTYLE_*.

Definition at line 5785 of file util.cpp.

5786{
5787 int hue = Config_getInt(HTML_COLORSTYLE_HUE);
5788 int sat = Config_getInt(HTML_COLORSTYLE_SAT);
5789 int gamma = Config_getInt(HTML_COLORSTYLE_GAMMA);
5790 while (data->name)
5791 {
5792 QCString fileName = dir+"/"+data->name;
5793 ColoredImage img(data->width,data->height,data->content,data->alpha,
5794 sat,hue,gamma);
5795 if (!img.save(fileName))
5796 {
5797 fprintf(stderr,"Warning: Cannot open file %s for writing\n",data->name);
5798 }
5799 Doxygen::indexList->addImageFile(data->name);
5800 data++;
5801 }
5802}
Class representing a bitmap image colored based on hue/sat/gamma settings.
Definition image.h:56
static IndexList * indexList
Definition doxygen.h:133
const unsigned char * content
Definition util.h:422
unsigned short height
Definition util.h:421
const unsigned char * alpha
Definition util.h:423
unsigned short width
Definition util.h:420
const char * name
Definition util.h:419

References ColoredImgDataItem::alpha, Config_getInt, ColoredImgDataItem::content, ColoredImgDataItem::height, Doxygen::indexList, ColoredImgDataItem::name, ColoredImage::save(), and ColoredImgDataItem::width.

◆ writeExamples()

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

Definition at line 1160 of file util.cpp.

1161{
1162 auto replaceFunc = [&list,&ol](size_t entryIndex)
1163 {
1164 const auto &e = list[entryIndex];
1165 ol.pushGeneratorState();
1169 // link for Html / man
1170 //printf("writeObjectLink(file=%s)\n",qPrint(e->file));
1171 ol.writeObjectLink(QCString(),e.file,e.anchor,e.name);
1172 ol.popGeneratorState();
1173
1174 ol.pushGeneratorState();
1177 // link for Latex / pdf with anchor because the sources
1178 // are not hyperlinked (not possible with a verbatim environment).
1179 ol.writeObjectLink(QCString(),e.file,QCString(),e.name);
1180 ol.popGeneratorState();
1181 };
1182
1183 writeMarkerList(ol, theTranslator->trWriteList(static_cast<int>(list.size())).str(), list.size(), replaceFunc);
1184
1185 ol.writeString(".");
1186}
void writeString(const QCString &text)
Definition outputlist.h:411
void disable(OutputType o)
void pushGeneratorState()
void popGeneratorState()
void writeMarkerList(OutputList &ol, const std::string &markerText, size_t numMarkers, std::function< void(size_t)> replaceFunc)
Definition util.cpp:1109

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

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

◆ writeFileContents()

QCString writeFileContents ( const QCString & baseName,
const QCString & extension,
const QCString & content,
bool & exists )

Thread-safe function to write a string 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 6962 of file util.cpp.

6963{
6964 uint8_t md5_sig[16];
6965 char sigStr[33];
6966 MD5Buffer(content.data(),static_cast<unsigned int>(content.length()),md5_sig);
6967 MD5SigToString(md5_sig,sigStr);
6968
6969 QCString fileName = baseName + sigStr + extension;
6970 { // ==== start atomic section
6971 std::lock_guard lock(writeFileContents_lock);
6972 auto it=writeFileContents_set.find(fileName.str());
6973 exists = it!=writeFileContents_set.end();
6974 if (!exists)
6975 {
6976 writeFileContents_set.insert(fileName.str());
6977 if (auto file = Portable::openOutputStream(fileName); file.is_open())
6978 {
6979 file.write( content.data(), content.length() );
6980 file.close();
6981 }
6982 else
6983 {
6984 err("Could not open file {} for writing\n",fileName);
6985 return QCString();
6986 }
6987 }
6988 } // ==== end atomic section
6989 return fileName;
6990}
static std::mutex writeFileContents_lock
Definition util.cpp:6951

References QCString::data(), err, QCString::length(), Portable::openOutputStream(), QCString::str(), writeFileContents_lock, and writeFileContents_set.

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

◆ writeMarkerList() [1/2]

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

Definition at line 1132 of file util.cpp.

1134{
1135 QCString result;
1136 static const reg::Ex marker(R"(@(\d+))");
1137 reg::Iterator it(markerText,marker);
1139 size_t index=0;
1140 for ( ; it!=end ; ++it)
1141 {
1142 const auto &match = *it;
1143 size_t newIndex = match.position();
1144 size_t matchLen = match.length();
1145 result += markerText.substr(index,newIndex-index);
1146 unsigned long entryIndex = std::stoul(match[1].str());
1147 if (entryIndex<static_cast<unsigned long>(numMarkers))
1148 {
1149 result+=replaceFunc(entryIndex);
1150 }
1151 index=newIndex+matchLen;
1152 }
1153 if (index<markerText.size())
1154 {
1155 result += markerText.substr(index);
1156 }
1157 return result;
1158}

References end().

◆ writeMarkerList() [2/2]

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

Definition at line 1109 of file util.cpp.

1111{
1112 static const reg::Ex marker(R"(@(\d+))");
1113 reg::Iterator it(markerText,marker);
1115 size_t index=0;
1116 for ( ; it!=end ; ++it)
1117 {
1118 const auto &match = *it;
1119 size_t newIndex = match.position();
1120 size_t matchLen = match.length();
1121 ol.parseText(markerText.substr(index,newIndex-index));
1122 unsigned long entryIndex = std::stoul(match[1].str());
1123 if (entryIndex<static_cast<unsigned long>(numMarkers))
1124 {
1125 replaceFunc(entryIndex);
1126 }
1127 index=newIndex+matchLen;
1128 }
1129 ol.parseText(markerText.substr(index));
1130}
void parseText(const QCString &textStr)

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

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

◆ writePageRef()

void writePageRef ( OutputList & ol,
const QCString & cn,
const QCString & mn )

◆ writeTypeConstraints()

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

Definition at line 5442 of file util.cpp.

5443{
5444 if (al.empty()) return;
5445 ol.startConstraintList(theTranslator->trTypeConstraints());
5446 for (const Argument &a : al)
5447 {
5449 ol.parseText(a.name);
5450 ol.endConstraintParam();
5452 linkifyText(TextGeneratorOLImpl(ol),d,nullptr,nullptr,a.type);
5453 ol.endConstraintType();
5455 ol.generateDoc(d->docFile(),
5456 d->docLine(),
5457 d,
5458 nullptr,
5459 a.docs,
5460 DocOptions()
5461 .setIndexWords(true));
5462 ol.endConstraintDocs();
5463 }
5464 ol.endConstraintList();
5465}
virtual int docLine() const =0
void endConstraintType()
Definition outputlist.h:714
void endConstraintList()
Definition outputlist.h:720
void startConstraintParam()
Definition outputlist.h:708
void generateDoc(const QCString &fileName, int startLine, const Definition *ctx, const MemberDef *md, const QCString &docStr, const DocOptions &options)
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 startConstraintList(const QCString &header)
Definition outputlist.h:706
Implements TextGeneratorIntf for an OutputDocInterface stream.
Definition util.h:76
void linkifyText(const TextGeneratorIntf &out, const Definition *scope, const FileDef *fileScope, const Definition *self, const QCString &text, bool autoBreak, bool external, bool keepSpaces, int indentLevel, size_t breakThreshold)
Definition util.cpp:894

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(), and theTranslator.

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