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  LinkifyTextOptions
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 QCString &text, const LinkifyTextOptions &options)
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 296 of file util.h.

◆ SelectionBlockList

using SelectionBlockList = std::vector<SelectionBlock>

Definition at line 230 of file util.h.

Function Documentation

◆ addCodeOnlyMappings()

void addCodeOnlyMappings ( )

Definition at line 5203 of file util.cpp.

5204{
5205 updateLanguageMapping(".xml", "xml");
5206 updateLanguageMapping(".sql", "sql");
5207}
bool updateLanguageMapping(const QCString &extension, const QCString &language)
Definition util.cpp:5104

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

4921{
4922 if (fName.isEmpty()) return;
4923 int i_fs = fName.findRev('/');
4924 int i_bs = fName.findRev('\\');
4925 int i = fName.find('.',std::max({ i_fs, i_bs ,0})); // search for . after path part
4926 if (i==-1)
4927 {
4929 }
4930}
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(), 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 4096 of file util.cpp.

4099{
4100 ASSERT(context!=nullptr);
4101 //printf("addMemberToMemberGroup() context=%s\n",qPrint(context->name()));
4102 if (ml==nullptr) return;
4103
4104 struct MoveMemberInfo
4105 {
4106 MoveMemberInfo(MemberDef *md,MemberGroup *mg,const RefItemVector &rv)
4107 : memberDef(md), memberGroup(mg), sli(rv) {}
4108 MemberDef *memberDef;
4109 MemberGroup *memberGroup;
4110 RefItemVector sli;
4111 };
4112 std::vector<MoveMemberInfo> movedMembers;
4113
4114 for (const auto &md : *ml)
4115 {
4116 if (md->isEnumerate()) // insert enum value of this enum into groups
4117 {
4118 for (const auto &fmd : md->enumFieldList())
4119 {
4120 int groupId=fmd->getMemberGroupId();
4121 if (groupId!=-1)
4122 {
4123 auto it = Doxygen::memberGroupInfoMap.find(groupId);
4125 {
4126 const auto &info = it->second;
4127 auto mg_it = std::find_if(pMemberGroups->begin(),
4128 pMemberGroups->end(),
4129 [&groupId](const auto &g)
4130 { return g->groupId()==groupId; }
4131 );
4132 MemberGroup *mg_ptr = nullptr;
4133 if (mg_it==pMemberGroups->end())
4134 {
4135 auto mg = std::make_unique<MemberGroup>(
4136 context,
4137 groupId,
4138 info->header,
4139 info->doc,
4140 info->docFile,
4141 info->docLine,
4142 ml->container());
4143 mg_ptr = mg.get();
4144 pMemberGroups->push_back(std::move(mg));
4145 }
4146 else
4147 {
4148 mg_ptr = (*mg_it).get();
4149 }
4150 mg_ptr->insertMember(fmd); // insert in member group
4152 if (fmdm)
4153 {
4154 fmdm->setMemberGroup(mg_ptr);
4155 }
4156 }
4157 }
4158 }
4159 }
4160 int groupId=md->getMemberGroupId();
4161 if (groupId!=-1)
4162 {
4163 auto it = Doxygen::memberGroupInfoMap.find(groupId);
4165 {
4166 const auto &info = it->second;
4167 auto mg_it = std::find_if(pMemberGroups->begin(),
4168 pMemberGroups->end(),
4169 [&groupId](const auto &g)
4170 { return g->groupId()==groupId; }
4171 );
4172 MemberGroup *mg_ptr = nullptr;
4173 if (mg_it==pMemberGroups->end())
4174 {
4175 auto mg = std::make_unique<MemberGroup>(
4176 context,
4177 groupId,
4178 info->header,
4179 info->doc,
4180 info->docFile,
4181 info->docLine,
4182 ml->container());
4183 mg_ptr = mg.get();
4184 pMemberGroups->push_back(std::move(mg));
4185 }
4186 else
4187 {
4188 mg_ptr = (*mg_it).get();
4189 }
4190 movedMembers.emplace_back(md,mg_ptr,info->m_sli);
4191 }
4192 }
4193 }
4194
4195 // move the members to their group
4196 for (const auto &mmi : movedMembers)
4197 {
4198 ml->remove(mmi.memberDef); // remove from member list
4199 mmi.memberGroup->insertMember(mmi.memberDef->resolveAlias()); // insert in member group
4200 mmi.memberGroup->setRefItems(mmi.sli);
4201 MemberDefMutable *rmdm = toMemberDefMutable(mmi.memberDef);
4202 if (rmdm)
4203 {
4204 rmdm->setMemberGroup(mmi.memberGroup);
4205 }
4206 }
4207}
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 4823 of file util.cpp.

4826{
4827 //printf("addRefItem(sli=%d,key=%s,prefix=%s,name=%s,title=%s,args=%s)\n",(int)sli.size(),key,prefix,name,title,args);
4828 if (!key.isEmpty() && key[0]!='@') // check for @ to skip anonymous stuff (see bug427012)
4829 {
4830 for (RefItem *item : sli)
4831 {
4832 item->setPrefix(prefix);
4833 item->setScope(scope);
4834 item->setName(name);
4835 item->setTitle(title);
4836 item->setArgs(args);
4837 item->setGroup(key);
4838 }
4839 }
4840}
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 4693 of file util.cpp.

4704{
4705 PageDef *pd=nullptr;
4706 //printf("addRelatedPage(name=%s gd=%p)\n",qPrint(name),gd);
4707 QCString title=ptitle.stripWhiteSpace();
4708 bool newPage = true;
4709 if ((pd=Doxygen::pageLinkedMap->find(name)) && !pd->isReference())
4710 {
4711 if (!xref && !title.isEmpty() && pd->title()!=pd->name() && pd->title()!=title)
4712 {
4713 warn(fileName,startLine,"multiple use of page label '{}' with different titles, (other occurrence: {}, line: {})",
4714 name,pd->docFile(),pd->getStartBodyLine());
4715 }
4716 if (!title.isEmpty() && pd->title()==pd->name()) // pd has no real title yet
4717 {
4718 pd->setTitle(title);
4720 if (si)
4721 {
4722 si->setTitle(title);
4723 }
4724 }
4725 // append documentation block to the page.
4726 pd->setDocumentation(doc,fileName,docLine);
4727 //printf("Adding page docs '%s' pi=%p name=%s\n",qPrint(doc),pd,name);
4728 // append (x)refitems to the page.
4729 pd->setRefItems(sli);
4730 newPage = false;
4731 }
4732
4733 if (newPage) // new page
4734 {
4735 QCString baseName=name;
4736 if (baseName.endsWith(".tex"))
4737 baseName=baseName.left(baseName.length()-4);
4738 else if (baseName.right(Doxygen::htmlFileExtension.length())==Doxygen::htmlFileExtension)
4739 baseName=baseName.left(baseName.length()-Doxygen::htmlFileExtension.length());
4740
4741 //printf("Appending page '%s'\n",qPrint(baseName));
4742 if (pd) // replace existing page
4743 {
4744 pd->setDocumentation(doc,fileName,docLine);
4746 pd->setShowLineNo(FALSE);
4747 pd->setNestingLevel(0);
4748 pd->setPageScope(nullptr);
4749 pd->setTitle(title);
4750 pd->setReference(QCString());
4751 }
4752 else // newPage
4753 {
4754 pd = Doxygen::pageLinkedMap->add(baseName,
4755 createPageDef(fileName,docLine,baseName,doc,title));
4756 }
4757 pd->setBodySegment(startLine,startLine,-1);
4758
4759 pd->setRefItems(sli);
4760 pd->setLanguage(lang);
4761
4762 if (tagInfo)
4763 {
4764 pd->setReference(tagInfo->tagName);
4765 pd->setFileName(tagInfo->fileName);
4766 }
4767
4768 if (gd) gd->addPage(pd);
4769
4770 if (pd->hasTitle())
4771 {
4772 //outputList->writeTitle(pi->name,pi->title);
4773
4774 // a page name is a label as well!
4775 QCString file;
4776 QCString orgFile;
4777 int line = -1;
4778 if (gd)
4779 {
4780 file=gd->getOutputFileBase();
4781 orgFile=gd->getOutputFileBase();
4782 }
4783 else
4784 {
4785 file=pd->getOutputFileBase();
4786 orgFile=pd->docFile();
4787 line = pd->getStartBodyLine();
4788 }
4789 const SectionInfo *si = SectionManager::instance().find(pd->name());
4790 if (si)
4791 {
4792 if (!si->ref().isEmpty()) // we are from a tag file
4793 {
4795 file,-1,pd->title(),SectionType::Page,0,pd->getReference());
4796 }
4797 else if (si->lineNr() != -1)
4798 {
4799 warn(orgFile,line,"multiple use of section label '{}', (first occurrence: {}, line {})",pd->name(),si->fileName(),si->lineNr());
4800 }
4801 else
4802 {
4803 warn(orgFile,line,"multiple use of section label '{}', (first occurrence: {})",pd->name(),si->fileName());
4804 }
4805 }
4806 else
4807 {
4809 file,-1,pd->title(),SectionType::Page,0,pd->getReference());
4810 //printf("si->label='%s' si->definition=%s si->fileName='%s'\n",
4811 // qPrint(si->label),si->definition?si->definition->name().data():"<none>",
4812 // qPrint(si->fileName));
4813 //printf(" SectionInfo: sec=%p sec->fileName=%s\n",si,qPrint(si->fileName));
4814 //printf("Adding section key=%s si->fileName=%s\n",qPrint(pageName),qPrint(si->fileName));
4815 }
4816 }
4817 }
4818 return pd;
4819}
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:3503

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

1250{
1251 QCString result;
1252 if (!al.hasParameters()) return result;
1253 result+="(";
1254 for (auto it = al.begin() ; it!=al.end() ;)
1255 {
1256 Argument a = *it;
1257 QCString type1 = useCanonicalType && !a.canType.isEmpty() ? a.canType : a.type;
1258 QCString type2;
1259 int i=type1.find(")("); // hack to deal with function pointers
1260 if (i!=-1)
1261 {
1262 type2=type1.mid(i);
1263 type1=type1.left(i);
1264 }
1265 if (!a.attrib.isEmpty())
1266 {
1267 result+=a.attrib+" ";
1268 }
1269 if (!a.name.isEmpty() || !a.array.isEmpty())
1270 {
1271 result+= type1+" "+a.name+type2+a.array;
1272 }
1273 else
1274 {
1275 result+= type1+type2;
1276 }
1277 if (!a.defval.isEmpty() && showDefVals)
1278 {
1279 result+="="+a.defval;
1280 }
1281 ++it;
1282 if (it!=al.end()) result+=", ";
1283 }
1284 result+=")";
1285 if (al.constSpecifier()) result+=" const";
1286 if (al.volatileSpecifier()) result+=" volatile";
1287 if (al.refQualifier()==RefQualifierType::LValue) result+=" &";
1288 else if (al.refQualifier()==RefQualifierType::RValue) result+=" &&";
1289 if (!al.trailingReturnType().isEmpty()) result+=al.trailingReturnType();
1290 if (al.pureSpecifier()) result+=" =0";
1291 return removeRedundantWhiteSpace(result);
1292}
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:567

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

6541{
6542 if (s.isEmpty()) return;
6543
6544 const char *p = s.data();
6545 char c = 0;
6546 while ((c=*p))
6547 {
6548 if (c==markerInfo.markerChar) // potential start of marker
6549 {
6550 if (qstrncmp(p,markerInfo.beginStr,markerInfo.beginLen)==0) // start of begin marker
6551 {
6552 size_t len = markerInfo.beginLen;
6553 bool negate = *(p+len)=='!';
6554 if (negate) len++;
6555 p += len;
6556 QCString marker;
6557 while (*p)
6558 {
6559 if (markerInfo.closeLen==0 && *p=='\n') // matching end of line
6560 {
6561 warn(fileName,-1,"Remaining begin replacement with marker '{}'",marker);
6562 break;
6563 }
6564 else if (markerInfo.closeLen!= 0 && qstrncmp(p,markerInfo.closeStr,markerInfo.closeLen)==0) // matching marker closing
6565 {
6566 p += markerInfo.closeLen;
6567 warn(fileName,-1,"Remaining begin replacement with marker '{}'",marker);
6568 break;
6569 }
6570 marker += *p;
6571 p++;
6572 }
6573 }
6574 else if (qstrncmp(p,markerInfo.endStr,markerInfo.endLen)==0) // start of end marker
6575 {
6576 size_t len = markerInfo.endLen;
6577 bool negate = *(p+len)=='!';
6578 if (negate) len++;
6579 p += len;
6580 QCString marker;
6581 while (*p)
6582 {
6583 if (markerInfo.closeLen==0 && *p=='\n') // matching end of line
6584 {
6585 warn(fileName,-1,"Remaining end replacement with marker '{}'",marker);
6586 break;
6587 }
6588 else if (markerInfo.closeLen!= 0 && qstrncmp(p,markerInfo.closeStr,markerInfo.closeLen)==0) // matching marker closing
6589 {
6590 p += markerInfo.closeLen;
6591 warn(fileName,-1,"Remaining end replacement with marker '{}'",marker);
6592 break;
6593 }
6594 marker += *p;
6595 p++;
6596 }
6597 }
6598 }
6599 p++;
6600 }
6601}
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:236
const char * closeStr
Definition util.h:239
const char * beginStr
Definition util.h:235
size_t closeLen
Definition util.h:240
const char * endStr
Definition util.h:237

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

4916{
4917 return fName.right(ext.length())==ext;
4918}

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

5314{
5315 MemberDef *bestMatch = getMemberFromSymbol(scope,fileScope,n);
5316
5317 if (bestMatch && bestMatch->isTypedef())
5318 return TRUE; // closest matching symbol is a typedef
5319 else
5320 return FALSE;
5321}
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:5261

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

Referenced by isVarWithConstructor().

◆ cleanupInlineGraph()

void cleanupInlineGraph ( )

Definition at line 7008 of file util.cpp.

7009{
7010 if (Config_getBool(DOT_CLEANUP))
7011 {
7012 for (const auto& fileName: writeFileContents_set)
7013 {
7014 Dir().remove(qPrint(fileName));
7015 }
7016 }
7017}
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:6967

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

Referenced by generateOutput().

◆ clearSubDirs()

void clearSubDirs ( const Dir & d)

Definition at line 3666 of file util.cpp.

3667{
3668 if (Config_getBool(CREATE_SUBDIRS))
3669 {
3670 // remove empty subdirectories
3671 int createSubdirsLevelPow2 = 1 << Config_getInt(CREATE_SUBDIRS_LEVEL);
3672 for (int l1=0;l1<16;l1++)
3673 {
3674 QCString subdir;
3675 subdir.sprintf("d%x",l1);
3676 for (int l2=0; l2 < createSubdirsLevelPow2; l2++)
3677 {
3678 QCString subsubdir;
3679 subsubdir.sprintf("d%x/d%02x",l1,l2);
3680 if (d.exists(subsubdir.str()) && d.isEmpty(subsubdir.str()))
3681 {
3682 d.rmdir(subsubdir.str());
3683 }
3684 }
3685 if (d.exists(subdir.str()) && d.isEmpty(subdir.str()))
3686 {
3687 d.rmdir(subdir.str());
3688 }
3689 }
3690 }
3691}
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 6842 of file util.cpp.

6843{
6844 int l = static_cast<int>(name.length());
6845 int lastSepPos = -1;
6846 const char *p = name.data();
6847 int i=l-2;
6848 int sharpCount=0;
6849 // --- begin optimized version of ts=name.findRev(">::");
6850 int ts = -1;
6851 while (i>=0)
6852 {
6853 if (p[i]=='>')
6854 {
6855 if (sharpCount==0 && p[i+1]==':' && p[i+2]==':')
6856 {
6857 ts=i;
6858 break;
6859 }
6860 sharpCount++;
6861 }
6862 else if (p[i]=='<')
6863 {
6864 sharpCount--;
6865 }
6866 i--;
6867 }
6868 // --- end optimized version
6869 if (ts==-1) ts=0; else p+=++ts;
6870 for (i=ts;i<l-1;i++)
6871 {
6872 char c=*p++;
6873 if (c==':' && *p==':') lastSepPos=i;
6874 if (c=='<') break;
6875 }
6876 return lastSepPos;
6877}

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

4970{
4971 if (str.isEmpty() || word==nullptr) return false;
4972 static const reg::Ex re(R"(\a+)");
4973 std::string s = str.str();
4974 for (reg::Iterator it(s,re) ; it!=reg::Iterator() ; ++it)
4975 {
4976 if (it->str()==word) return true;
4977 }
4978 return false;
4979}
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 4046 of file util.cpp.

4047{
4048 if (str.isEmpty()) return QCString();
4049
4050 std::string s = str.data();
4051 static const reg::Ex re(R"(&\a\w*;)");
4052 reg::Iterator it(s,re);
4054
4055 QCString result;
4056 result.reserve(str.length()+32);
4057 size_t p=0, i=0, l=0;
4058 for (; it!=end ; ++it)
4059 {
4060 const auto &match = *it;
4061 p = match.position();
4062 l = match.length();
4063 if (p>i)
4064 {
4065 result+=s.substr(i,p-i);
4066 }
4067 QCString entity(match.str());
4069 const char *code=nullptr;
4070 if (symType!=HtmlEntityMapper::Sym_Unknown && (code=HtmlEntityMapper::instance().utf8(symType)))
4071 {
4072 result+=code;
4073 }
4074 else
4075 {
4076 result+=entity;
4077 }
4078 i=p+l;
4079 }
4080 result+=s.substr(i);
4081 //printf("convertCharEntitiesToUTF8(%s)->%s\n",qPrint(s),qPrint(result));
4082 return result;
4083}
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(), generateXMLForRequirements(), getSQLDocBlock(), and parseCommentAsText().

◆ convertFileNameFortranParserCode()

FortranFormat convertFileNameFortranParserCode ( QCString fn)

Definition at line 6414 of file util.cpp.

6415{
6417 QCString parserName = Doxygen::parserManager->getParserName(ext);
6418
6419 if (parserName == "fortranfixed") return FortranFormat::Fixed;
6420 else if (parserName == "fortranfree") return FortranFormat::Free;
6421
6423}
static ParserManager * parserManager
Definition doxygen.h:128
QCString getFileNameExtension(const QCString &fn)
Definition util.cpp:5251

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

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

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

6253{
6254 bool extractPrivate = Config_getBool(EXTRACT_PRIVATE);
6255
6256 // default representing 1-1 mapping
6257 *outListType1=inListType;
6258 *outListType2=MemberListType::Invalid();
6259
6260 if (inProt==Protection::Public)
6261 {
6262 if (inListType.isPrivate())
6263 {
6264 *outListType1=MemberListType::Invalid();
6265 }
6266 }
6267 else if (inProt==Protection::Protected)
6268 {
6269 if (inListType.isPrivate() || inListType.isPublic())
6270 {
6271 *outListType1=MemberListType::Invalid();
6272 }
6273 else if (inListType.isProtected())
6274 {
6275 *outListType2=inListType.toPublic();
6276 }
6277 }
6278 else if (inProt==Protection::Private)
6279 {
6280 if (inListType.isPublic() || inListType.isProtected())
6281 {
6282 *outListType1=MemberListType::Invalid();
6283 }
6284 else if (inListType.isPrivate())
6285 {
6286 if (extractPrivate)
6287 {
6288 *outListType1=inListType.toPublic();
6289 *outListType2=inListType.toProtected();
6290 }
6291 else
6292 {
6293 *outListType1=MemberListType::Invalid();
6294 }
6295 }
6296 }
6297
6298 //printf("convertProtectionLevel(type=%s prot=%d): %s,%s\n",
6299 // qPrint(inListType.to_string()),inProt,qPrint(outListType1->to_string()),qPrint(outListType2->to_string()));
6300}
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 3962 of file util.cpp.

3963{
3964 if (s.isEmpty()) return s;
3965 QCString result;
3966 result.reserve(s.length()+32);
3967 const char *p=s.data();
3968 char c = 0;
3969 while ((c=*p++))
3970 {
3971 switch (c)
3972 {
3973 case '<': result+="&lt;"; break;
3974 case '>': result+="&gt;"; break;
3975 case '&': if (keepEntities)
3976 {
3977 const char *e=p;
3978 char ce = 0;
3979 while ((ce=*e++))
3980 {
3981 if (ce==';' || (!(isId(ce) || ce=='#'))) break;
3982 }
3983 if (ce==';') // found end of an entity
3984 {
3985 // copy entry verbatim
3986 result+=c;
3987 while (p<e) result+=*p++;
3988 }
3989 else
3990 {
3991 result+="&amp;";
3992 }
3993 }
3994 else
3995 {
3996 result+="&amp;";
3997 }
3998 break;
3999 case '\'': result+="&#39;"; break;
4000 case '"': result+="&quot;"; break;
4001 default:
4002 {
4003 uint8_t uc = static_cast<uint8_t>(c);
4004 if (uc<32 && !isspace(c))
4005 {
4006 result+="&#x24";
4007 result+=hex[uc>>4];
4008 result+=hex[uc&0xF];
4009 result+=';';
4010 }
4011 else
4012 {
4013 result+=c;
4014 }
4015 }
4016 break;
4017 }
4018 }
4019 return result;
4020}
static constexpr auto hex
bool isId(int c)
Definition util.h:256

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

3872{
3873 if (s.isEmpty()) return s;
3874 QCString result;
3875 result.reserve(s.length()+8);
3876 const char *p = s.data();
3877 char c = 0;
3878 bool first = true;
3879 while ((c=*p++))
3880 {
3881 char encChar[4];
3882 if ((c>='0' && c<='9') || (c>='a' && c<='z') || (c>='A' && c<='Z') || c=='-')
3883 { // any permissive character except _
3884 if (first && c>='0' && c<='9') result+='a'; // don't start with a digit
3885 result+=c;
3886 }
3887 else
3888 {
3889 encChar[0]='_';
3890 encChar[1]=hex[static_cast<unsigned char>(c)>>4];
3891 encChar[2]=hex[static_cast<unsigned char>(c)&0xF];
3892 encChar[3]=0;
3893 result+=encChar;
3894 }
3895 first=false;
3896 }
3897 return result;
3898}

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

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

4023{
4024 if (s.isEmpty()) return s;
4025 QCString result;
4026 result.reserve(s.length()+32);
4027 const char *p=s.data();
4028 char c = 0;
4029 while ((c=*p++))
4030 {
4031 switch (c)
4032 {
4033 case '"': if (!singleQuotes) result+="\\\""; else result+=c;
4034 break;
4035 case '\'': if (singleQuotes) result+="\\\'"; else result+=c;
4036 break;
4037 case '\\': if (*p=='u' && *(p+1)=='{') result+="\\"; // keep \u{..} unicode escapes
4038 else result+="\\\\";
4039 break;
4040 default: result+=c; break;
4041 }
4042 }
4043 return keepEntities ? result : convertCharEntitiesToUTF8(result);
4044}
QCString convertCharEntitiesToUTF8(const QCString &str)
Definition util.cpp:4046

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

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

◆ convertToXML()

QCString convertToXML ( const QCString & s,
bool keepEntities )

Converts a string to an XML-encoded string

Definition at line 3911 of file util.cpp.

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

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(), generateXMLForRequirements(), generateXMLSection(), DotDirDeps::getImgAltText(), EclipseHelp::initialize(), Qhp::initialize(), XmlDocVisitor::operator()(), XmlDocVisitor::operator()(), HtmlAttribList::toString(), QhpSectionTree::traverse(), visitPreStart(), SearchIndexExternal::write(), FileDefImpl::writeClassesToTagFile(), NamespaceDefImpl::writeClassesToTagFile(), NamespaceDefImpl::writeConceptsToTagFile(), DefinitionImpl::writeDocAnchorsToTagFile(), DotNode::writeDocbook(), DotGraph::writeGraphHeader(), writeInnerClasses(), writeInnerConcepts(), writeInnerDirs(), writeInnerFiles(), writeInnerGroups(), writeInnerModules(), writeInnerNamespaces(), writeInnerPages(), writeJavascriptSearchData(), writeJavasScriptSearchDataPage(), DotNode::writeLabel(), writeListOfAllMembers(), writeMapArea(), writeMemberReference(), writeRequirementRefs(), ClassDefImpl::writeTagFile(), ConceptDefImpl::writeTagFile(), DirDefImpl::writeTagFile(), FileDefImpl::writeTagFile(), GroupDefImpl::writeTagFile(), MemberDefImpl::writeTagFile(), ModuleDefImpl::writeTagFile(), NamespaceDefImpl::writeTagFile(), PageDefImpl::writeTagFile(), RequirementManager::writeTagFile(), VhdlDocGen::writeTagFile(), writeTemplateArgumentList(), DocSets::writeToken(), DotNode::writeXML(), writeXMLLink(), and writeXMLString().

◆ copyFile()

bool copyFile ( const 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 5875 of file util.cpp.

5876{
5877 if (!Dir().copy(src.str(),dest.str()))
5878 {
5879 err("could not copy file {} to {}\n",src,dest);
5880 return false;
5881 }
5882 return true;
5883}
#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 3904 of file util.cpp.

3905{
3906 if (s.isEmpty()) return s;
3907 return "a" + s;
3908}

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

5944{
5945 QCString result = url;
5946 if (!relPath.isEmpty() && !isURL(url))
5947 {
5948 result.prepend(relPath);
5949 }
5950 return result;
5951}
bool isURL(const QCString &url)
Checks whether the given url starts with a supported protocol.
Definition util.cpp:5931

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

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

◆ createHtmlUrl()

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

Definition at line 5734 of file util.cpp.

5740{
5741 QCString url;
5742 if (!ref.isEmpty())
5743 {
5744 url = externalRef(relPath,ref,href);
5745 }
5746 if (!targetFileName.isEmpty())
5747 {
5748 QCString fn = targetFileName;
5749 if (ref.isEmpty())
5750 {
5751 if (!anchor.isEmpty() && isLocalFile)
5752 {
5753 fn=""; // omit file name for local links
5754 }
5755 else
5756 {
5757 url = relPath;
5758 }
5759 }
5760 url+=fn;
5761 }
5762 if (!anchor.isEmpty())
5763 {
5764 if (!url.endsWith("=")) url+="#";
5765 url+=anchor;
5766 }
5767 //printf("createHtmlUrl(relPath=%s,local=%d,target=%s,anchor=%s)=%s\n",qPrint(relPath),isLocalFile,qPrint(targetFileName),qPrint(anchor),qPrint(url));
5768 return url;
5769}
QCString externalRef(const QCString &relPath, const QCString &ref, bool href)
Definition util.cpp:5771

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

3640{
3641 if (Config_getBool(CREATE_SUBDIRS))
3642 {
3643 // create up to 4096 subdirectories
3644 int createSubdirsLevelPow2 = 1 << Config_getInt(CREATE_SUBDIRS_LEVEL);
3645 for (int l1=0; l1<16; l1++)
3646 {
3647 QCString subdir;
3648 subdir.sprintf("d%x",l1);
3649 if (!d.exists(subdir.str()) && !d.mkdir(subdir.str()))
3650 {
3651 term("Failed to create output directory '{}'\n",subdir);
3652 }
3653 for (int l2=0; l2<createSubdirsLevelPow2; l2++)
3654 {
3655 QCString subsubdir;
3656 subsubdir.sprintf("d%x/d%02x",l1,l2);
3657 if (!d.exists(subsubdir.str()) && !d.mkdir(subsubdir.str()))
3658 {
3659 term("Failed to create output directory '{}'\n",subsubdir);
3660 }
3661 }
3662 }
3663 }
3664}
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 6941 of file util.cpp.

6942{
6943 QCString result=name;
6944 if (result.endsWith("-g"))
6945 {
6946 int idx = result.find('-');
6947 result = result.left(idx)+templArgs;
6948 }
6949 return result;
6950}

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

Referenced by ClassDefImpl::className().

◆ detab()

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

Definition at line 6738 of file util.cpp.

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

3600{
3601 bool searchIncludes = Config_getBool(SEARCH_INCLUDES);
3602 QCString absIncFileName = incFileName;
3603 FileInfo fi(curFile.str());
3604 if (fi.exists())
3605 {
3606 QCString absName = fi.dirPath(TRUE)+"/"+incFileName;
3607 FileInfo fi2(absName.str());
3608 if (fi2.exists())
3609 {
3610 absIncFileName=fi2.absFilePath();
3611 }
3612 else if (searchIncludes) // search in INCLUDE_PATH as well
3613 {
3614 const StringVector &includePath = Config_getList(INCLUDE_PATH);
3615 for (const auto &incPath : includePath)
3616 {
3617 FileInfo fi3(incPath);
3618 if (fi3.exists() && fi3.isDir())
3619 {
3620 absName = fi3.absFilePath()+"/"+incFileName;
3621 //printf("trying absName=%s\n",qPrint(absName));
3622 FileInfo fi4(absName.str());
3623 if (fi4.exists())
3624 {
3625 absIncFileName=fi4.absFilePath();
3626 break;
3627 }
3628 //printf( "absIncFileName = %s\n", qPrint(absIncFileName) );
3629 }
3630 }
3631 }
3632 //printf( "absIncFileName = %s\n", qPrint(absIncFileName) );
3633 }
3634 return absIncFileName;
3635}
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 3328 of file util.cpp.

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

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

5724{
5725 bool extLinksInWindow = Config_getBool(EXT_LINKS_IN_WINDOW);
5726 if (extLinksInWindow)
5727 return "target=\"_blank\" ";
5728 else if (parent)
5729 return "target=\"_parent\" ";
5730 else
5731 return "";
5732}
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 5771 of file util.cpp.

5772{
5773 QCString result;
5774 if (!ref.isEmpty())
5775 {
5776 auto it = Doxygen::tagDestinationMap.find(ref.str());
5778 {
5779 result = it->second;
5780 size_t l = result.length();
5781 if (!relPath.isEmpty() && l>0 && result.at(0)=='.')
5782 { // relative path -> prepend relPath.
5783 result.prepend(relPath);
5784 l+=relPath.length();
5785 }
5786 if (l>0 && result.at(l-1)!='/') result+='/';
5787 if (!href) result.append("\" ");
5788 }
5789 }
5790 else
5791 {
5792 result = relPath;
5793 }
5794 return result;
5795}
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 6952 of file util.cpp.

6953{
6954 QCString text=rawStart;
6955 int i = text.find('"');
6956 assert(i!=-1);
6957 return text.mid(i+1,text.length()-i-2); // text=...R"xyz( -> delimiter=xyz
6958}

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

4215{
4216 AUTO_TRACE("type='{}' name='{}' lang={}",type,name,lang);
4217 static const reg::Ex re_norm(R"(\a[\w:]*)");
4218 static const reg::Ex re_fortran(R"(\a[\w:()=]*)");
4219 const reg::Ex *re = &re_norm;
4220
4221 name.clear();
4222 templSpec.clear();
4223 if (type.isEmpty())
4224 {
4225 AUTO_TRACE_EXIT("empty type");
4226 return -1;
4227 }
4228 size_t typeLen=type.length();
4229 if (typeLen>0)
4230 {
4231 if (lang == SrcLangExt::Fortran)
4232 {
4233 if (type[pos]==',')
4234 {
4235 AUTO_TRACE_EXIT("comma");
4236 return -1;
4237 }
4238 if (!type.lower().startsWith("type"))
4239 {
4240 re = &re_fortran;
4241 }
4242 }
4243 std::string s = type.str();
4244 reg::Iterator it(s,*re,static_cast<int>(pos));
4246
4247 if (it!=end)
4248 {
4249 const auto &match = *it;
4250 size_t i = match.position();
4251 size_t l = match.length();
4252 size_t ts = i+l;
4253 size_t te = ts;
4254 size_t tl = 0;
4255
4256 while (ts<typeLen && type[static_cast<uint32_t>(ts)]==' ') { ts++; tl++; } // skip any whitespace
4257 if (ts<typeLen && type[static_cast<uint32_t>(ts)]=='<') // assume template instance
4258 {
4259 // locate end of template
4260 te=ts+1;
4261 int brCount=1;
4262 while (te<typeLen && brCount!=0)
4263 {
4264 if (type[static_cast<uint32_t>(te)]=='<')
4265 {
4266 if (te<typeLen-1 && type[static_cast<uint32_t>(te)+1]=='<') te++; else brCount++;
4267 }
4268 if (type[static_cast<uint32_t>(te)]=='>')
4269 {
4270 if (te<typeLen-1 && type[static_cast<uint32_t>(te)+1]=='>') te++; else brCount--;
4271 }
4272 te++;
4273 }
4274 }
4275 name = match.str();
4276 if (te>ts)
4277 {
4278 templSpec = QCString(type).mid(ts,te-ts);
4279 tl+=te-ts;
4280 pos=static_cast<int>(i+l+tl);
4281 }
4282 else // no template part
4283 {
4284 pos=static_cast<int>(i+l);
4285 }
4286 //printf("extractClassNameFromType([in] type=%s,[out] pos=%d,[out] name=%s,[out] templ=%s)=TRUE i=%d\n",
4287 // qPrint(type),pos,qPrint(name),qPrint(templSpec),i);
4288 AUTO_TRACE_EXIT("pos={} templSpec='{}' return={}",pos,templSpec,i);
4289 return static_cast<int>(i);
4290 }
4291 }
4292 pos = static_cast<int>(typeLen);
4293 //printf("extractClassNameFromType([in] type=%s,[out] pos=%d,[out] name=%s,[out] templ=%s)=FALSE\n",
4294 // qPrint(type),pos,qPrint(name),qPrint(templSpec));
4295 AUTO_TRACE_EXIT("not found");
4296 return -1;
4297}
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 6196 of file util.cpp.

6197{
6198 std::string s = docs.str();
6199 static const reg::Ex re(R"(\‍[([ inout,]+)\‍])");
6200 reg::Iterator it(s,re);
6202 if (it!=end)
6203 {
6204 const auto &match = *it;
6205 size_t p = match.position();
6206 size_t l = match.length();
6207 if (p==0 && l>2)
6208 {
6209 // make dir the part inside [...] without separators
6210 std::string dir = match[1].str();
6211 // strip , and ' ' from dir
6212 dir.erase(std::remove_if(dir.begin(),dir.end(),
6213 [](const char c) { return c==' ' || c==','; }
6214 ),dir.end());
6215 unsigned char ioMask=0;
6216 size_t inIndex = dir.find( "in");
6217 if ( inIndex!=std::string::npos) { dir.erase( inIndex,2); ioMask|=(1<<0); }
6218 size_t outIndex = dir.find("out");
6219 if (outIndex!=std::string::npos) { dir.erase(outIndex,3); ioMask|=(1<<1); }
6220 if (dir.empty() && ioMask!=0) // only in and/or out attributes found
6221 {
6222 docs = s.substr(l); // strip attributes
6223 if (ioMask==((1<<0)|(1<<1))) return "[in,out]";
6224 else if (ioMask==(1<<0)) return "[in]";
6225 else if (ioMask==(1<<1)) return "[out]";
6226 }
6227 }
6228 }
6229 return "";
6230}

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

Referenced by inlineArgListToDoc().

◆ extractEndRawStringDelimiter()

QCString extractEndRawStringDelimiter ( const char * rawEnd)

Definition at line 6960 of file util.cpp.

6961{
6962 QCString text=rawEnd;
6963 return text.mid(1,text.length()-2); // text=)xyz" -> delimiter=xyz
6964}

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

3699{
3700 int i=0, p=0;
3701 QCString clName=scopeName;
3702 NamespaceDef *nd = nullptr;
3703 if (!clName.isEmpty() && (nd=getResolvedNamespace(clName)) && getClass(clName)==nullptr)
3704 { // the whole name is a namespace (and not a class)
3705 namespaceName=nd->name();
3706 className.clear();
3707 goto done;
3708 }
3709 p=static_cast<int>(clName.length())-2;
3710 while (p>=0 && (i=clName.findRev("::",p))!=-1)
3711 // see if the first part is a namespace (and not a class)
3712 {
3713 //printf("Trying %s\n",qPrint(clName.left(i)));
3714 if (i>0 && (nd=getResolvedNamespace(clName.left(i))) && getClass(clName.left(i))==nullptr)
3715 {
3716 //printf("found!\n");
3717 namespaceName=nd->name();
3718 className=clName.right(clName.length()-i-2);
3719 goto done;
3720 }
3721 p=i-2; // try a smaller piece of the scope
3722 }
3723 //printf("not found!\n");
3724
3725 // not found, so we just have to guess.
3726 className=scopeName;
3727 namespaceName.clear();
3728
3729done:
3730 if (className.isEmpty() && !namespaceName.isEmpty() && !allowEmptyClass)
3731 {
3732 // class and namespace with the same name, correct to return the class.
3733 className=namespaceName;
3734 namespaceName.clear();
3735 }
3736 //printf("extractNamespace '%s' => '%s|%s'\n",qPrint(scopeName),
3737 // qPrint(className),qPrint(namespaceName));
3738 if (className.endsWith("-p"))
3739 {
3740 className = className.left(className.length()-2);
3741 }
3742 return;
3743}
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 1489 of file util.cpp.

1490{
1491 if (name.isEmpty()) return QCString();
1492 bool fileOpened=false;
1493 if (name[0]=='-' && name[1]==0) // read from stdin
1494 {
1495 std::string contents;
1496 std::string line;
1497 while (getline(std::cin,line))
1498 {
1499 contents+=line+'\n';
1500 }
1501 return contents;
1502 }
1503 else // read from file
1504 {
1505 FileInfo fi(name.str());
1506 if (!fi.exists() || !fi.isFile())
1507 {
1508 err("file '{}' not found\n",name);
1509 return "";
1510 }
1511 std::string buf;
1512 fileOpened=readInputFile(name,buf,filter,isSourceCode);
1513 if (fileOpened)
1514 {
1515 addTerminalCharIfMissing(buf,'\n');
1516 return buf;
1517 }
1518 }
1519 if (!fileOpened)
1520 {
1521 err("cannot open file '{}' for reading\n",name);
1522 }
1523 return "";
1524}
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:5548

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

6108{
6109 bool allExternals = Config_getBool(ALLEXTERNALS);
6110 bool isDocFile = fd->isDocumentationFile();
6111 genSourceFile = !isDocFile && fd->generateSourceFile();
6112 return ( ((allExternals && fd->isLinkable()) ||
6114 ) &&
6115 !isDocFile
6116 );
6117}
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 5628 of file util.cpp.

5629{
5630 std::string tf;
5631 std::string t = title.str();
5632 static const reg::Ex re(R"(%[a-z_A-Z]+)");
5633 reg::Iterator it(t,re);
5635 size_t p = 0;
5636 for (; it!=end ; ++it)
5637 {
5638 const auto &match = *it;
5639 size_t i = match.position();
5640 size_t l = match.length();
5641 if (i>p) tf+=t.substr(p,i-p);
5642 tf+=match.str().substr(1); // skip %
5643 p=i+l;
5644 }
5645 tf+=t.substr(p);
5646 return tf;
5647}

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

Referenced by addToIndices(), createJavaScriptSearchIndex(), PerlModGenerator::generatePerlModForPage(), generateSqlite3ForPage(), generateXMLForPage(), generateXMLForRequirement(), generateXMLForRequirements(), parseCommentAsHtml(), SearchIndexExternal::setCurrentDoc(), HtmlGenerator::startFile(), 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 4985 of file util.cpp.

4986{
4987 static reg::Ex re(R"(\s*(<\a+>)\s*)");
4988 std::string s = sentence.str();
4989 reg::Iterator it(s,re);
4991 std::string result;
4992 bool found=false;
4993 size_t p=0;
4994 for ( ; it!=end ; ++it)
4995 {
4996 const auto match = *it;
4997 std::string part = match[1].str();
4998 if (part!=word)
4999 {
5000 size_t i = match.position();
5001 size_t l = match.length();
5002 result+=s.substr(p,i-p);
5003 result+=match.str();
5004 p=i+l;
5005 }
5006 else
5007 {
5008 found=true;
5009 size_t i = match[1].position();
5010 size_t l = match[1].length();
5011 result+=s.substr(p,i-p);
5012 p=i+l;
5013 }
5014 }
5015 result+=s.substr(p);
5016 sentence = QCString(result).simplifyWhiteSpace();
5017 return found;
5018}
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 2889 of file util.cpp.

2890{
2891 ambig=FALSE;
2892 if (n.isEmpty()) return nullptr;
2893
2894
2895 const int maxAddrSize = 20;
2896 char addr[maxAddrSize];
2897 qsnprintf(addr,maxAddrSize,"%p:",reinterpret_cast<const void*>(fnMap));
2898 QCString key = addr;
2899 key+=n;
2900
2901 std::lock_guard<std::mutex> lock(g_findFileDefMutex);
2902 FindFileCacheElem *cachedResult = g_findFileDefCache.find(key.str());
2903 //printf("key=%s cachedResult=%p\n",qPrint(key),cachedResult);
2904 if (cachedResult)
2905 {
2906 ambig = cachedResult->isAmbig;
2907 //printf("cached: fileDef=%p\n",cachedResult->fileDef);
2908 return cachedResult->fileDef;
2909 }
2910 else
2911 {
2912 cachedResult = g_findFileDefCache.insert(key.str(),FindFileCacheElem(nullptr,FALSE));
2913 }
2914
2915 QCString name=Dir::cleanDirPath(n.str());
2916 QCString path;
2917 if (name.isEmpty()) return nullptr;
2918 int slashPos=std::max(name.findRev('/'),name.findRev('\\'));
2919 if (slashPos!=-1)
2920 {
2921 path=removeLongPathMarker(name.left(slashPos+1));
2922 name=name.right(name.length()-slashPos-1);
2923 }
2924 if (name.isEmpty()) return nullptr;
2925 const FileName *fn = fnMap->find(name);
2926 if (fn)
2927 {
2928 //printf("fn->size()=%zu\n",fn->size());
2929 if (fn->size()==1)
2930 {
2931 const std::unique_ptr<FileDef> &fd = fn->front();
2932 bool isSamePath = Portable::fileSystemIsCaseSensitive() ?
2933 fd->getPath().right(path.length())==path :
2934 fd->getPath().right(path.length()).lower()==path.lower();
2935 if (path.isEmpty() || isSamePath)
2936 {
2937 cachedResult->fileDef = fd.get();
2938 return fd.get();
2939 }
2940 }
2941 else // file name alone is ambiguous
2942 {
2943 int count=0;
2944 FileDef *lastMatch=nullptr;
2945 QCString pathStripped = stripFromIncludePath(path);
2946 for (const auto &fd_p : *fn)
2947 {
2948 FileDef *fd = fd_p.get();
2949 QCString fdStripPath = stripFromIncludePath(fd->getPath());
2950 if (path.isEmpty() ||
2951 (!pathStripped.isEmpty() && fdStripPath.endsWith(pathStripped)) ||
2952 (pathStripped.isEmpty() && fdStripPath.isEmpty()))
2953 {
2954 count++;
2955 lastMatch=fd;
2956 }
2957 }
2958
2959 ambig=(count>1);
2960 cachedResult->isAmbig = ambig;
2961 cachedResult->fileDef = lastMatch;
2962 return lastMatch;
2963 }
2964 }
2965 else
2966 {
2967 //printf("not found!\n");
2968 }
2969 return nullptr;
2970}
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:470
#define qsnprintf
Definition qcstring.h:49
Cache element for the file name to FileDef mapping cache.
Definition util.cpp:2879
FileDef * fileDef
Definition util.cpp:2881
QCString stripFromIncludePath(const QCString &path)
Definition util.cpp:329
static Cache< std::string, FindFileCacheElem > g_findFileDefCache(5000)
static std::mutex g_findFileDefMutex
Definition util.cpp:2887
QCString removeLongPathMarker(QCString path)
Definition util.cpp:287

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

2975{
2976 ambig=false;
2977 QCString result;
2978 bool found=false;
2979 if (!found)
2980 {
2981 FileInfo fi(file.str());
2982 if (fi.exists())
2983 {
2984 result=fi.absFilePath();
2985 found=true;
2986 }
2987 }
2988 if (!found)
2989 {
2990 const StringVector &examplePathList = Config_getList(EXAMPLE_PATH);
2991 for (const auto &s : examplePathList)
2992 {
2993 std::string absFileName = s+(Portable::pathSeparator()+file).str();
2994 FileInfo fi(absFileName);
2995 if (fi.exists())
2996 {
2997 result=fi.absFilePath();
2998 found=true;
2999 }
3000 }
3001 }
3002
3003 if (!found)
3004 {
3005 // as a fallback we also look in the exampleNameDict
3007 if (fd && !ambig)
3008 {
3009 result=fd->absFilePath();
3010 }
3011 }
3012 return result;
3013}
static FileNameLinkedMap * exampleNameLinkedMap
Definition doxygen.h:102
virtual QCString absFilePath() const =0
QCString pathSeparator()
Definition portable.cpp:374
FileDef * findFileDef(const FileNameLinkedMap *fnMap, const QCString &n, bool &ambig)
Definition util.cpp:2889

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

6681{
6683 return reg::search(s,match,re) ? static_cast<int>(match.position()) : -1;
6684}
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 6672 of file util.cpp.

6673{
6674 auto it = std::find(sv.begin(),sv.end(),s);
6675 return it!=sv.end() ? static_cast<int>(it-sv.begin()) : -1;
6676}

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

◆ fixSpaces()

QCString fixSpaces ( const QCString & s)
inline

Definition at line 522 of file util.h.

522{ 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(), and renderQuickLinksAsTree().

◆ generateAnonymousAnchor()

QCString generateAnonymousAnchor ( const QCString & fileName,
int count )

Definition at line 3557 of file util.cpp.

3558{
3559 QCString fn = stripFromPath(fileName)+":"+QCString().setNum(count);
3560 const int sig_size=16;
3561 uint8_t md5_sig[sig_size];
3562 MD5Buffer(fn.data(),static_cast<unsigned int>(fn.length()),md5_sig);
3563 char result[sig_size*3+2];
3564 char *p = result;
3565 *p++='@';
3566 for (int i=0;i<sig_size;i++)
3567 {
3568 static const char oct[]="01234567";
3569 uint8_t byte = md5_sig[i];
3570 *p++=oct[(byte>>6)&7];
3571 *p++=oct[(byte>>3)&7];
3572 *p++=oct[(byte>>0)&7];
3573 }
3574 *p='\0';
3575 return result;
3576}
QCString & setNum(short n)
Definition qcstring.h:459
static QCString stripFromPath(const QCString &p, const StringVector &l)
Definition util.cpp:298

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

◆ generateFileRef()

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

Definition at line 2861 of file util.cpp.

2862{
2863 //printf("generateFileRef(%s,%s)\n",name,text);
2864 QCString linkText = text.isEmpty() ? text : name;
2865 //FileInfo *fi;
2866 bool ambig = false;
2868 if (fd && fd->isLinkable())
2869 // link to documented input file
2870 ol.writeObjectLink(fd->getReference(),fd->getOutputFileBase(),QCString(),linkText);
2871 else
2872 ol.docify(linkText);
2873}
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 279 of file util.cpp.

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

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

3320{
3321 auto caseSenseNames = Config_getEnum(CASE_SENSE_NAMES);
3322
3323 if (caseSenseNames == CASE_SENSE_NAMES_t::YES) return true;
3324 else if (caseSenseNames == CASE_SENSE_NAMES_t::NO) return false;
3326}
#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 2293 of file util.cpp.

2294{
2295 GetDefResult result;
2296 if (input.memberName.isEmpty()) return result;
2297 AUTO_TRACE("scopeName={},memberName={},forceEmptyScope={}",
2298 input.scopeName,input.memberName,input.forceEmptyScope);
2299
2300 //printf("@@ --- getDefsNew(%s,%s)-----------\n",qPrint(scName),qPrint(mbName));
2301 const Definition *scope = Doxygen::globalScope;
2302 SymbolResolver resolver;
2303 if (input.currentFile) resolver.setFileScope(input.currentFile);
2304 if (!input.scopeName.isEmpty() && !input.forceEmptyScope)
2305 {
2306 scope = resolver.resolveSymbol(scope,input.scopeName);
2307 }
2308 if (scope==Doxygen::globalScope)
2309 {
2310 scope = input.currentFile;
2311 }
2312 //printf("@@ -> found scope scope=%s member=%s out=%s\n",qPrint(input.scopeName),qPrint(input.memberName),qPrint(scope?scope->name():""));
2313 //
2314 const Definition *symbol = resolver.resolveSymbol(scope,input.memberName,input.args,input.checkCV,input.insideCode,true);
2315 //printf("@@ -> found symbol in=%s out=%s\n",qPrint(input.memberName),qPrint(symbol?symbol->qualifiedName():QCString()));
2316 if (symbol && symbol->definitionType()==Definition::TypeMember)
2317 {
2318 result.md = toMemberDef(symbol);
2319 result.cd = result.md->getClassDef();
2320 if (result.cd==nullptr) result.nd = result.md->getNamespaceDef();
2321 if (result.cd==nullptr && result.nd==nullptr) result.fd = result.md->getFileDef();
2322 result.gd = result.md->getGroupDef();
2323 result.found = true;
2324 }
2325 else if (symbol && symbol->definitionType()==Definition::TypeClass)
2326 {
2327 result.cd = toClassDef(symbol);
2328 result.found = true;
2329 }
2330 else if (symbol && symbol->definitionType()==Definition::TypeNamespace)
2331 {
2332 result.nd = toNamespaceDef(symbol);
2333 result.found = true;
2334 }
2335 else if (symbol && symbol->definitionType()==Definition::TypeConcept)
2336 {
2337 result.cnd = toConceptDef(symbol);
2338 result.found = true;
2339 }
2340 else if (symbol && symbol->definitionType()==Definition::TypeModule)
2341 {
2342 result.modd = toModuleDef(symbol);
2343 result.found = true;
2344 }
2345 return result;
2346}
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:164
const FileDef * currentFile
Definition util.h:165
QCString scopeName
Definition util.h:161
bool insideCode
Definition util.h:167
bool checkCV
Definition util.h:166
QCString args
Definition util.h:163
QCString memberName
Definition util.h:162
const MemberDef * md
Definition util.h:173
const ConceptDef * cnd
Definition util.h:178
const FileDef * fd
Definition util.h:175
const ModuleDef * modd
Definition util.h:179
const GroupDef * gd
Definition util.h:177
bool found
Definition util.h:172
const ClassDef * cd
Definition util.h:174
const NamespaceDef * nd
Definition util.h:176

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

6308{
6309 QCString imgExt = Config_getEnumAsString(DOT_IMAGE_FORMAT);
6310 int i= imgExt.find(':'); // strip renderer part when using e.g. 'png:cairo:gd' as format
6311 return i==-1 ? imgExt : imgExt.left(i);
6312}
#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(), HtmlDocVisitor::writeMscFile(), and HtmlDocVisitor::writePlantUMLFile().

◆ getEncoding()

QCString getEncoding ( const FileInfo & fi)

Definition at line 5709 of file util.cpp.

5710{
5711 InputFileEncoding elem;
5712 auto getter = [](const InputFileEncoding &e) -> QCString { return e.pattern; };
5713 if (genericPatternMatch(fi,Doxygen::inputFileEncodingList,elem,getter)) // check for file specific encoding
5714 {
5715 return elem.encoding;
5716 }
5717 else // fall back to default encoding
5718 {
5719 return Config_getString(INPUT_ENCODING);
5720 }
5721}
static InputFileEncodingList inputFileEncodingList
Definition doxygen.h:137
#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:5652

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

1418{
1419 // sanity check
1420 if (name.isEmpty()) return "";
1421
1422 const StringVector& filterSrcList = Config_getList(FILTER_SOURCE_PATTERNS);
1423 const StringVector& filterList = Config_getList(FILTER_PATTERNS);
1424
1425 QCString filterName;
1426 bool found=FALSE;
1427 if (isSourceCode && !filterSrcList.empty())
1428 { // first look for source filter pattern list
1429 filterName = getFilterFromList(name,filterSrcList,found);
1430 }
1431 if (!found && filterName.isEmpty())
1432 { // then look for filter pattern list
1433 filterName = getFilterFromList(name,filterList,found);
1434 }
1435 if (!found)
1436 { // then use the generic input filter
1437 return Config_getString(INPUT_FILTER);
1438 }
1439 else
1440 {
1441 /* remove surrounding double quotes */
1442 if (filterName.length()>=2 && filterName[0]=='"' && filterName[static_cast<int>(filterName.length())-1]=='"')
1443 {
1444 filterName = filterName.mid(1,filterName.length()-2);
1445 }
1446 return filterName;
1447 }
1448}
static QCString getFilterFromList(const QCString &name, const StringVector &filterList, bool &found)
Definition util.cpp:1376

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

5228{
5229 // try the extension
5230 auto lang = getLanguageFromFileName(fileName, SrcLangExt::Unknown);
5231 if (lang == SrcLangExt::Unknown)
5232 {
5233 // try the language names
5234 QCString langName = fileName.lower();
5235 if (langName.at(0)=='.') langName = langName.mid(1);
5236 auto it = std::find_if(g_lang2extMap.begin(),g_lang2extMap.end(),
5237 [&langName](const auto &info) { return info.langName==langName; });
5238 if (it != g_lang2extMap.end())
5239 {
5240 lang = it->parserId;
5241 fileName = it->defExt;
5242 }
5243 else // default to C++
5244 {
5245 return SrcLangExt::Cpp;
5246 }
5247 }
5248 return lang;
5249}
SrcLangExt getLanguageFromFileName(const QCString &fileName, SrcLangExt defLang)
Definition util.cpp:5209
static std::vector< Lang2ExtMap > g_lang2extMap
Definition util.cpp:5080

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

5210{
5211 FileInfo fi(fileName.str());
5212 // we need only the part after the last ".", newer implementations of FileInfo have 'suffix()' for this.
5213 QCString extName = QCString(fi.extension(FALSE)).lower();
5214 if (extName.isEmpty()) extName=".no_extension";
5215 if (extName.at(0)!='.') extName.prepend(".");
5216 auto it = g_extLookup.find(extName.str());
5217 if (it!=g_extLookup.end()) // listed extension
5218 {
5219 //printf("getLanguageFromFileName(%s)=%x\n",qPrint(fi.extension()),*pVal);
5220 return it->second;
5221 }
5222 //printf("getLanguageFromFileName(%s) not found!\n",qPrint(fileName));
5223 return defLang; // not listed => assume C-ish language.
5224}
static std::unordered_map< std::string, SrcLangExt > g_extLookup
Definition util.cpp:5070

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

5916{
5917 if (lang==SrcLangExt::Java || lang==SrcLangExt::CSharp || lang==SrcLangExt::VHDL || lang==SrcLangExt::Python)
5918 {
5919 return ".";
5920 }
5921 else if (lang==SrcLangExt::PHP && !classScope)
5922 {
5923 return "\\";
5924 }
5925 else
5926 {
5927 return "::";
5928 }
5929}

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

◆ getOverloadDocs()

QCString getOverloadDocs ( )

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

Definition at line 4088 of file util.cpp.

4089{
4090 return theTranslator->trOverloadText();
4091 //"This is an overloaded member function, "
4092 // "provided for convenience. It differs from the above "
4093 // "function only in what argument(s) it accepts.";
4094}
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 3230 of file util.cpp.

3231{
3232 if (name.isEmpty()) return 0;
3233 const StringVector &sl = Config_getList(IGNORE_PREFIX);
3234 for (const auto &s : sl)
3235 {
3236 const char *ps=s.c_str();
3237 const char *pd=name.data();
3238 int i=0;
3239 while (*ps!=0 && *pd!=0 && *ps==*pd)
3240 {
3241 ps++;
3242 pd++;
3243 i++;
3244 }
3245 if (*ps==0 && *pd!=0)
3246 {
3247 return i;
3248 }
3249 }
3250 return 0;
3251}

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

6830{
6831 QCString projectCookie = Config_getString(HTML_PROJECT_COOKIE);
6832 if (projectCookie.isEmpty()) return QCString();
6833 uint8_t md5_sig[16];
6834 char sigStr[34];
6835 MD5Buffer(projectCookie.data(),static_cast<unsigned int>(projectCookie.length()),md5_sig);
6836 MD5SigToString(md5_sig,sigStr);
6837 sigStr[32]='_'; sigStr[33]=0;
6838 return sigStr;
6839}

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

4639{
4640 int sl=static_cast<int>(s.length());
4641 int sp=p;
4642 int count=0;
4643 bool done=false;
4644 if (sp>=sl) return -1;
4645 while (sp<sl)
4646 {
4647 char c=s.at(sp);
4648 if (c==':')
4649 {
4650 sp++;
4651 p++;
4652 }
4653 else
4654 {
4655 break;
4656 }
4657 }
4658 while (sp<sl)
4659 {
4660 char c=s.at(sp);
4661 switch (c)
4662 {
4663 case ':': // found next part
4664 goto found;
4665 case '<': // skip template specifier
4666 count=1;sp++;
4667 done=false;
4668 while (sp<sl && !done)
4669 {
4670 // TODO: deal with << and >> operators!
4671 c=s.at(sp++);
4672 switch(c)
4673 {
4674 case '<': count++; break;
4675 case '>': count--; if (count==0) done=true; break;
4676 default: break;
4677 }
4678 }
4679 break;
4680 default:
4681 sp++;
4682 break;
4683 }
4684 }
4685found:
4686 *l=sp-p;
4687 //printf("getScopeFragment(%s,%d)=%s\n",qPrint(s),p,qPrint(s.mid(p,*l)));
4688 return p;
4689}

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

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

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

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

References updateLanguageMapping().

Referenced by initDoxygen().

◆ inlineArgListToDoc()

QCString inlineArgListToDoc ( const ArgumentList & al)

Definition at line 1204 of file util.cpp.

1205{
1206 QCString paramDocs;
1207 if (al.hasDocumentation())
1208 {
1209 for (const Argument &a : al)
1210 {
1211 if (a.hasDocumentation())
1212 {
1213 QCString docsWithoutDir = a.docs;
1214 QCString direction = extractDirection(docsWithoutDir);
1215 paramDocs+=" \\ilinebr @param"+direction+" "+a.name+" "+docsWithoutDir;
1216 }
1217 }
1218 }
1219 return paramDocs;
1220}
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:6196

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

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

◆ inlineTemplateArgListToDoc()

QCString inlineTemplateArgListToDoc ( const ArgumentList & al)

Definition at line 1222 of file util.cpp.

1223{
1224 QCString paramDocs;
1225 if (al.hasTemplateDocumentation())
1226 {
1227 for (const Argument &a : al)
1228 {
1229 if (!a.docs.isEmpty())
1230 {
1231 if (!a.name.isEmpty())
1232 {
1233 paramDocs+=" \\ilinebr @tparam "+a.name+" "+a.docs;
1234 }
1235 else if (!a.type.isEmpty())
1236 {
1237 QCString type = a.type;
1238 type.stripPrefix("class ");
1239 type.stripPrefix("typename ");
1240 type = type.stripWhiteSpace();
1241 paramDocs+=" \\ilinebr @tparam "+type+" "+a.docs;
1242 }
1243 }
1244 }
1245 }
1246 return paramDocs;
1247}
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 3745 of file util.cpp.

3746{
3747 QCString result=scope;
3748 if (!templ.isEmpty() && scope.find('<')==-1)
3749 {
3750 int si=0, pi=0;
3751 ClassDef *cd=nullptr;
3752 while (
3753 (si=scope.find("::",pi))!=-1 && !getClass(scope.left(si)+templ) &&
3754 ((cd=getClass(scope.left(si)))==nullptr || cd->templateArguments().empty())
3755 )
3756 {
3757 //printf("Tried '%s'\n",qPrint((scope.left(si)+templ)));
3758 pi=si+2;
3759 }
3760 if (si==-1) // not nested => append template specifier
3761 {
3762 result+=templ;
3763 }
3764 else // nested => insert template specifier before after first class name
3765 {
3766 result=scope.left(si) + templ + scope.right(scope.length()-si);
3767 }
3768 }
3769 //printf("insertTemplateSpecifierInScope('%s','%s')=%s\n",
3770 // qPrint(scope),qPrint(templ),qPrint(result));
3771 return result;
3772}
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 6700 of file util.cpp.

6701{
6702 QCString result;
6703 int residual = n;
6704
6705 char modVal[2];
6706 modVal[1] = 0;
6707 while (residual > 0)
6708 {
6709 modVal[0] = (upper ? 'A': 'a') + (residual-1)%26;
6710 result = modVal + result;
6711 residual = (residual-1) / 26;
6712 }
6713 return result;
6714}

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

◆ integerToRoman()

QCString integerToRoman ( int n,
bool upper = true )

Definition at line 6716 of file util.cpp.

6717{
6718 static const char *str_romans_upper[] = { "M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I" };
6719 static const char *str_romans_lower[] = { "m", "cm", "d", "cd", "c", "xc", "l", "xl", "x", "ix", "v", "iv", "i" };
6720 static const int values[] = { 1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1 };
6721 static const char **str_romans = upper ? str_romans_upper : str_romans_lower;
6722
6723 QCString result;
6724 int residual = n;
6725
6726 for (int i = 0; i < 13; ++i)
6727 {
6728 while (residual - values[i] >= 0)
6729 {
6730 result += str_romans[i];
6731 residual -= values[i];
6732 }
6733 }
6734
6735 return result;
6736}

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

◆ isId()

◆ isIdJS()

bool isIdJS ( int c)
inline

Definition at line 260 of file util.h.

261{
262 return c>=128 || c<0 || isalnum(c);
263}

Referenced by SearchTerm::termEncoded().

◆ isURL()

bool isURL ( const QCString & url)

Checks whether the given url starts with a supported protocol.

Definition at line 5931 of file util.cpp.

5932{
5933 static const std::unordered_set<std::string> schemes = {
5934 "http", "https", "ftp", "ftps", "sftp", "file", "news", "irc", "ircs"
5935 };
5936 QCString loc_url = url.stripWhiteSpace();
5937 int colonPos = loc_url.find(':');
5938 return colonPos!=-1 && schemes.find(loc_url.left(colonPos).str())!=schemes.end();
5939}

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

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

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

6688{
6689 std::string result;
6690 bool first=true;
6691 for (const auto &s : sv)
6692 {
6693 if (!first) result+=delimiter;
6694 first=false;
6695 result+=s;
6696 }
6697 return result;
6698}

◆ langToString()

QCString langToString ( SrcLangExt lang)

Returns a string representation of lang.

Definition at line 5909 of file util.cpp.

5910{
5911 return to_string(lang);
5912}
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 881 of file util.cpp.

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

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

5889{
5890 int result = 1;
5891
5892 // find the character positions of the first marker
5893 int m1 = text.find(marker);
5894 if (m1==-1) return result;
5895
5896 // find start line positions for the markers
5897 bool found=false;
5898 int p=0, i=0;
5899 while (!found && (i=text.find('\n',p))!=-1)
5900 {
5901 found = (p<=m1 && m1<i); // found the line with the start marker
5902 p=i+1;
5903 result++;
5904 }
5905 return result;
5906}

References QCString::find().

◆ linkifyText()

void linkifyText ( const TextGeneratorIntf & ol,
const QCString & text,
const LinkifyTextOptions & options )

Definition at line 893 of file util.cpp.

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

References Definition::anchor(), LinkifyTextOptions::argumentList(), AUTO_TRACE, LinkifyTextOptions::autoBreak(), ArgumentList::begin(), LinkifyTextOptions::breakThreshold(), QCString::data(), Definition::definitionType(), ArgumentList::end(), end(), LinkifyTextOptions::external(), FALSE, LinkifyTextOptions::fileScope(), QCString::findRev(), GetDefResult::found, getClass(), getConcept(), getDefs(), Definition::getLanguage(), Definition::getOuterScope(), Definition::getOutputFileBase(), Definition::getReference(), SymbolResolver::getTypedef(), LinkifyTextOptions::indentLevel(), QCString::isEmpty(), Definition::isLinkable(), Definition::isLinkableInProject(), MemberDef::isVariable(), LinkifyTextOptions::keepSpaces(), QCString::left(), GetDefResult::md, QCString::mid(), Definition::name(), Definition::qualifiedName(), SymbolResolver::resolveClass(), SymbolResolver::resolveSymbol(), LinkifyTextOptions::scope(), LinkifyTextOptions::self(), 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 2693 of file util.cpp.

2694{
2695 //bool optimizeOutputJava = Config_getBool(OPTIMIZE_OUTPUT_JAVA);
2696 QCString result=link;
2697 if (!result.isEmpty())
2698 {
2699 // replace # by ::
2700 result=substitute(result,"#","::");
2701 // replace . by ::
2702 if (!isFileName && result.find('<')==-1) result=substitute(result,".","::",3);
2703 // strip leading :: prefix if present
2704 if (result.at(0)==':' && result.at(1)==':')
2705 {
2706 result=result.right(result.length()-2);
2707 }
2709 if (sep!="::")
2710 {
2711 result=substitute(result,"::",sep);
2712 }
2713 }
2714 //printf("linkToText(%s,lang=%d)=%s\n",qPrint(link),lang,qPrint(result));
2715 return result;
2716}
QCString getLanguageSpecificSeparator(SrcLangExt lang, bool classScope)
Returns the scope separator to use given the programming language lang.
Definition util.cpp:5915

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

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

References Doxygen::mainPage.

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

◆ makeBaseName()

◆ mangleCSharpGenericName()

QCString mangleCSharpGenericName ( const QCString & name)

Definition at line 6931 of file util.cpp.

6932{
6933 int idx = name.find('<');
6934 if (idx!=-1)
6935 {
6936 return name.left(idx)+"-"+QCString().setNum(name.contains(",")+1)+"-g";
6937 }
6938 return name;
6939}
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 2016 of file util.cpp.

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

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

2261{
2262 AUTO_TRACE("srcAl={} dstAl={}",argListToString(srcAl),argListToString(dstAl));
2263 if (srcAl.size()!=dstAl.size()) // different number of template parameters -> overload
2264 {
2265 AUTO_TRACE_EXIT("different number of parameters");
2266 return false;
2267 }
2268 auto isUnconstraintTemplate = [](const QCString &type)
2269 {
2270 return type=="typename" || type=="class" || type.startsWith("typename ") || type.startsWith("class ");
2271 };
2272 auto srcIt = srcAl.begin();
2273 auto dstIt = dstAl.begin();
2274 while (srcIt!=srcAl.end() && dstIt!=dstAl.end())
2275 {
2276 const Argument &srcA = *srcIt;
2277 const Argument &dstA = *dstIt;
2278 if ((!isUnconstraintTemplate(srcA.type) || !isUnconstraintTemplate(dstA.type)) && srcA.type!=dstA.type) // different constraints -> overload
2279 {
2280 AUTO_TRACE_EXIT("different constraints");
2281 return false;
2282 }
2283 ++srcIt;
2284 ++dstIt;
2285 }
2286 AUTO_TRACE_EXIT("same");
2287 // no overload with respect to the template parameters
2288 return true;
2289}

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

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

6880{
6881 if (Config_getBool(CALL_GRAPH) !=md1->hasCallGraph()) md2->overrideCallGraph(md1->hasCallGraph());
6882 if (Config_getBool(CALLER_GRAPH)!=md1->hasCallerGraph()) md2->overrideCallerGraph(md1->hasCallerGraph());
6883 if (Config_getBool(CALL_GRAPH) !=md2->hasCallGraph()) md1->overrideCallGraph( md2->hasCallGraph());
6884 if (Config_getBool(CALLER_GRAPH)!=md2->hasCallerGraph()) md1->overrideCallerGraph(md2->hasCallerGraph());
6885
6886 if (Config_getBool(SHOW_ENUM_VALUES) !=md1->hasEnumValues()) md2->overrideEnumValues(md1->hasEnumValues());
6887 if (Config_getBool(SHOW_ENUM_VALUES) !=md2->hasEnumValues()) md1->overrideEnumValues( md2->hasEnumValues());
6888
6889 if (Config_getBool(REFERENCED_BY_RELATION)!=md1->hasReferencedByRelation()) md2->overrideReferencedByRelation(md1->hasReferencedByRelation());
6890 if (Config_getBool(REFERENCES_RELATION) !=md1->hasReferencesRelation()) md2->overrideReferencesRelation(md1->hasReferencesRelation());
6891 if (Config_getBool(REFERENCED_BY_RELATION)!=md2->hasReferencedByRelation()) md1->overrideReferencedByRelation(md2->hasReferencedByRelation());
6892 if (Config_getBool(REFERENCES_RELATION) !=md2->hasReferencesRelation()) md1->overrideReferencesRelation(md2->hasReferencesRelation());
6893
6894 if (Config_getBool(INLINE_SOURCES)!=md1->hasInlineSource()) md2->overrideInlineSource(md1->hasInlineSource());
6895 if (Config_getBool(INLINE_SOURCES)!=md2->hasInlineSource()) md1->overrideInlineSource(md2->hasInlineSource());
6896}
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 4593 of file util.cpp.

4594{
4595 AUTO_TRACE("leftScope='{}' rightScope='{}'",leftScope,rightScope);
4596 // case leftScope=="A" rightScope=="A::B" => result = "A::B"
4597 if (leftScopeMatch(leftScope,rightScope))
4598 {
4599 AUTO_TRACE_EXIT("case1={}",rightScope);
4600 return rightScope;
4601 }
4602 QCString result;
4603 int i=0,p=static_cast<int>(leftScope.length());
4604
4605 // case leftScope=="A::B" rightScope=="B::C" => result = "A::B::C"
4606 // case leftScope=="A::B" rightScope=="B" => result = "A::B"
4607 bool found=FALSE;
4608 while ((i=leftScope.findRev("::",p))>0)
4609 {
4610 if (leftScopeMatch(rightScope,leftScope.right(leftScope.length()-i-2)))
4611 {
4612 result = leftScope.left(i+2)+rightScope;
4613 found=TRUE;
4614 }
4615 p=i-1;
4616 }
4617 if (found)
4618 {
4619 AUTO_TRACE_EXIT("case2={}",result);
4620 return result;
4621 }
4622
4623 // case leftScope=="A" rightScope=="B" => result = "A::B"
4624 result=leftScope;
4625 if (!result.isEmpty() && !rightScope.isEmpty()) result+="::";
4626 result+=rightScope;
4627 AUTO_TRACE_EXIT("case3={}",result);
4628 return result;
4629}
bool leftScopeMatch(const QCString &scope, const QCString &name)
Definition util.cpp:881

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

4303{
4304 // skip until <
4305 int p=name.find('<');
4306 if (p==-1) return name;
4307 p++;
4308 QCString result = name.left(p);
4309
4310 std::string s = name.mid(p).str();
4311 static const reg::Ex re(R"([\a:][\w:]*)");
4312 reg::Iterator it(s,re);
4314 size_t pi=0;
4315 // for each identifier in the template part (e.g. B<T> -> T)
4316 for (; it!=end ; ++it)
4317 {
4318 const auto &match = *it;
4319 size_t i = match.position();
4320 size_t l = match.length();
4321 result += s.substr(pi,i-pi);
4322 QCString n(match.str());
4323 bool found=FALSE;
4324 for (const Argument &formArg : formalArgs)
4325 {
4326 if (formArg.name == n)
4327 {
4328 found=TRUE;
4329 break;
4330 }
4331 }
4332 if (!found)
4333 {
4334 // try to resolve the type
4335 SymbolResolver resolver;
4336 const ClassDef *cd = resolver.resolveClass(context,n);
4337 if (cd)
4338 {
4339 result+=cd->name();
4340 }
4341 else
4342 {
4343 result+=n;
4344 }
4345 }
4346 else
4347 {
4348 result+=n;
4349 }
4350 pi=i+l;
4351 }
4352 result+=s.substr(pi);
4353 //printf("normalizeNonTemplateArgumentInString(%s)=%s\n",qPrint(name),qPrint(result));
4354 return removeRedundantWhiteSpace(result);
4355}
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 6314 of file util.cpp.

6315{
6316 assert(!f.is_open());
6317 bool fileOpened=FALSE;
6318 bool writeToStdout=outFile=="-";
6319 if (writeToStdout) // write to stdout
6320 {
6321 f.basic_ios<char>::rdbuf(std::cout.rdbuf());
6322 fileOpened = true;
6323 }
6324 else // write to file
6325 {
6326 FileInfo fi(outFile.str());
6327 if (fi.exists()) // create a backup
6328 {
6329 Dir dir;
6330 FileInfo backup(fi.filePath()+".bak");
6331 if (backup.exists()) // remove existing backup
6332 dir.remove(backup.filePath());
6333 dir.rename(fi.filePath(),fi.filePath()+".bak");
6334 }
6335 f = Portable::openOutputStream(outFile);
6336 fileOpened = f.is_open();
6337 }
6338 return fileOpened;
6339}
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:648

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

5424{
5425 std::lock_guard lock(g_docCacheMutex);
5426 auto it = g_docCache.find(doc.str());
5427 if (it != g_docCache.end())
5428 {
5429 //printf("Cache: [%s]->[%s]\n",qPrint(doc),qPrint(it->second));
5430 return it->second;
5431 }
5432 auto parser { createDocParser() };
5433 auto ast { validatingParseTitle(*parser.get(),fileName,lineNr,doc) };
5434 auto astImpl = dynamic_cast<const DocNodeAST*>(ast.get());
5435 QCString result;
5436 if (astImpl)
5437 {
5438 TextStream t;
5439 OutputCodeList codeList;
5440 codeList.add<HtmlCodeGenerator>(&t);
5441 HtmlDocVisitor visitor(t,codeList,scope,fileName);
5442 std::visit(visitor,astImpl->root);
5443 result = t.str();
5444 }
5445 else // fallback, should not happen
5446 {
5447 result = filterTitle(doc);
5448 }
5449 //printf("Conversion: [%s]->[%s]\n",qPrint(doc),qPrint(result));
5450 g_docCache.insert(std::make_pair(doc.str(),result));
5451 return result;
5452}
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:5421
QCString filterTitle(const QCString &title)
Definition util.cpp:5628
static std::mutex g_docCacheMutex
Definition util.cpp:5420

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

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

◆ parseCommentAsText()

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

Definition at line 5367 of file util.cpp.

5369{
5370 if (doc.isEmpty()) return "";
5371 //printf("parseCommentAsText(%s)\n",qPrint(doc));
5372 TextStream t;
5373 auto parser { createDocParser() };
5374 auto ast { validatingParseDoc(*parser.get(),
5375 fileName,
5376 lineNr,
5377 scope,
5378 md,
5379 doc,
5380 DocOptions()
5381 .setAutolinkSupport(false))
5382 };
5383 auto astImpl = dynamic_cast<const DocNodeAST*>(ast.get());
5384 if (astImpl)
5385 {
5386 TextDocVisitor visitor(t);
5387 std::visit(visitor,astImpl->root);
5388 }
5390 int i=0;
5391 int charCnt=0;
5392 int l=static_cast<int>(result.length());
5393 while ((i=nextUTF8CharPosition(result,l,i))<l)
5394 {
5395 charCnt++;
5396 if (charCnt>=80) break;
5397 }
5398 if (charCnt>=80) // try to truncate the string
5399 {
5400 while ((i=nextUTF8CharPosition(result,l,i))<l && charCnt<100)
5401 {
5402 charCnt++;
5403 if (result.at(i)==',' ||
5404 result.at(i)=='.' ||
5405 result.at(i)=='!' ||
5406 result.at(i)=='?' ||
5407 result.at(i)=='}') // good for UTF-16 characters and } otherwise also a good point to stop the string
5408 {
5409 i++; // we want to be "behind" last inspected character
5410 break;
5411 }
5412 }
5413 }
5414 if ( i < l) result=result.left(i)+"...";
5415 return result.data();
5416}
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:5323

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(), and RequirementManager::writeRef().

◆ patternMatch()

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

Definition at line 5702 of file util.cpp.

5703{
5704 std::string elem;
5705 auto getter = [](std::string s) -> QCString { return s; };
5706 return genericPatternMatch(fi,patList,elem,getter);
5707}

References genericPatternMatch().

Referenced by readDir().

◆ processMarkup()

QCString processMarkup ( const QCString & s)

◆ projectLogoFile()

QCString projectLogoFile ( )

Definition at line 3139 of file util.cpp.

3140{
3141 QCString projectLogo = Config_getString(PROJECT_LOGO);
3142 if (!projectLogo.isEmpty())
3143 {
3144 // check for optional width= and height= specifier
3145 int wi = projectLogo.find(" width=");
3146 if (wi!=-1) // and strip them
3147 {
3148 projectLogo = projectLogo.left(wi);
3149 }
3150 int hi = projectLogo.find(" height=");
3151 if (hi!=-1)
3152 {
3153 projectLogo = projectLogo.left(hi);
3154 }
3155 }
3156 //printf("projectlogo='%s'\n",qPrint(projectLogo));
3157 return projectLogo;
3158}

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

Referenced by copyLogo(), and substituteKeywords().

◆ protectionLevelVisible()

bool protectionLevelVisible ( Protection prot)

Definition at line 5955 of file util.cpp.

5956{
5957 bool extractPrivate = Config_getBool(EXTRACT_PRIVATE);
5958 bool extractPackage = Config_getBool(EXTRACT_PACKAGE);
5959
5960 return (prot!=Protection::Private && prot!=Protection::Package) ||
5961 (prot==Protection::Private && extractPrivate) ||
5962 (prot==Protection::Package && extractPackage);
5963}

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

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

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

6362{
6363 int column=0;
6364 bool skipLine=FALSE;
6365
6366 if (format == FortranFormat::Fixed) return TRUE;
6367 if (format == FortranFormat::Free) return FALSE;
6368
6369 int tabSize=Config_getInt(TAB_SIZE);
6370 size_t sizCont = contents.length();
6371 for (size_t i=0;i<sizCont;i++)
6372 {
6373 column++;
6374
6375 switch(contents.at(i))
6376 {
6377 case '\n':
6378 column=0;
6379 skipLine=FALSE;
6380 break;
6381 case '\t':
6382 column += tabSize-1;
6383 break;
6384 case ' ':
6385 break;
6386 case '\000':
6387 return FALSE;
6388 case '#':
6389 skipLine=TRUE;
6390 break;
6391 case 'C':
6392 case 'c':
6393 if (column==1)
6394 {
6395 return !keyWordsFortranC(contents.data()+i);
6396 }
6397 // fallthrough
6398 case '*':
6399 if (column==1) return TRUE;
6400 if (skipLine) break;
6401 return FALSE;
6402 case '!':
6403 if (column!=6) skipLine=TRUE;
6404 break;
6405 default:
6406 if (skipLine) break;
6407 if (column>=7) return TRUE;
6408 return FALSE;
6409 }
6410 }
6411 return FALSE;
6412}
static bool keyWordsFortranC(const char *contents)
Definition util.cpp:6341

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

3579{
3580 QCString result;
3581 if (Config_getBool(CREATE_SUBDIRS))
3582 {
3583 if (name.isEmpty())
3584 {
3585 return REL_PATH_TO_ROOT;
3586 }
3587 else
3588 {
3589 int i = name.findRev('/');
3590 if (i!=-1)
3591 {
3592 result=REL_PATH_TO_ROOT;
3593 }
3594 }
3595 }
3596 return result;
3597}
#define REL_PATH_TO_ROOT
Definition util.cpp:94

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

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

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

6605{
6606 std::string out;
6607 out.reserve(s.length());
6608 const char *p=s.data();
6609 if (p)
6610 {
6611 char c = 0;
6612 while ((c=*p++))
6613 {
6614 if (c=='\n')
6615 {
6616 const char *e = p;
6617 while (*e==' ' || *e=='\t') e++;
6618 if (*e=='\n')
6619 {
6620 p=e;
6621 }
6622 else out+=c;
6623 }
6624 else
6625 {
6626 out+=c;
6627 }
6628 }
6629 }
6630 //printf("removeEmptyLines(%s)=%s\n",qPrint(s),qPrint(out));
6631 return out;
6632}

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

Referenced by substituteHtmlKeywords(), and substituteLatexKeywords().

◆ removeLongPathMarker()

QCString removeLongPathMarker ( QCString path)

Definition at line 287 of file util.cpp.

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

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

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

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

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

5825{
5826 if (str.isEmpty()) return QCString();
5827 std::string result;
5828 std::string s=str.str();
5829 static const reg::Ex re(R"(##[0-9A-Fa-f][0-9A-Fa-f])");
5830 reg::Iterator it(s,re);
5832 int hue = Config_getInt(HTML_COLORSTYLE_HUE);
5833 int sat = Config_getInt(HTML_COLORSTYLE_SAT);
5834 int gamma = Config_getInt(HTML_COLORSTYLE_GAMMA);
5835 size_t sl=s.length();
5836 size_t p=0;
5837 for (; it!=end ; ++it)
5838 {
5839 const auto &match = *it;
5840 size_t i = match.position();
5841 size_t l = match.length();
5842 if (i>p) result+=s.substr(p,i-p);
5843 std::string lumStr = match.str().substr(2);
5844#define HEXTONUM(x) (((x)>='0' && (x)<='9') ? ((x)-'0') : \
5845 ((x)>='a' && (x)<='f') ? ((x)-'a'+10) : \
5846 ((x)>='A' && (x)<='F') ? ((x)-'A'+10) : 0)
5847
5848 double r = 0,g = 0,b = 0;
5849 int level = HEXTONUM(lumStr[0])*16+HEXTONUM(lumStr[1]);
5850 ColoredImage::hsl2rgb(hue/360.0,sat/255.0,
5851 pow(level/255.0,gamma/100.0),&r,&g,&b);
5852 int red = static_cast<int>(r*255.0);
5853 int green = static_cast<int>(g*255.0);
5854 int blue = static_cast<int>(b*255.0);
5855 char colStr[8];
5856 colStr[0]='#';
5857 colStr[1]=hex[red>>4];
5858 colStr[2]=hex[red&0xf];
5859 colStr[3]=hex[green>>4];
5860 colStr[4]=hex[green&0xf];
5861 colStr[5]=hex[blue>>4];
5862 colStr[6]=hex[blue&0xf];
5863 colStr[7]=0;
5864 //printf("replacing %s->%s (level=%d)\n",qPrint(lumStr),colStr,level);
5865 result+=colStr;
5866 p=i+l;
5867 }
5868 if (p<sl) result+=s.substr(p);
5869 return result;
5870}
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 2719 of file util.cpp.

2727{
2728 *resContext=nullptr;
2729
2730 QCString linkRef=lr;
2731 if (lang==SrcLangExt::CSharp)
2732 {
2733 linkRef = mangleCSharpGenericName(linkRef);
2734 }
2735 QCString linkRefWithoutTemplates = stripTemplateSpecifiersFromScope(linkRef,FALSE);
2736 AUTO_TRACE("scName='{}',ref='{}'",scName,lr);
2737 const FileDef *fd = nullptr;
2738 const GroupDef *gd = nullptr;
2739 const PageDef *pd = nullptr;
2740 const ClassDef *cd = nullptr;
2741 const DirDef *dir = nullptr;
2742 const ConceptDef *cnd = nullptr;
2743 const ModuleDef *modd = nullptr;
2744 const NamespaceDef *nd = nullptr;
2745 const SectionInfo *si = nullptr;
2746 bool ambig = false;
2747 if (linkRef.isEmpty()) // no reference name!
2748 {
2749 AUTO_TRACE_EXIT("no_ref");
2750 return FALSE;
2751 }
2752 else if ((pd=Doxygen::pageLinkedMap->find(linkRef))) // link to a page
2753 {
2754 gd = pd->getGroupDef();
2755 if (gd)
2756 {
2757 if (!pd->name().isEmpty()) si=SectionManager::instance().find(pd->name());
2758 *resContext=gd;
2759 if (si) resAnchor = si->label();
2760 }
2761 else
2762 {
2763 *resContext=pd;
2764 }
2765 AUTO_TRACE_EXIT("page");
2766 return TRUE;
2767 }
2768 else if ((si=SectionManager::instance().find(prefix+linkRef)))
2769 {
2770 *resContext=si->definition();
2771 resAnchor = si->label();
2772 AUTO_TRACE_EXIT("section anchor={} def={}",resAnchor,si->definition()?si->definition()->name():"<none>");
2773 return TRUE;
2774 }
2775 else if (!prefix.isEmpty() && (si=SectionManager::instance().find(linkRef)))
2776 {
2777 *resContext=si->definition();
2778 resAnchor = si->label();
2779 AUTO_TRACE_EXIT("section anchor={} def={}",resAnchor,si->definition()?si->definition()->name():"<none>");
2780 return TRUE;
2781 }
2782 else if ((pd=Doxygen::exampleLinkedMap->find(linkRef))) // link to an example
2783 {
2784 *resContext=pd;
2785 AUTO_TRACE_EXIT("example");
2786 return TRUE;
2787 }
2788 else if ((gd=Doxygen::groupLinkedMap->find(linkRef))) // link to a group
2789 {
2790 *resContext=gd;
2791 AUTO_TRACE_EXIT("group");
2792 return TRUE;
2793 }
2794 else if ((fd=findFileDef(Doxygen::inputNameLinkedMap,linkRef,ambig)) // file link
2795 && fd->isLinkable())
2796 {
2797 *resContext=fd;
2798 AUTO_TRACE_EXIT("file");
2799 return TRUE;
2800 }
2801 else if ((cd=getClass(linkRef))) // class link
2802 {
2803 *resContext=cd;
2804 resAnchor=cd->anchor();
2805 AUTO_TRACE_EXIT("class");
2806 return TRUE;
2807 }
2808 else if (lang==SrcLangExt::Java &&
2809 (cd=getClass(linkRefWithoutTemplates))) // Java generic class link
2810 {
2811 *resContext=cd;
2812 resAnchor=cd->anchor();
2813 AUTO_TRACE_EXIT("generic");
2814 return TRUE;
2815 }
2816 else if ((cd=getClass(linkRef+"-p"))) // Obj-C protocol link
2817 {
2818 *resContext=cd;
2819 resAnchor=cd->anchor();
2820 AUTO_TRACE_EXIT("protocol");
2821 return TRUE;
2822 }
2823 else if ((cnd=getConcept(linkRef))) // C++20 concept definition
2824 {
2825 *resContext=cnd;
2826 resAnchor=cnd->anchor();
2827 AUTO_TRACE_EXIT("concept");
2828 return TRUE;
2829 }
2830 else if ((modd=ModuleManager::instance().modules().find(linkRef)))
2831 {
2832 *resContext=modd;
2833 resAnchor=modd->anchor();
2834 AUTO_TRACE_EXIT("module");
2835 return TRUE;
2836 }
2837 else if ((nd=Doxygen::namespaceLinkedMap->find(linkRef)))
2838 {
2839 *resContext=nd;
2840 AUTO_TRACE_EXIT("namespace");
2841 return TRUE;
2842 }
2843 else if ((dir=Doxygen::dirLinkedMap->find(FileInfo(linkRef.str()).absFilePath()+"/"))
2844 && dir->isLinkable()) // TODO: make this location independent like filedefs
2845 {
2846 *resContext=dir;
2847 AUTO_TRACE_EXIT("directory");
2848 return TRUE;
2849 }
2850 else // probably a member reference
2851 {
2852 const MemberDef *md = nullptr;
2853 bool res = resolveRef(scName,lr,TRUE,resContext,&md,lang);
2854 if (md) resAnchor=md->anchor();
2855 AUTO_TRACE_EXIT("member? res={}",res);
2856 return res;
2857 }
2858}
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:126
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:2437
QCString mangleCSharpGenericName(const QCString &name)
Definition util.cpp:6931
QCString stripTemplateSpecifiersFromScope(const QCString &fullName, bool parentOnly, QCString *pLastScopeStripped, QCString scopeName, bool allowArtificial)
Definition util.cpp:4526

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

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

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

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

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

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

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

6428{
6429 if (s.isEmpty()) return s;
6430
6431 // helper to find the end of a block
6432 auto skipBlock = [&markerInfo](const char *p,const SelectionBlock &blk)
6433 {
6434 char c = 0;
6435 while ((c=*p))
6436 {
6437 if (c==markerInfo.markerChar && qstrncmp(p,markerInfo.endStr,markerInfo.endLen)==0) // end marker
6438 {
6439 size_t len = markerInfo.endLen;
6440 bool negate = *(p+markerInfo.endLen)=='!';
6441 if (negate) len++;
6442 size_t blkNameLen = qstrlen(blk.name);
6443 if (qstrncmp(p+len,blk.name,blkNameLen)==0 && // matching marker name
6444 qstrncmp(p+len+blkNameLen,markerInfo.closeStr,markerInfo.closeLen)==0) // matching marker closing
6445 {
6446 //printf("Found end marker %s enabled=%d negate=%d\n",blk.name,blk.enabled,negate);
6447 return p+len+blkNameLen+markerInfo.closeLen;
6448 }
6449 else // not the right marker id
6450 {
6451 p++;
6452 }
6453 }
6454 else // not and end marker
6455 {
6456 p++;
6457 }
6458 }
6459 return p;
6460 };
6461
6462 QCString result;
6463 result.reserve(s.length());
6464 const char *p = s.data();
6465 char c = 0;
6466 while ((c=*p))
6467 {
6468 if (c==markerInfo.markerChar) // potential start of marker
6469 {
6470 if (qstrncmp(p,markerInfo.beginStr,markerInfo.beginLen)==0) // start of begin marker
6471 {
6472 bool found = false;
6473 size_t len = markerInfo.beginLen;
6474 bool negate = *(p+len)=='!';
6475 if (negate) len++;
6476 for (const auto &blk : blockList)
6477 {
6478 size_t blkNameLen = qstrlen(blk.name);
6479 if (qstrncmp(p+len,blk.name,blkNameLen)==0 && // matching marker name
6480 qstrncmp(p+len+blkNameLen,markerInfo.closeStr,markerInfo.closeLen)==0) // matching marker closing
6481 {
6482 bool blockEnabled = blk.enabled!=negate;
6483 //printf("Found start marker %s enabled=%d negate=%d\n",blk.name,blk.enabled,negate);
6484 p+=len+blkNameLen+markerInfo.closeLen;
6485 if (!blockEnabled) // skip until the end of the block
6486 {
6487 //printf("skipping block\n");
6488 p=skipBlock(p,blk);
6489 }
6490 found=true;
6491 break;
6492 }
6493 }
6494 if (!found) // unknown marker id
6495 {
6496 result+=c;
6497 p++;
6498 }
6499 }
6500 else if (qstrncmp(p,markerInfo.endStr,markerInfo.endLen)==0) // start of end marker
6501 {
6502 bool found = false;
6503 size_t len = markerInfo.endLen;
6504 bool negate = *(p+len)=='!';
6505 if (negate) len++;
6506 for (const auto &blk : blockList)
6507 {
6508 size_t blkNameLen = qstrlen(blk.name);
6509 if (qstrncmp(p+len,blk.name,blkNameLen)==0 && // matching marker name
6510 qstrncmp(p+len+blkNameLen,markerInfo.closeStr,markerInfo.closeLen)==0) // matching marker closing
6511 {
6512 //printf("Found end marker %s enabled=%d negate=%d\n",blk.name,blk.enabled,negate);
6513 p+=len+blkNameLen+markerInfo.closeLen;
6514 found=true;
6515 break;
6516 }
6517 }
6518 if (!found) // unknown marker id
6519 {
6520 result+=c;
6521 p++;
6522 }
6523 }
6524 else // not a start or end marker
6525 {
6526 result+=c;
6527 p++;
6528 }
6529 }
6530 else // not a marker character
6531 {
6532 result+=c;
6533 p++;
6534 }
6535 }
6536 //printf("====\n%s\n-----\n%s\n~~~~\n",qPrint(s),qPrint(result));
6537 return result;
6538}
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 3017 of file util.cpp.

3018{
3019 QCString result;
3020 QCString name=Dir::cleanDirPath(n.str());
3021 QCString path;
3022 int slashPos=std::max(name.findRev('/'),name.findRev('\\'));
3023 if (slashPos!=-1)
3024 {
3025 path=removeLongPathMarker(name.left(slashPos+1));
3026 name=name.right(name.length()-slashPos-1);
3027 }
3028 const FileName *fn=fnMap->find(name);
3029 if (fn)
3030 {
3031 bool first = true;
3032 QCString pathStripped = stripFromIncludePath(path);
3033 for (const auto &fd_p : *fn)
3034 {
3035 FileDef *fd = fd_p.get();
3036 QCString fdStripPath = stripFromIncludePath(fd->getPath());
3037 if (path.isEmpty() ||
3038 (!pathStripped.isEmpty() && fdStripPath.endsWith(pathStripped)) ||
3039 (pathStripped.isEmpty() && fdStripPath.isEmpty()))
3040 {
3041 if (!first) result += "\n";
3042 else first = false;
3043 result+=" "+fd->absFilePath();
3044 }
3045 }
3046
3047 }
3048 return result;
3049}

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

6654{
6655 StringVector result;
6656 reg::Iterator iter(s, delimiter);
6658 size_t p=0;
6659 for ( ; iter != end; ++iter)
6660 {
6661 const auto &match = *iter;
6662 size_t i=match.position();
6663 size_t l=match.length();
6664 if (i>p) result.push_back(s.substr(p,i-p));
6665 p=i+l;
6666 }
6667 if (p<s.length()) result.push_back(s.substr(p));
6668 return result;
6669}

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

6637{
6638 StringVector result;
6639 size_t prev = 0, pos = 0, len = s.length();
6640 do
6641 {
6642 pos = s.find(delimiter, prev);
6643 if (pos == std::string::npos) pos = len;
6644 if (pos>prev) result.push_back(s.substr(prev,pos-prev));
6645 prev = pos + delimiter.length();
6646 }
6647 while (pos<len && prev<len);
6648 return result;
6649}

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

5485{
5486#ifdef TRACINGSUPPORT
5487 void *backtraceFrames[128];
5488 int frameCount = backtrace(backtraceFrames, 128);
5489 const size_t cmdLen = 40960;
5490 static char cmd[cmdLen];
5491 char *p = cmd;
5492 p += qsnprintf(p,cmdLen,"/usr/bin/atos -p %d ", (int)getpid());
5493 for (int x = 0; x < frameCount; x++)
5494 {
5495 p += qsnprintf(p,cmdLen,"%p ", backtraceFrames[x]);
5496 }
5497 fprintf(stderr,"========== STACKTRACE START ==============\n");
5498 if (FILE *fp = Portable::popen(cmd, "r"))
5499 {
5500 char resBuf[512];
5501 while (size_t len = fread(resBuf, 1, sizeof(resBuf), fp))
5502 {
5503 fwrite(resBuf, 1, len, stderr);
5504 }
5505 Portable::pclose(fp);
5506 }
5507 fprintf(stderr,"============ STACKTRACE END ==============\n");
5508 //fprintf(stderr,"%s\n", frameStrings[x]);
5509#endif
5510}

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

◆ stripAnonymousNamespaceScope()

QCString stripAnonymousNamespaceScope ( const QCString & s)

Definition at line 230 of file util.cpp.

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

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

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

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

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

References Config_getList, and stripFromPath().

◆ stripIndentation()

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

Definition at line 5967 of file util.cpp.

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

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

6057{
6058 //printf("stripIndentationVerbatim(level=%d):\n%s\n------\n",indentationLevel,qPrint(doc));
6059 if (indentationLevel <= 0 || doc.isEmpty()) return; // nothing to strip
6060
6061 // by stripping content the string will only become shorter so we write the results
6062 // back into the input string and then resize it at the end.
6063 char c = 0;
6064 const char *src = doc.data();
6065 char *dst = doc.rawData();
6066 bool insideIndent = !skipFirstLine; // skip the initial line from stripping
6067 int cnt = 0;
6068 if (!skipFirstLine) cnt = indentationLevel;
6069 while ((c=*src++))
6070 {
6071 // invariant: dst<=src
6072 switch(c)
6073 {
6074 case '\n':
6075 *dst++ = c;
6076 insideIndent = true;
6077 cnt = indentationLevel;
6078 break;
6079 case ' ':
6080 if (insideIndent)
6081 {
6082 if (cnt>0) // count down the spacing until the end of the indent
6083 {
6084 cnt--;
6085 }
6086 else // reached the end of the indent, start of the part of the line to keep
6087 {
6088 insideIndent = false;
6089 *dst++ = c;
6090 }
6091 }
6092 else // part after indent, copy to the output
6093 {
6094 *dst++ = c;
6095 }
6096 break;
6097 default:
6098 insideIndent = false;
6099 *dst++ = c;
6100 break;
6101 }
6102 }
6103 doc.resize(static_cast<uint32_t>(dst-doc.data()));
6104 //printf("stripIndentationVerbatim: result=\n%s\n------\n",qPrint(doc));
6105}
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 5028 of file util.cpp.

5029{
5030 if (s.isEmpty()) return QCString();
5031 const char *p = s.data();
5032
5033 // search for leading empty lines
5034 int i=0,li=-1,l=static_cast<int>(s.length());
5035 char c = 0;
5036 while ((c=*p))
5037 {
5038 if (c==' ' || c=='\t' || c=='\r') { i++; p++; }
5039 else if (c=='\\' && literal_at(p,"\\ilinebr")) { i+=8; li=i; p+=8; }
5040 else if (c=='\n') { i++; li=i; docLine++; p++; }
5041 else break;
5042 }
5043
5044 // search for trailing empty lines
5045 int b=l-1,bi=-1;
5046 p=s.data()+b;
5047 while (b>=0)
5048 {
5049 c=*p;
5050 if (c==' ' || c=='\t' || c=='\r') { b--; p--; }
5051 else if (c=='r' && b>=7 && literal_at(p-7,"\\ilinebr")) { bi=b-7; b-=8; p-=8; }
5052 else if (c=='>' && b>=11 && literal_at(p-11,"\\ilinebr<br>")) { bi=b-11; b-=12; p-=12; }
5053 else if (c=='\n') { bi=b; b--; p--; }
5054 else break;
5055 }
5056
5057 // return whole string if no leading or trailing lines where found
5058 if (li==-1 && bi==-1) return s;
5059
5060 // return substring
5061 if (bi==-1) bi=l;
5062 if (li==-1) li=0;
5063 if (bi<=li) return QCString(); // only empty lines
5064 //printf("docLine='%s' len=%d li=%d bi=%d\n",qPrint(s),s.length(),li,bi);
5065 return s.mid(li,bi-li);
5066}

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

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

◆ stripPath()

QCString stripPath ( const QCString & s)

Definition at line 4947 of file util.cpp.

4948{
4949 QCString result=s;
4950 int i=result.findRev('/');
4951 if (i!=-1)
4952 {
4953 result=result.mid(i+1);
4954 }
4955 i=result.findRev('\\');
4956 if (i!=-1)
4957 {
4958 result=result.mid(i+1);
4959 }
4960 return result;
4961}

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

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

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

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

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

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

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

3207{
3208 return substituteKeywords(file,s,
3209 {
3210 // keyword value getter
3211 { "$title", [&]() { return !title.isEmpty() ? title : projName; } },
3212 { "$doxygenversion", [&]() { return getDoxygenVersion(); } },
3213 { "$projectname", [&]() { return projName; } },
3214 { "$projectnumber", [&]() { return projNum; } },
3215 { "$projectbrief", [&]() { return projBrief; } },
3216 { "$projectlogo", [&]() { return stripPath(projectLogoFile()); } },
3217 { "$logosize", [&]() { return projectLogoSize(); } },
3218 { "$projecticon", [&]() { return stripPath(Config_getString(PROJECT_ICON)); } },
3219 { "$langISO", [&]() { return theTranslator->trISOLang(); } },
3220 { "$showdate", [&](const QCString &fmt) { return showDate(fmt); } }
3221 });
3222}
Definition message.h:144
QCString substituteKeywords(const QCString &file, const QCString &s, const KeywordSubstitutionList &keywords)
Definition util.cpp:3053
QCString projectLogoFile()
Definition util.cpp:3139
static QCString projectLogoSize()
Definition util.cpp:3160
static QCString showDate(const QCString &fmt)
Definition util.cpp:3126

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

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

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

1295{
1296 QCString result;
1297 if (al.empty()) return result;
1298 result="<";
1299 bool first=true;
1300 for (const auto &a : al)
1301 {
1302 if (a.defval.isEmpty() || includeDefault)
1303 {
1304 if (!first) result+=", ";
1305 if (!a.name.isEmpty()) // add template argument name
1306 {
1307 if (lang==SrcLangExt::Java || lang==SrcLangExt::CSharp)
1308 {
1309 result+=a.type+" ";
1310 }
1311 result+=a.name;
1312 }
1313 else // extract name from type
1314 {
1315 int i = static_cast<int>(a.type.length())-1;
1316 while (i>=0 && isId(a.type.at(i))) i--;
1317 if (i>0)
1318 {
1319 result+=a.type.right(a.type.length()-i-1);
1320 if (a.type.find("...")!=-1)
1321 {
1322 result+="...";
1323 }
1324 }
1325 else // nothing found -> take whole name
1326 {
1327 result+=a.type;
1328 }
1329 }
1330 if (!a.typeConstraint.isEmpty() && lang==SrcLangExt::Java)
1331 {
1332 result+=" extends "; // TODO: now Java specific, C# has where...
1333 result+=a.typeConstraint;
1334 }
1335 first=false;
1336 }
1337 }
1338 result+=">";
1339 return removeRedundantWhiteSpace(result);
1340}

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

1452{
1453 const char *outputEncoding = "UTF-8";
1454 if (inputEncoding==nullptr || qstricmp(inputEncoding,outputEncoding)==0) return true;
1455 size_t inputSize=input.length();
1456 size_t outputSize=inputSize*4;
1457 QCString output(outputSize, QCString::ExplicitSize);
1458 void *cd = portable_iconv_open(outputEncoding,inputEncoding);
1459 if (cd==reinterpret_cast<void *>(-1))
1460 {
1461 return false;
1462 }
1463 bool ok=true;
1464 size_t iLeft=inputSize;
1465 size_t oLeft=outputSize;
1466 const char *inputPtr = input.data();
1467 char *outputPtr = output.rawData();
1468 if (!portable_iconv(cd, &inputPtr, &iLeft, &outputPtr, &oLeft))
1469 {
1470 outputSize-=static_cast<int>(oLeft);
1471 output.resize(outputSize);
1472 output.at(outputSize)='\0';
1473 // replace input
1474 input=output.str();
1475 //printf("iconv: input size=%d output size=%d\n[%s]\n",size,newSize,qPrint(srcBuf));
1476 }
1477 else
1478 {
1479 ok=false;
1480 }
1482 return ok;
1483}
@ 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 3415 of file util.cpp.

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

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

◆ updateColumnCount()

size_t updateColumnCount ( const char * s,
size_t col )

Definition at line 6898 of file util.cpp.

6899{
6900 if (s)
6901 {
6902 const int tabSize = Config_getInt(TAB_SIZE);
6903 char c;
6904 while ((c=*s++))
6905 {
6906 switch(c)
6907 {
6908 case '\t': col+=tabSize - (col%tabSize);
6909 break;
6910 case '\n': col=0;
6911 break;
6912 default:
6913 col++;
6914 if (c<0) // multi-byte character
6915 {
6916 int numBytes = getUTF8CharNumBytes(c);
6917 for (int i=0;i<numBytes-1 && (c=*s++);i++) {} // skip over extra chars
6918 if (c==0) return col; // end of string half way a multibyte char
6919 }
6920 break;
6921 }
6922 }
6923 }
6924 return col;
6925}

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

5105{
5106 QCString langName = language.lower();
5107 auto it1 = std::find_if(g_lang2extMap.begin(),g_lang2extMap.end(),
5108 [&langName](const auto &info) { return info.langName==langName; });
5109 if (it1 == g_lang2extMap.end()) return false;
5110
5111 // found the language
5112 SrcLangExt parserId = it1->parserId;
5113 QCString extName = extension.lower();
5114 if (extName.isEmpty()) return FALSE;
5115 if (extName.at(0)!='.') extName.prepend(".");
5116 auto it2 = g_extLookup.find(extName.str());
5117 if (it2!=g_extLookup.end())
5118 {
5119 g_extLookup.erase(it2); // language was already register for this ext
5120 }
5121 //printf("registering extension %s\n",qPrint(extName));
5122 g_extLookup.emplace(extName.str(),parserId);
5123 if (!Doxygen::parserManager->registerExtension(extName,it1->parserName))
5124 {
5125 err("Failed to assign extension {} to parser {} for language {}\n",
5126 extName.data(),it1->parserName,language);
5127 }
5128 else
5129 {
5130 //msg("Registered extension {} to language parser {}...\n",
5131 // extName,language);
5132 }
5133 return TRUE;
5134}
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 5800 of file util.cpp.

5801{
5802 int hue = Config_getInt(HTML_COLORSTYLE_HUE);
5803 int sat = Config_getInt(HTML_COLORSTYLE_SAT);
5804 int gamma = Config_getInt(HTML_COLORSTYLE_GAMMA);
5805 while (data->name)
5806 {
5807 QCString fileName = dir+"/"+data->name;
5808 ColoredImage img(data->width,data->height,data->content,data->alpha,
5809 sat,hue,gamma);
5810 if (!img.save(fileName))
5811 {
5812 fprintf(stderr,"Warning: Cannot open file %s for writing\n",data->name);
5813 }
5814 Doxygen::indexList->addImageFile(data->name);
5815 data++;
5816 }
5817}
Class representing a bitmap image colored based on hue/sat/gamma settings.
Definition image.h:56
static IndexList * indexList
Definition doxygen.h:131
const unsigned char * content
Definition util.h:470
unsigned short height
Definition util.h:469
const unsigned char * alpha
Definition util.h:471
unsigned short width
Definition util.h:468
const char * name
Definition util.h:467

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

1176{
1177 auto replaceFunc = [&list,&ol](size_t entryIndex)
1178 {
1179 const auto &e = list[entryIndex];
1180 ol.pushGeneratorState();
1184 // link for Html / man
1185 //printf("writeObjectLink(file=%s)\n",qPrint(e->file));
1186 ol.writeObjectLink(QCString(),e.file,e.anchor,e.name);
1187 ol.popGeneratorState();
1188
1189 ol.pushGeneratorState();
1192 // link for Latex / pdf with anchor because the sources
1193 // are not hyperlinked (not possible with a verbatim environment).
1194 ol.writeObjectLink(QCString(),e.file,QCString(),e.name);
1195 ol.popGeneratorState();
1196 };
1197
1198 writeMarkerList(ol, theTranslator->trWriteList(static_cast<int>(list.size())).str(), list.size(), replaceFunc);
1199
1200 ol.writeString(".");
1201}
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:1124

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

6978{
6979 uint8_t md5_sig[16];
6980 char sigStr[33];
6981 MD5Buffer(content.data(),static_cast<unsigned int>(content.length()),md5_sig);
6982 MD5SigToString(md5_sig,sigStr);
6983
6984 QCString fileName = baseName + sigStr + extension;
6985 { // ==== start atomic section
6986 std::lock_guard lock(writeFileContents_lock);
6987 auto it=writeFileContents_set.find(fileName.str());
6988 exists = it!=writeFileContents_set.end();
6989 if (!exists)
6990 {
6991 writeFileContents_set.insert(fileName.str());
6992 if (auto file = Portable::openOutputStream(fileName); file.is_open())
6993 {
6994 file.write( content.data(), content.length() );
6995 file.close();
6996 }
6997 else
6998 {
6999 err("Could not open file {} for writing\n",fileName);
7000 return QCString();
7001 }
7002 }
7003 } // ==== end atomic section
7004 return fileName;
7005}
static std::mutex writeFileContents_lock
Definition util.cpp:6966

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

1149{
1150 QCString result;
1151 static const reg::Ex marker(R"(@(\d+))");
1152 reg::Iterator it(markerText,marker);
1154 size_t index=0;
1155 for ( ; it!=end ; ++it)
1156 {
1157 const auto &match = *it;
1158 size_t newIndex = match.position();
1159 size_t matchLen = match.length();
1160 result += markerText.substr(index,newIndex-index);
1161 unsigned long entryIndex = std::stoul(match[1].str());
1162 if (entryIndex<static_cast<unsigned long>(numMarkers))
1163 {
1164 result+=replaceFunc(entryIndex);
1165 }
1166 index=newIndex+matchLen;
1167 }
1168 if (index<markerText.size())
1169 {
1170 result += markerText.substr(index);
1171 }
1172 return result;
1173}

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

1126{
1127 static const reg::Ex marker(R"(@(\d+))");
1128 reg::Iterator it(markerText,marker);
1130 size_t index=0;
1131 for ( ; it!=end ; ++it)
1132 {
1133 const auto &match = *it;
1134 size_t newIndex = match.position();
1135 size_t matchLen = match.length();
1136 ol.parseText(markerText.substr(index,newIndex-index));
1137 unsigned long entryIndex = std::stoul(match[1].str());
1138 if (entryIndex<static_cast<unsigned long>(numMarkers))
1139 {
1140 replaceFunc(entryIndex);
1141 }
1142 index=newIndex+matchLen;
1143 }
1144 ol.parseText(markerText.substr(index));
1145}
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 5457 of file util.cpp.

5458{
5459 if (al.empty()) return;
5460 ol.startConstraintList(theTranslator->trTypeConstraints());
5461 for (const Argument &a : al)
5462 {
5464 ol.parseText(a.name);
5465 ol.endConstraintParam();
5467 linkifyText(TextGeneratorOLImpl(ol),a.type,LinkifyTextOptions().setScope(d));
5468 ol.endConstraintType();
5470 ol.generateDoc(d->docFile(),
5471 d->docLine(),
5472 d,
5473 nullptr,
5474 a.docs,
5475 DocOptions()
5476 .setIndexWords(true));
5477 ol.endConstraintDocs();
5478 }
5479 ol.endConstraintList();
5480}
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 QCString &text, const LinkifyTextOptions &options)
Definition util.cpp:893

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().