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

A bunch of utility functions. More...

#include <memory>
#include <unordered_map>
#include <algorithm>
#include <functional>
#include <fstream>
#include <variant>
#include <string_view>
#include <ctype.h>
#include "types.h"
#include "docparser.h"
#include "containers.h"
#include "outputgen.h"
#include "regex.h"
#include "conceptdef.h"
#include "construct.h"
Include dependency graph for util.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

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

Typedefs

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

Functions

QCString langToString (SrcLangExt lang)
 Returns a string representation of lang.
QCString getLanguageSpecificSeparator (SrcLangExt lang, bool classScope=FALSE)
 Returns the scope separator to use given the programming language lang.
void linkifyText (const TextGeneratorIntf &ol, const Definition *scope, const FileDef *fileScope, const Definition *self, const QCString &text, bool autoBreak=FALSE, bool external=TRUE, bool keepSpaces=FALSE, int indentLevel=0)
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 247 of file util.h.

◆ SelectionBlockList

using SelectionBlockList = std::vector<SelectionBlock>

Definition at line 181 of file util.h.

Function Documentation

◆ addCodeOnlyMappings()

void addCodeOnlyMappings ( )

Definition at line 5185 of file util.cpp.

5186{
5187 updateLanguageMapping(".xml", "xml");
5188 updateLanguageMapping(".sql", "sql");
5189}
bool updateLanguageMapping(const QCString &extension, const QCString &language)
Definition util.cpp:5086

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

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

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

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

◆ addMembersToMemberGroup()

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

Definition at line 4078 of file util.cpp.

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

4808{
4809 //printf("addRefItem(sli=%d,key=%s,prefix=%s,name=%s,title=%s,args=%s)\n",(int)sli.size(),key,prefix,name,title,args);
4810 if (!key.isEmpty() && key[0]!='@') // check for @ to skip anonymous stuff (see bug427012)
4811 {
4812 for (RefItem *item : sli)
4813 {
4814 item->setPrefix(prefix);
4815 item->setScope(scope);
4816 item->setName(name);
4817 item->setTitle(title);
4818 item->setArgs(args);
4819 item->setGroup(key);
4820 }
4821 }
4822}
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 4675 of file util.cpp.

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

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

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

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

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

◆ checkBlocks()

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

Definition at line 6522 of file util.cpp.

6523{
6524 if (s.isEmpty()) return;
6525
6526 const char *p = s.data();
6527 char c = 0;
6528 while ((c=*p))
6529 {
6530 if (c==markerInfo.markerChar) // potential start of marker
6531 {
6532 if (qstrncmp(p,markerInfo.beginStr,markerInfo.beginLen)==0) // start of begin marker
6533 {
6534 size_t len = markerInfo.beginLen;
6535 bool negate = *(p+len)=='!';
6536 if (negate) len++;
6537 p += len;
6538 QCString marker;
6539 while (*p)
6540 {
6541 if (markerInfo.closeLen==0 && *p=='\n') // matching end of line
6542 {
6543 warn(fileName,-1,"Remaining begin replacement with marker '{}'",marker);
6544 break;
6545 }
6546 else if (markerInfo.closeLen!= 0 && qstrncmp(p,markerInfo.closeStr,markerInfo.closeLen)==0) // matching marker closing
6547 {
6548 p += markerInfo.closeLen;
6549 warn(fileName,-1,"Remaining begin replacement with marker '{}'",marker);
6550 break;
6551 }
6552 marker += *p;
6553 p++;
6554 }
6555 }
6556 else if (qstrncmp(p,markerInfo.endStr,markerInfo.endLen)==0) // start of end marker
6557 {
6558 size_t len = markerInfo.endLen;
6559 bool negate = *(p+len)=='!';
6560 if (negate) len++;
6561 p += len;
6562 QCString marker;
6563 while (*p)
6564 {
6565 if (markerInfo.closeLen==0 && *p=='\n') // matching end of line
6566 {
6567 warn(fileName,-1,"Remaining end replacement with marker '{}'",marker);
6568 break;
6569 }
6570 else if (markerInfo.closeLen!= 0 && qstrncmp(p,markerInfo.closeStr,markerInfo.closeLen)==0) // matching marker closing
6571 {
6572 p += markerInfo.closeLen;
6573 warn(fileName,-1,"Remaining end replacement with marker '{}'",marker);
6574 break;
6575 }
6576 marker += *p;
6577 p++;
6578 }
6579 }
6580 }
6581 p++;
6582 }
6583}
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:187
const char * closeStr
Definition util.h:190
const char * beginStr
Definition util.h:186
size_t closeLen
Definition util.h:191
const char * endStr
Definition util.h:188

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

4898{
4899 return fName.right(ext.length())==ext;
4900}

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

5296{
5297 MemberDef *bestMatch = getMemberFromSymbol(scope,fileScope,n);
5298
5299 if (bestMatch && bestMatch->isTypedef())
5300 return TRUE; // closest matching symbol is a typedef
5301 else
5302 return FALSE;
5303}
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:5243

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

Referenced by isVarWithConstructor().

◆ cleanupInlineGraph()

void cleanupInlineGraph ( )

Definition at line 6990 of file util.cpp.

6991{
6992 if (Config_getBool(DOT_CLEANUP))
6993 {
6994 for (const auto& fileName: writeFileContents_set)
6995 {
6996 Dir().remove(qPrint(fileName));
6997 }
6998 }
6999}
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:6949

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

Referenced by generateOutput().

◆ clearSubDirs()

void clearSubDirs ( const Dir & d)

Definition at line 3648 of file util.cpp.

3649{
3650 if (Config_getBool(CREATE_SUBDIRS))
3651 {
3652 // remove empty subdirectories
3653 int createSubdirsLevelPow2 = 1 << Config_getInt(CREATE_SUBDIRS_LEVEL);
3654 for (int l1=0;l1<16;l1++)
3655 {
3656 QCString subdir;
3657 subdir.sprintf("d%x",l1);
3658 for (int l2=0; l2 < createSubdirsLevelPow2; l2++)
3659 {
3660 QCString subsubdir;
3661 subsubdir.sprintf("d%x/d%02x",l1,l2);
3662 if (d.exists(subsubdir.str()) && d.isEmpty(subsubdir.str()))
3663 {
3664 d.rmdir(subsubdir.str());
3665 }
3666 }
3667 if (d.exists(subdir.str()) && d.isEmpty(subdir.str()))
3668 {
3669 d.rmdir(subdir.str());
3670 }
3671 }
3672 }
3673}
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 6824 of file util.cpp.

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

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

4952{
4953 if (str.isEmpty() || word==nullptr) return false;
4954 static const reg::Ex re(R"(\a+)");
4955 std::string s = str.str();
4956 for (reg::Iterator it(s,re) ; it!=reg::Iterator() ; ++it)
4957 {
4958 if (it->str()==word) return true;
4959 }
4960 return false;
4961}
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 4028 of file util.cpp.

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

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

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

◆ convertFileNameFortranParserCode()

FortranFormat convertFileNameFortranParserCode ( QCString fn)

Definition at line 6396 of file util.cpp.

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

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

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

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(), generateXMLForRequirement(), ModuleDefImpl::getOutputFileBase(), DocParser::handleAHref(), PageDefImpl::PageDefImpl(), CCodeParser::parseCode(), FortranCodeParser::parseCode(), VHDLCodeParser::parseCode(), RefList::RefList(), FileDefImpl::setDiskNameLocal(), and NamespaceDefImpl::setFileNameLocal().

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

6235{
6236 bool extractPrivate = Config_getBool(EXTRACT_PRIVATE);
6237
6238 // default representing 1-1 mapping
6239 *outListType1=inListType;
6240 *outListType2=MemberListType::Invalid();
6241
6242 if (inProt==Protection::Public)
6243 {
6244 if (inListType.isPrivate())
6245 {
6246 *outListType1=MemberListType::Invalid();
6247 }
6248 }
6249 else if (inProt==Protection::Protected)
6250 {
6251 if (inListType.isPrivate() || inListType.isPublic())
6252 {
6253 *outListType1=MemberListType::Invalid();
6254 }
6255 else if (inListType.isProtected())
6256 {
6257 *outListType2=inListType.toPublic();
6258 }
6259 }
6260 else if (inProt==Protection::Private)
6261 {
6262 if (inListType.isPublic() || inListType.isProtected())
6263 {
6264 *outListType1=MemberListType::Invalid();
6265 }
6266 else if (inListType.isPrivate())
6267 {
6268 if (extractPrivate)
6269 {
6270 *outListType1=inListType.toPublic();
6271 *outListType2=inListType.toProtected();
6272 }
6273 else
6274 {
6275 *outListType1=MemberListType::Invalid();
6276 }
6277 }
6278 }
6279
6280 //printf("convertProtectionLevel(type=%s prot=%d): %s,%s\n",
6281 // qPrint(inListType.to_string()),inProt,qPrint(outListType1->to_string()),qPrint(outListType2->to_string()));
6282}
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 3944 of file util.cpp.

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

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

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

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

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

◆ convertToJSString()

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

Definition at line 4004 of file util.cpp.

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

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

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

◆ convertToXML()

QCString convertToXML ( const QCString & s,
bool keepEntities )

Converts a string to an XML-encoded string

Definition at line 3893 of file util.cpp.

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

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

Referenced by DocSets::addContentsItem(), EclipseHelp::addContentsItem(), Qhp::addFile(), Sitemap::addIndexFile(), Qhp::addIndexItem(), XmlDocVisitor::filter(), generateXMLForClass(), generateXMLForConcept(), generateXMLForDir(), generateXMLForFile(), generateXMLForGroup(), generateXMLForMember(), generateXMLForModule(), generateXMLForNamespace(), generateXMLForPage(), generateXMLForRequirement(), generateXMLSection(), DotDirDeps::getImgAltText(), EclipseHelp::initialize(), Qhp::initialize(), XmlDocVisitor::operator()(), XmlDocVisitor::operator()(), HtmlAttribList::toString(), QhpSectionTree::traverse(), visitPreStart(), SearchIndexExternal::write(), FileDefImpl::writeClassesToTagFile(), NamespaceDefImpl::writeClassesToTagFile(), NamespaceDefImpl::writeConceptsToTagFile(), DefinitionImpl::writeDocAnchorsToTagFile(), DotNode::writeDocbook(), DotGraph::writeGraphHeader(), writeInnerClasses(), writeInnerConcepts(), writeInnerDirs(), writeInnerFiles(), writeInnerGroups(), writeInnerModules(), writeInnerNamespaces(), writeInnerPages(), writeJavascriptSearchData(), writeJavasScriptSearchDataPage(), DotNode::writeLabel(), writeListOfAllMembers(), writeMapArea(), writeMemberReference(), 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 5857 of file util.cpp.

5858{
5859 if (!Dir().copy(src.str(),dest.str()))
5860 {
5861 err("could not copy file {} to {}\n",src,dest);
5862 return false;
5863 }
5864 return true;
5865}
#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 3886 of file util.cpp.

3887{
3888 if (s.isEmpty()) return s;
3889 return "a" + s;
3890}

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

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

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

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

◆ createHtmlUrl()

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

Definition at line 5716 of file util.cpp.

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

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

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

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

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

Referenced by ClassDefImpl::className().

◆ detab()

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

Definition at line 6720 of file util.cpp.

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

◆ determineAbsoluteIncludeName()

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

Definition at line 3581 of file util.cpp.

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

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

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

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

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

5754{
5755 QCString result;
5756 if (!ref.isEmpty())
5757 {
5758 auto it = Doxygen::tagDestinationMap.find(ref.str());
5760 {
5761 result = it->second;
5762 size_t l = result.length();
5763 if (!relPath.isEmpty() && l>0 && result.at(0)=='.')
5764 { // relative path -> prepend relPath.
5765 result.prepend(relPath);
5766 l+=relPath.length();
5767 }
5768 if (l>0 && result.at(l-1)!='/') result+='/';
5769 if (!href) result.append("\" ");
5770 }
5771 }
5772 else
5773 {
5774 result = relPath;
5775 }
5776 return result;
5777}
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 6934 of file util.cpp.

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

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

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

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

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

Referenced by inlineArgListToDoc().

◆ extractEndRawStringDelimiter()

QCString extractEndRawStringDelimiter ( const char * rawEnd)

Definition at line 6942 of file util.cpp.

6943{
6944 QCString text=rawEnd;
6945 return text.mid(1,text.length()-2); // text=)xyz" -> delimiter=xyz
6946}

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

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

1472{
1473 if (name.isEmpty()) return QCString();
1474 bool fileOpened=false;
1475 if (name[0]=='-' && name[1]==0) // read from stdin
1476 {
1477 std::string contents;
1478 std::string line;
1479 while (getline(std::cin,line))
1480 {
1481 contents+=line+'\n';
1482 }
1483 return contents;
1484 }
1485 else // read from file
1486 {
1487 FileInfo fi(name.str());
1488 if (!fi.exists() || !fi.isFile())
1489 {
1490 err("file '{}' not found\n",name);
1491 return "";
1492 }
1493 std::string buf;
1494 fileOpened=readInputFile(name,buf,filter,isSourceCode);
1495 if (fileOpened)
1496 {
1497 addTerminalCharIfMissing(buf,'\n');
1498 return buf;
1499 }
1500 }
1501 if (!fileOpened)
1502 {
1503 err("cannot open file '{}' for reading\n",name);
1504 }
1505 return "";
1506}
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:5530

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

6090{
6091 bool allExternals = Config_getBool(ALLEXTERNALS);
6092 bool isDocFile = fd->isDocumentationFile();
6093 genSourceFile = !isDocFile && fd->generateSourceFile();
6094 return ( ((allExternals && fd->isLinkable()) ||
6096 ) &&
6097 !isDocFile
6098 );
6099}
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 5610 of file util.cpp.

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

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

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

◆ findAndRemoveWord()

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

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

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

Definition at line 4967 of file util.cpp.

4968{
4969 static reg::Ex re(R"(\s*(<\a+>)\s*)");
4970 std::string s = sentence.str();
4971 reg::Iterator it(s,re);
4973 std::string result;
4974 bool found=false;
4975 size_t p=0;
4976 for ( ; it!=end ; ++it)
4977 {
4978 const auto match = *it;
4979 std::string part = match[1].str();
4980 if (part!=word)
4981 {
4982 size_t i = match.position();
4983 size_t l = match.length();
4984 result+=s.substr(p,i-p);
4985 result+=match.str();
4986 p=i+l;
4987 }
4988 else
4989 {
4990 found=true;
4991 size_t i = match[1].position();
4992 size_t l = match[1].length();
4993 result+=s.substr(p,i-p);
4994 p=i+l;
4995 }
4996 }
4997 result+=s.substr(p);
4998 sentence = QCString(result).simplifyWhiteSpace();
4999 return found;
5000}
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 2871 of file util.cpp.

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

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

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

◆ findFilePath()

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

Definition at line 2956 of file util.cpp.

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

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

6663{
6665 return reg::search(s,match,re) ? static_cast<int>(match.position()) : -1;
6666}
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 6654 of file util.cpp.

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

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

◆ fixSpaces()

QCString fixSpaces ( const QCString & s)
inline

Definition at line 473 of file util.h.

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

References substitute().

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

◆ generateAnonymousAnchor()

QCString generateAnonymousAnchor ( const QCString & fileName,
int count )

Definition at line 3539 of file util.cpp.

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

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

◆ generateFileRef()

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

Definition at line 2843 of file util.cpp.

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

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

◆ generateMarker()

QCString generateMarker ( int id)

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

Definition at line 280 of file util.cpp.

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

References qsnprintf.

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

◆ getCaseSenseNames()

bool getCaseSenseNames ( )

Definition at line 3301 of file util.cpp.

3302{
3303 auto caseSenseNames = Config_getEnum(CASE_SENSE_NAMES);
3304
3305 if (caseSenseNames == CASE_SENSE_NAMES_t::YES) return true;
3306 else if (caseSenseNames == CASE_SENSE_NAMES_t::NO) return false;
3308}
#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 2275 of file util.cpp.

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

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

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

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

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

◆ getEncoding()

QCString getEncoding ( const FileInfo & fi)

Definition at line 5691 of file util.cpp.

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

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

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

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

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

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

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

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

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

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

◆ getOverloadDocs()

QCString getOverloadDocs ( )

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

Definition at line 4070 of file util.cpp.

4071{
4072 return theTranslator->trOverloadText();
4073 //"This is an overloaded member function, "
4074 // "provided for convenience. It differs from the above "
4075 // "function only in what argument(s) it accepts.";
4076}
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 3212 of file util.cpp.

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

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

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

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

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

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

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

◆ guessSection()

EntryType guessSection ( const QCString & name)

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

Definition at line 339 of file util.cpp.

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

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

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

◆ initDefaultExtensionMapping()

void initDefaultExtensionMapping ( )

Definition at line 5118 of file util.cpp.

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

References updateLanguageMapping().

Referenced by initDoxygen().

◆ inlineArgListToDoc()

QCString inlineArgListToDoc ( const ArgumentList & al)

Definition at line 1186 of file util.cpp.

1187{
1188 QCString paramDocs;
1189 if (al.hasDocumentation())
1190 {
1191 for (const Argument &a : al)
1192 {
1193 if (a.hasDocumentation())
1194 {
1195 QCString docsWithoutDir = a.docs;
1196 QCString direction = extractDirection(docsWithoutDir);
1197 paramDocs+=" \\ilinebr @param"+direction+" "+a.name+" "+docsWithoutDir;
1198 }
1199 }
1200 }
1201 return paramDocs;
1202}
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:6178

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

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

◆ inlineTemplateArgListToDoc()

QCString inlineTemplateArgListToDoc ( const ArgumentList & al)

Definition at line 1204 of file util.cpp.

1205{
1206 QCString paramDocs;
1207 if (al.hasTemplateDocumentation())
1208 {
1209 for (const Argument &a : al)
1210 {
1211 if (!a.docs.isEmpty())
1212 {
1213 if (!a.name.isEmpty())
1214 {
1215 paramDocs+=" \\ilinebr @tparam "+a.name+" "+a.docs;
1216 }
1217 else if (!a.type.isEmpty())
1218 {
1219 QCString type = a.type;
1220 type.stripPrefix("class ");
1221 type.stripPrefix("typename ");
1222 type = type.stripWhiteSpace();
1223 paramDocs+=" \\ilinebr @tparam "+type+" "+a.docs;
1224 }
1225 }
1226 }
1227 }
1228 return paramDocs;
1229}
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 3727 of file util.cpp.

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

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

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

◆ integerToRoman()

QCString integerToRoman ( int n,
bool upper = true )

Definition at line 6698 of file util.cpp.

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

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

◆ isId()

◆ isIdJS()

bool isIdJS ( int c)
inline

Definition at line 211 of file util.h.

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

Referenced by SearchTerm::termEncoded().

◆ isURL()

bool isURL ( const QCString & url)

Checks whether the given url starts with a supported protocol.

Definition at line 5913 of file util.cpp.

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

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

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

◆ join()

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

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

Definition at line 6669 of file util.cpp.

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

◆ langToString()

QCString langToString ( SrcLangExt lang)

Returns a string representation of lang.

Definition at line 5891 of file util.cpp.

5892{
5893 return to_string(lang);
5894}
static constexpr const char * to_string(Protection prot) noexcept
Definition types.h:38

References to_string().

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

◆ leftScopeMatch()

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

Definition at line 882 of file util.cpp.

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

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

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

◆ lineBlock()

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

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

See also
routine extractBlock

Definition at line 5870 of file util.cpp.

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

References QCString::find().

◆ linkifyText()

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

Definition at line 894 of file util.cpp.

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

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

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

◆ linkToText()

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

Definition at line 2675 of file util.cpp.

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

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

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

References Doxygen::mainPage.

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

◆ makeBaseName()

◆ mangleCSharpGenericName()

QCString mangleCSharpGenericName ( const QCString & name)

Definition at line 6913 of file util.cpp.

6914{
6915 int idx = name.find('<');
6916 if (idx!=-1)
6917 {
6918 return name.left(idx)+"-"+QCString().setNum(name.contains(",")+1)+"-g";
6919 }
6920 return name;
6921}
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 1998 of file util.cpp.

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

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

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

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

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

6862{
6863 if (Config_getBool(CALL_GRAPH) !=md1->hasCallGraph()) md2->overrideCallGraph(md1->hasCallGraph());
6864 if (Config_getBool(CALLER_GRAPH)!=md1->hasCallerGraph()) md2->overrideCallerGraph(md1->hasCallerGraph());
6865 if (Config_getBool(CALL_GRAPH) !=md2->hasCallGraph()) md1->overrideCallGraph( md2->hasCallGraph());
6866 if (Config_getBool(CALLER_GRAPH)!=md2->hasCallerGraph()) md1->overrideCallerGraph(md2->hasCallerGraph());
6867
6868 if (Config_getBool(SHOW_ENUM_VALUES) !=md1->hasEnumValues()) md2->overrideEnumValues(md1->hasEnumValues());
6869 if (Config_getBool(SHOW_ENUM_VALUES) !=md2->hasEnumValues()) md1->overrideEnumValues( md2->hasEnumValues());
6870
6871 if (Config_getBool(REFERENCED_BY_RELATION)!=md1->hasReferencedByRelation()) md2->overrideReferencedByRelation(md1->hasReferencedByRelation());
6872 if (Config_getBool(REFERENCES_RELATION) !=md1->hasReferencesRelation()) md2->overrideReferencesRelation(md1->hasReferencesRelation());
6873 if (Config_getBool(REFERENCED_BY_RELATION)!=md2->hasReferencedByRelation()) md1->overrideReferencedByRelation(md2->hasReferencedByRelation());
6874 if (Config_getBool(REFERENCES_RELATION) !=md2->hasReferencesRelation()) md1->overrideReferencesRelation(md2->hasReferencesRelation());
6875
6876 if (Config_getBool(INLINE_SOURCES)!=md1->hasInlineSource()) md2->overrideInlineSource(md1->hasInlineSource());
6877 if (Config_getBool(INLINE_SOURCES)!=md2->hasInlineSource()) md1->overrideInlineSource(md2->hasInlineSource());
6878}
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 4575 of file util.cpp.

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

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

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

◆ nextUtf8CharPosition()

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

◆ normalizeNonTemplateArgumentsInString()

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

Definition at line 4281 of file util.cpp.

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

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

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

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

◆ parseCommentAsHtml()

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

Definition at line 5405 of file util.cpp.

5406{
5407 std::lock_guard lock(g_docCacheMutex);
5408 auto it = g_docCache.find(doc.str());
5409 if (it != g_docCache.end())
5410 {
5411 //printf("Cache: [%s]->[%s]\n",qPrint(doc),qPrint(it->second));
5412 return it->second;
5413 }
5414 auto parser { createDocParser() };
5415 auto ast { validatingParseTitle(*parser.get(),fileName,lineNr,doc) };
5416 auto astImpl = dynamic_cast<const DocNodeAST*>(ast.get());
5417 QCString result;
5418 if (astImpl)
5419 {
5420 TextStream t;
5421 OutputCodeList codeList;
5422 codeList.add<HtmlCodeGenerator>(&t);
5423 HtmlDocVisitor visitor(t,codeList,scope,fileName);
5424 std::visit(visitor,astImpl->root);
5425 result = t.str();
5426 }
5427 else // fallback, should not happen
5428 {
5429 result = filterTitle(doc);
5430 }
5431 //printf("Conversion: [%s]->[%s]\n",qPrint(doc),qPrint(result));
5432 g_docCache.insert(std::make_pair(doc.str(),result));
5433 return result;
5434}
Class representing the abstract syntax tree of a documentation block.
Definition docnode.h:1464
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:5403
QCString filterTitle(const QCString &title)
Definition util.cpp:5610
static std::mutex g_docCacheMutex
Definition util.cpp:5402

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

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

◆ parseCommentAsText()

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

Definition at line 5349 of file util.cpp.

5351{
5352 if (doc.isEmpty()) return "";
5353 //printf("parseCommentAsText(%s)\n",qPrint(doc));
5354 TextStream t;
5355 auto parser { createDocParser() };
5356 auto ast { validatingParseDoc(*parser.get(),
5357 fileName,
5358 lineNr,
5359 scope,
5360 md,
5361 doc,
5362 DocOptions()
5363 .setAutolinkSupport(false))
5364 };
5365 auto astImpl = dynamic_cast<const DocNodeAST*>(ast.get());
5366 if (astImpl)
5367 {
5368 TextDocVisitor visitor(t);
5369 std::visit(visitor,astImpl->root);
5370 }
5372 int i=0;
5373 int charCnt=0;
5374 int l=static_cast<int>(result.length());
5375 while ((i=nextUTF8CharPosition(result,l,i))<l)
5376 {
5377 charCnt++;
5378 if (charCnt>=80) break;
5379 }
5380 if (charCnt>=80) // try to truncate the string
5381 {
5382 while ((i=nextUTF8CharPosition(result,l,i))<l && charCnt<100)
5383 {
5384 charCnt++;
5385 if (result.at(i)==',' ||
5386 result.at(i)=='.' ||
5387 result.at(i)=='!' ||
5388 result.at(i)=='?' ||
5389 result.at(i)=='}') // good for UTF-16 characters and } otherwise also a good point to stop the string
5390 {
5391 i++; // we want to be "behind" last inspected character
5392 break;
5393 }
5394 }
5395 }
5396 if ( i < l) result=result.left(i)+"...";
5397 return result.data();
5398}
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:5305

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

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

◆ patternMatch()

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

Definition at line 5684 of file util.cpp.

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

References genericPatternMatch().

Referenced by readDir().

◆ processMarkup()

QCString processMarkup ( const QCString & s)

◆ projectLogoFile()

QCString projectLogoFile ( )

Definition at line 3121 of file util.cpp.

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

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

Referenced by copyLogo(), and substituteKeywords().

◆ protectionLevelVisible()

bool protectionLevelVisible ( Protection prot)

Definition at line 5937 of file util.cpp.

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

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

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

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

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

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

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

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

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

◆ removeAnonymousScopes()

QCString removeAnonymousScopes ( const QCString & str)

Removes all anonymous scopes from string s Possible examples:

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

Definition at line 162 of file util.cpp.

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

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

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

◆ removeEmptyLines()

QCString removeEmptyLines ( const QCString & s)

Definition at line 6586 of file util.cpp.

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

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

Referenced by substituteHtmlKeywords(), and substituteLatexKeywords().

◆ removeLongPathMarker()

QCString removeLongPathMarker ( QCString path)

Definition at line 288 of file util.cpp.

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

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

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

◆ removeRedundantWhiteSpace()

QCString removeRedundantWhiteSpace ( const QCString & s)

Definition at line 568 of file util.cpp.

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

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

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

◆ replaceAnonymousScopes()

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

Definition at line 219 of file util.cpp.

220{
221 if (s.isEmpty()) return s;
222 static const reg::Ex marker(R"(@\d+)");
223 std::string result = reg::replace(s.str(),marker,
224 !replacement.isEmpty() ? replacement.data() : "__anonymous__");
225 //printf("replaceAnonymousScopes('%s')='%s'\n",qPrint(s),qPrint(result));
226 return result;
227}
std::string replace(std::string_view str, const Ex &re, std::string_view replacement)
Searching in a given input string for parts that match regular expression re and replaces those parts...
Definition regex.cpp:866

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

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

◆ replaceColorMarkers()

QCString replaceColorMarkers ( const QCString & str)

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

Definition at line 5806 of file util.cpp.

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

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

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

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

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

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

◆ resolveTypeDef()

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

Definition at line 374 of file util.cpp.

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

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

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

◆ rightScopeMatch()

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

Definition at line 871 of file util.cpp.

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

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

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

◆ selectBlocks()

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

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

Definition at line 6409 of file util.cpp.

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

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

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

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

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

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

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

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

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

◆ stripAnonymousNamespaceScope()

QCString stripAnonymousNamespaceScope ( const QCString & s)

Definition at line 231 of file util.cpp.

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

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

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

◆ stripExtension()

◆ stripExtensionGeneral()

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

◆ stripFromIncludePath()

QCString stripFromIncludePath ( const QCString & path)

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

Definition at line 330 of file util.cpp.

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

References Config_getList, and stripFromPath().

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

◆ stripFromPath()

QCString stripFromPath ( const QCString & path)

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

Definition at line 322 of file util.cpp.

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

References Config_getList, and stripFromPath().

◆ stripIndentation()

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

Definition at line 5949 of file util.cpp.

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

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

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

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

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

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

◆ stripPath()

QCString stripPath ( const QCString & s)

Definition at line 4929 of file util.cpp.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

◆ updateColumnCount()

size_t updateColumnCount ( const char * s,
size_t col )

Definition at line 6880 of file util.cpp.

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

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

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

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

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

1158{
1159 auto replaceFunc = [&list,&ol](size_t entryIndex)
1160 {
1161 const auto &e = list[entryIndex];
1162 ol.pushGeneratorState();
1166 // link for Html / man
1167 //printf("writeObjectLink(file=%s)\n",qPrint(e->file));
1168 ol.writeObjectLink(QCString(),e.file,e.anchor,e.name);
1169 ol.popGeneratorState();
1170
1171 ol.pushGeneratorState();
1174 // link for Latex / pdf with anchor because the sources
1175 // are not hyperlinked (not possible with a verbatim environment).
1176 ol.writeObjectLink(QCString(),e.file,QCString(),e.name);
1177 ol.popGeneratorState();
1178 };
1179
1180 writeMarkerList(ol, theTranslator->trWriteList(static_cast<int>(list.size())).str(), list.size(), replaceFunc);
1181
1182 ol.writeString(".");
1183}
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:1106

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

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

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

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

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

1108{
1109 static const reg::Ex marker(R"(@(\d+))");
1110 reg::Iterator it(markerText,marker);
1112 size_t index=0;
1113 for ( ; it!=end ; ++it)
1114 {
1115 const auto &match = *it;
1116 size_t newIndex = match.position();
1117 size_t matchLen = match.length();
1118 ol.parseText(markerText.substr(index,newIndex-index));
1119 unsigned long entryIndex = std::stoul(match[1].str());
1120 if (entryIndex<static_cast<unsigned long>(numMarkers))
1121 {
1122 replaceFunc(entryIndex);
1123 }
1124 index=newIndex+matchLen;
1125 }
1126 ol.parseText(markerText.substr(index));
1127}
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 5439 of file util.cpp.

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

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

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