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 ArgumentList *srcAl, const Definition *dstScope, const FileDef *dstFileScope, 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)
 
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)
 
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)
 
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)
 
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)
 
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)
 

Detailed Description

A bunch of utility functions.

Definition in file util.h.

Typedef Documentation

◆ KeywordSubstitutionList

Definition at line 248 of file util.h.

◆ SelectionBlockList

using SelectionBlockList = std::vector<SelectionBlock>

Definition at line 182 of file util.h.

Function Documentation

◆ addCodeOnlyMappings()

void addCodeOnlyMappings ( )

Definition at line 5708 of file util.cpp.

5709{
5710 updateLanguageMapping(".xml", "xml");
5711 updateLanguageMapping(".sql", "sql");
5712}
bool updateLanguageMapping(const QCString &extension, const QCString &language)
Definition util.cpp:5609

References updateLanguageMapping().

Referenced by generateOutput().

◆ addDirPrefix()

void addDirPrefix ( QCString & fileName)

References word.

◆ addGroupListToTitle()

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

◆ addHtmlExtensionIfMissing()

void addHtmlExtensionIfMissing ( QCString & fName)

Definition at line 5408 of file util.cpp.

5409{
5410 if (fName.isEmpty()) return;
5411 int i_fs = fName.findRev('/');
5412 int i_bs = fName.findRev('\\');
5413 int i = fName.find('.',std::max({ i_fs, i_bs ,0})); // search for . after path part
5414 if (i==-1)
5415 {
5417 }
5418}
static QCString htmlFileExtension
Definition doxygen.h:122
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:150
int findRev(char c, int index=-1, bool cs=TRUE) const
Definition qcstring.cpp:91

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(), VhdlDocGen::writeTagFile(), DocSets::writeToken(), HtmlCodeGenerator::writeTooltip(), and DotNode::writeUrl().

◆ addMembersToMemberGroup()

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

Definition at line 4603 of file util.cpp.

4606{
4607 ASSERT(context!=nullptr);
4608 //printf("addMemberToMemberGroup() context=%s\n",qPrint(context->name()));
4609 if (ml==nullptr) return;
4610
4611 struct MoveMemberInfo
4612 {
4613 MoveMemberInfo(MemberDef *md,MemberGroup *mg,const RefItemVector &rv)
4614 : memberDef(md), memberGroup(mg), sli(rv) {}
4615 MemberDef *memberDef;
4616 MemberGroup *memberGroup;
4617 RefItemVector sli;
4618 };
4619 std::vector<MoveMemberInfo> movedMembers;
4620
4621 for (const auto &md : *ml)
4622 {
4623 if (md->isEnumerate()) // insert enum value of this enum into groups
4624 {
4625 for (const auto &fmd : md->enumFieldList())
4626 {
4627 int groupId=fmd->getMemberGroupId();
4628 if (groupId!=-1)
4629 {
4630 auto it = Doxygen::memberGroupInfoMap.find(groupId);
4632 {
4633 const auto &info = it->second;
4634 auto mg_it = std::find_if(pMemberGroups->begin(),
4635 pMemberGroups->end(),
4636 [&groupId](const auto &g)
4637 { return g->groupId()==groupId; }
4638 );
4639 MemberGroup *mg_ptr = nullptr;
4640 if (mg_it==pMemberGroups->end())
4641 {
4642 auto mg = std::make_unique<MemberGroup>(
4643 context,
4644 groupId,
4645 info->header,
4646 info->doc,
4647 info->docFile,
4648 info->docLine,
4649 ml->container());
4650 mg_ptr = mg.get();
4651 pMemberGroups->push_back(std::move(mg));
4652 }
4653 else
4654 {
4655 mg_ptr = (*mg_it).get();
4656 }
4657 mg_ptr->insertMember(fmd); // insert in member group
4659 if (fmdm)
4660 {
4661 fmdm->setMemberGroup(mg_ptr);
4662 }
4663 }
4664 }
4665 }
4666 }
4667 int groupId=md->getMemberGroupId();
4668 if (groupId!=-1)
4669 {
4670 auto it = Doxygen::memberGroupInfoMap.find(groupId);
4672 {
4673 const auto &info = it->second;
4674 auto mg_it = std::find_if(pMemberGroups->begin(),
4675 pMemberGroups->end(),
4676 [&groupId](const auto &g)
4677 { return g->groupId()==groupId; }
4678 );
4679 MemberGroup *mg_ptr = nullptr;
4680 if (mg_it==pMemberGroups->end())
4681 {
4682 auto mg = std::make_unique<MemberGroup>(
4683 context,
4684 groupId,
4685 info->header,
4686 info->doc,
4687 info->docFile,
4688 info->docLine,
4689 ml->container());
4690 mg_ptr = mg.get();
4691 pMemberGroups->push_back(std::move(mg));
4692 }
4693 else
4694 {
4695 mg_ptr = (*mg_it).get();
4696 }
4697 movedMembers.emplace_back(md,mg_ptr,info->m_sli);
4698 }
4699 }
4700 }
4701
4702 // move the members to their group
4703 for (const auto &mmi : movedMembers)
4704 {
4705 ml->remove(mmi.memberDef); // remove from member list
4706 mmi.memberGroup->insertMember(mmi.memberDef->resolveAlias()); // insert in member group
4707 mmi.memberGroup->setRefItems(mmi.sli);
4708 MemberDefMutable *rmdm = toMemberDefMutable(mmi.memberDef);
4709 if (rmdm)
4710 {
4711 rmdm->setMemberGroup(mmi.memberGroup);
4712 }
4713 }
4714}
static MemberGroupInfoMap memberGroupInfoMap
Definition doxygen.h:118
virtual void setMemberGroup(MemberGroup *grp)=0
A class representing a group of members.
Definition membergroup.h:43
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 5311 of file util.cpp.

5314{
5315 //printf("addRefItem(sli=%d,key=%s,prefix=%s,name=%s,title=%s,args=%s)\n",(int)sli.size(),key,prefix,name,title,args);
5316 if (!key.isEmpty() && key[0]!='@') // check for @ to skip anonymous stuff (see bug427012)
5317 {
5318 for (RefItem *item : sli)
5319 {
5320 item->setPrefix(prefix);
5321 item->setScope(scope);
5322 item->setName(name);
5323 item->setTitle(title);
5324 item->setArgs(args);
5325 item->setGroup(key);
5326 }
5327 }
5328}
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(), addListReferences(), ClassDefImpl::addListReferences(), FileDefImpl::addListReferences(), GroupDefImpl::addListReferences(), ModuleDefImpl::addListReferences(), NamespaceDefImpl::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 5181 of file util.cpp.

5192{
5193 PageDef *pd=nullptr;
5194 //printf("addRelatedPage(name=%s gd=%p)\n",qPrint(name),gd);
5195 QCString title=ptitle.stripWhiteSpace();
5196 bool newPage = true;
5197 if ((pd=Doxygen::pageLinkedMap->find(name)) && !pd->isReference())
5198 {
5199 if (!xref && !title.isEmpty() && pd->title()!=pd->name() && pd->title()!=title)
5200 {
5201 warn(fileName,startLine,"multiple use of page label '{}' with different titles, (other occurrence: {}, line: {})",
5202 name,pd->docFile(),pd->getStartBodyLine());
5203 }
5204 if (!title.isEmpty() && pd->title()==pd->name()) // pd has no real title yet
5205 {
5206 pd->setTitle(title);
5208 if (si)
5209 {
5210 si->setTitle(title);
5211 }
5212 }
5213 // append documentation block to the page.
5214 pd->setDocumentation(doc,fileName,docLine);
5215 //printf("Adding page docs '%s' pi=%p name=%s\n",qPrint(doc),pd,name);
5216 // append (x)refitems to the page.
5217 pd->setRefItems(sli);
5218 newPage = false;
5219 }
5220
5221 if (newPage) // new page
5222 {
5223 QCString baseName=name;
5224 if (baseName.endsWith(".tex"))
5225 baseName=baseName.left(baseName.length()-4);
5226 else if (baseName.right(Doxygen::htmlFileExtension.length())==Doxygen::htmlFileExtension)
5227 baseName=baseName.left(baseName.length()-Doxygen::htmlFileExtension.length());
5228
5229 //printf("Appending page '%s'\n",qPrint(baseName));
5230 if (pd) // replace existing page
5231 {
5232 pd->setDocumentation(doc,fileName,docLine);
5234 pd->setShowLineNo(FALSE);
5235 pd->setNestingLevel(0);
5236 pd->setPageScope(nullptr);
5237 pd->setTitle(title);
5238 pd->setReference(QCString());
5239 }
5240 else // newPage
5241 {
5242 pd = Doxygen::pageLinkedMap->add(baseName,
5243 createPageDef(fileName,docLine,baseName,doc,title));
5244 }
5245 pd->setBodySegment(startLine,startLine,-1);
5246
5247 pd->setRefItems(sli);
5248 pd->setLanguage(lang);
5249
5250 if (tagInfo)
5251 {
5252 pd->setReference(tagInfo->tagName);
5253 pd->setFileName(tagInfo->fileName);
5254 }
5255
5256 if (gd) gd->addPage(pd);
5257
5258 if (pd->hasTitle())
5259 {
5260 //outputList->writeTitle(pi->name,pi->title);
5261
5262 // a page name is a label as well!
5263 QCString file;
5264 QCString orgFile;
5265 int line = -1;
5266 if (gd)
5267 {
5268 file=gd->getOutputFileBase();
5269 orgFile=gd->getOutputFileBase();
5270 }
5271 else
5272 {
5273 file=pd->getOutputFileBase();
5274 orgFile=pd->docFile();
5275 line = pd->getStartBodyLine();
5276 }
5277 const SectionInfo *si = SectionManager::instance().find(pd->name());
5278 if (si)
5279 {
5280 if (!si->ref().isEmpty()) // we are from a tag file
5281 {
5283 file,-1,pd->title(),SectionType::Page,0,pd->getReference());
5284 }
5285 else if (si->lineNr() != -1)
5286 {
5287 warn(orgFile,line,"multiple use of section label '{}', (first occurrence: {}, line {})",pd->name(),si->fileName(),si->lineNr());
5288 }
5289 else
5290 {
5291 warn(orgFile,line,"multiple use of section label '{}', (first occurrence: {})",pd->name(),si->fileName());
5292 }
5293 }
5294 else
5295 {
5297 file,-1,pd->title(),SectionType::Page,0,pd->getReference());
5298 //printf("si->label='%s' si->definition=%s si->fileName='%s'\n",
5299 // qPrint(si->label),si->definition?si->definition->name().data():"<none>",
5300 // qPrint(si->fileName));
5301 //printf(" SectionInfo: sec=%p sec->fileName=%s\n",si,qPrint(si->fileName));
5302 //printf("Adding section key=%s si->fileName=%s\n",qPrint(pageName),qPrint(si->fileName));
5303 }
5304 }
5305 }
5306 return pd;
5307}
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:100
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:153
bool endsWith(const char *s) const
Definition qcstring.h:509
QCString stripWhiteSpace() const
returns a copy of this string with leading and trailing whitespace removed
Definition qcstring.h:245
QCString right(size_t len) const
Definition qcstring.h:219
QCString left(size_t len) const
Definition qcstring.h:214
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:154
SectionInfo * add(const SectionInfo &si)
Definition section.h:138
static SectionManager & instance()
returns a reference to the singleton
Definition section.h:175
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:79
#define FALSE
Definition qcstring.h:34
QCString fileName
Definition entry.h:105
QCString tagName
Definition entry.h:104
QCString convertNameToFile(const QCString &name, bool allowDots, bool allowUnderscore)
Definition util.cpp:4013

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

1202{
1203 QCString result;
1204 if (!al.hasParameters()) return result;
1205 result+="(";
1206 for (auto it = al.begin() ; it!=al.end() ;)
1207 {
1208 Argument a = *it;
1209 QCString type1 = useCanonicalType && !a.canType.isEmpty() ? a.canType : a.type;
1210 QCString type2;
1211 int i=type1.find(")("); // hack to deal with function pointers
1212 if (i!=-1)
1213 {
1214 type2=type1.mid(i);
1215 type1=type1.left(i);
1216 }
1217 if (!a.attrib.isEmpty())
1218 {
1219 result+=a.attrib+" ";
1220 }
1221 if (!a.name.isEmpty() || !a.array.isEmpty())
1222 {
1223 result+= type1+" "+a.name+type2+a.array;
1224 }
1225 else
1226 {
1227 result+= type1+type2;
1228 }
1229 if (!a.defval.isEmpty() && showDefVals)
1230 {
1231 result+="="+a.defval;
1232 }
1233 ++it;
1234 if (it!=al.end()) result+=", ";
1235 }
1236 result+=")";
1237 if (al.constSpecifier()) result+=" const";
1238 if (al.volatileSpecifier()) result+=" volatile";
1239 if (al.refQualifier()==RefQualifierType::LValue) result+=" &";
1240 else if (al.refQualifier()==RefQualifierType::RValue) result+=" &&";
1241 if (!al.trailingReturnType().isEmpty()) result+=al.trailingReturnType();
1242 if (al.pureSpecifier()) result+=" =0";
1243 return removeRedundantWhiteSpace(result);
1244}
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:226
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:578

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

6999{
7000 if (s.isEmpty()) return;
7001
7002 const char *p = s.data();
7003 char c = 0;
7004 while ((c=*p))
7005 {
7006 if (c==markerInfo.markerChar) // potential start of marker
7007 {
7008 if (qstrncmp(p,markerInfo.beginStr,markerInfo.beginLen)==0) // start of begin marker
7009 {
7010 size_t len = markerInfo.beginLen;
7011 bool negate = *(p+len)=='!';
7012 if (negate) len++;
7013 p += len;
7014 QCString marker;
7015 while (*p)
7016 {
7017 if (markerInfo.closeLen==0 && *p=='\n') // matching end of line
7018 {
7019 warn(fileName,-1,"Remaining begin replacement with marker '{}'",marker);
7020 break;
7021 }
7022 else if (markerInfo.closeLen!= 0 && qstrncmp(p,markerInfo.closeStr,markerInfo.closeLen)==0) // matching marker closing
7023 {
7024 p += markerInfo.closeLen;
7025 warn(fileName,-1,"Remaining begin replacement with marker '{}'",marker);
7026 break;
7027 }
7028 marker += *p;
7029 p++;
7030 }
7031 }
7032 else if (qstrncmp(p,markerInfo.endStr,markerInfo.endLen)==0) // start of end marker
7033 {
7034 size_t len = markerInfo.endLen;
7035 bool negate = *(p+len)=='!';
7036 if (negate) len++;
7037 p += len;
7038 QCString marker;
7039 while (*p)
7040 {
7041 if (markerInfo.closeLen==0 && *p=='\n') // matching end of line
7042 {
7043 warn(fileName,-1,"Remaining end replacement with marker '{}'",marker);
7044 break;
7045 }
7046 else if (markerInfo.closeLen!= 0 && qstrncmp(p,markerInfo.closeStr,markerInfo.closeLen)==0) // matching marker closing
7047 {
7048 p += markerInfo.closeLen;
7049 warn(fileName,-1,"Remaining end replacement with marker '{}'",marker);
7050 break;
7051 }
7052 marker += *p;
7053 p++;
7054 }
7055 }
7056 }
7057 p++;
7058 }
7059}
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:159
int qstrncmp(const char *str1, const char *str2, size_t len)
Definition qcstring.h:75
size_t beginLen
Definition util.h:188
const char * closeStr
Definition util.h:191
const char * beginStr
Definition util.h:187
size_t closeLen
Definition util.h:192
const char * endStr
Definition util.h:189

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

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

◆ checkExtension()

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

Definition at line 5403 of file util.cpp.

5404{
5405 return fName.right(ext.length())==ext;
5406}

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

5819{
5820 MemberDef *bestMatch = getMemberFromSymbol(scope,fileScope,n);
5821
5822 if (bestMatch && bestMatch->isTypedef())
5823 return TRUE; // closest matching symbol is a typedef
5824 else
5825 return FALSE;
5826}
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:5766

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

Referenced by isVarWithConstructor().

◆ clearSubDirs()

void clearSubDirs ( const Dir & d)

Definition at line 4176 of file util.cpp.

4177{
4178 if (Config_getBool(CREATE_SUBDIRS))
4179 {
4180 // remove empty subdirectories
4181 int createSubdirsLevelPow2 = 1 << Config_getInt(CREATE_SUBDIRS_LEVEL);
4182 for (int l1=0;l1<16;l1++)
4183 {
4184 QCString subdir;
4185 subdir.sprintf("d%x",l1);
4186 for (int l2=0; l2 < createSubdirsLevelPow2; l2++)
4187 {
4188 QCString subsubdir;
4189 subsubdir.sprintf("d%x/d%02x",l1,l2);
4190 if (d.exists(subsubdir.str()) && d.isEmpty(subsubdir.str()))
4191 {
4192 d.rmdir(subsubdir.str());
4193 }
4194 }
4195 if (d.exists(subdir.str()) && d.isEmpty(subdir.str()))
4196 {
4197 d.rmdir(subdir.str());
4198 }
4199 }
4200 }
4201}
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:537
QCString & sprintf(const char *format,...)
Definition qcstring.cpp:29
#define Config_getInt(name)
Definition config.h:34
#define Config_getBool(name)
Definition config.h:33

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

7301{
7302 int l = static_cast<int>(name.length());
7303 int lastSepPos = -1;
7304 const char *p = name.data();
7305 int i=l-2;
7306 int sharpCount=0;
7307 // --- begin optimized version of ts=name.findRev(">::");
7308 int ts = -1;
7309 while (i>=0)
7310 {
7311 if (p[i]=='>')
7312 {
7313 if (sharpCount==0 && p[i+1]==':' && p[i+2]==':')
7314 {
7315 ts=i;
7316 break;
7317 }
7318 sharpCount++;
7319 }
7320 else if (p[i]=='<')
7321 {
7322 sharpCount--;
7323 }
7324 i--;
7325 }
7326 // --- end optimized version
7327 if (ts==-1) ts=0; else p+=++ts;
7328 for (i=ts;i<l-1;i++)
7329 {
7330 char c=*p++;
7331 if (c==':' && *p==':') lastSepPos=i;
7332 if (c=='<') break;
7333 }
7334 return lastSepPos;
7335}

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

5475{
5476 if (str.isEmpty() || word==nullptr) return false;
5477 static const reg::Ex re(R"(\a+)");
5478 std::string s = str.str();
5479 for (reg::Iterator it(s,re) ; it!=reg::Iterator() ; ++it)
5480 {
5481 if (it->str()==word) return true;
5482 }
5483 return false;
5484}
Class representing a regular expression.
Definition regex.h:39
Iterator class to iterator through matches.
Definition regex.h:232
std::string_view word
Definition util.cpp:980

References QCString::isEmpty(), QCString::str(), reg::Match::str(), and word.

◆ convertCharEntitiesToUTF8()

QCString convertCharEntitiesToUTF8 ( const QCString & s)

Definition at line 4553 of file util.cpp.

4554{
4555 if (str.isEmpty()) return QCString();
4556
4557 std::string s = str.data();
4558 static const reg::Ex re(R"(&\a\w*;)");
4559 reg::Iterator it(s,re);
4561
4562 GrowBuf growBuf;
4563 size_t p=0, i=0, l=0;
4564 for (; it!=end ; ++it)
4565 {
4566 const auto &match = *it;
4567 p = match.position();
4568 l = match.length();
4569 if (p>i)
4570 {
4571 growBuf.addStr(s.substr(i,p-i));
4572 }
4573 QCString entity(match.str());
4575 const char *code=nullptr;
4576 if (symType!=HtmlEntityMapper::Sym_Unknown && (code=HtmlEntityMapper::instance().utf8(symType)))
4577 {
4578 growBuf.addStr(code);
4579 }
4580 else
4581 {
4582 growBuf.addStr(entity);
4583 }
4584 i=p+l;
4585 }
4586 growBuf.addStr(s.substr(i));
4587 growBuf.addChar(0);
4588 //printf("convertCharEntitiesToUTF8(%s)->%s\n",qPrint(s),growBuf.get());
4589 return growBuf.get();
4590}
Class representing a string buffer optimized for growing.
Definition growbuf.h:28
void addChar(char c)
Definition growbuf.h:69
void addStr(const QCString &s)
Definition growbuf.h:72
char * get()
Definition growbuf.h:114
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.
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:759

References GrowBuf::addChar(), GrowBuf::addStr(), QCString::data(), end(), GrowBuf::get(), HtmlEntityMapper::instance(), QCString::isEmpty(), HtmlEntityMapper::name2sym(), and HtmlEntityMapper::Sym_Unknown.

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

◆ convertFileNameFortranParserCode()

FortranFormat convertFileNameFortranParserCode ( QCString fn)

Definition at line 6872 of file util.cpp.

6873{
6875 QCString parserName = Doxygen::parserManager->getParserName(ext);
6876
6877 if (parserName == "fortranfixed") return FortranFormat::Fixed;
6878 else if (parserName == "fortranfree") return FortranFormat::Free;
6879
6881}
static ParserManager * parserManager
Definition doxygen.h:131
QCString getFileNameExtension(const QCString &fn)
Definition util.cpp:5756

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

Referenced by convertCppComments().

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

4014{
4015 if (name.isEmpty()) return name;
4016 bool shortNames = Config_getBool(SHORT_NAMES);
4017 bool createSubdirs = Config_getBool(CREATE_SUBDIRS);
4018 QCString result;
4019 if (shortNames) // use short names only
4020 {
4021 std::lock_guard<std::mutex> lock(g_usedNamesMutex);
4022 auto kv = g_usedNames.find(name.str());
4023 uint32_t num=0;
4024 if (kv!=g_usedNames.end())
4025 {
4026 num = kv->second;
4027 }
4028 else
4029 {
4030 num = g_usedNamesCount;
4031 g_usedNames.emplace(name.str(),g_usedNamesCount++);
4032 }
4033 result.sprintf("a%05d",num);
4034 }
4035 else // long names
4036 {
4037 result=escapeCharsInString(name,allowDots,allowUnderscore);
4038 size_t resultLen = result.length();
4039 if (resultLen>=128) // prevent names that cannot be created!
4040 {
4041 // third algorithm based on MD5 hash
4042 uint8_t md5_sig[16];
4043 char sigStr[33];
4044 MD5Buffer(result.data(),static_cast<unsigned int>(resultLen),md5_sig);
4045 MD5SigToString(md5_sig,sigStr);
4046 result=result.left(128-32)+sigStr;
4047 }
4048 }
4049 if (createSubdirs)
4050 {
4051 int l1Dir=0,l2Dir=0;
4052 int createSubdirsLevel = Config_getInt(CREATE_SUBDIRS_LEVEL);
4053 int createSubdirsBitmaskL2 = (1<<createSubdirsLevel)-1;
4054
4055 // compute md5 hash to determine sub directory to use
4056 uint8_t md5_sig[16];
4057 MD5Buffer(result.data(),static_cast<unsigned int>(result.length()),md5_sig);
4058 l1Dir = md5_sig[14] & 0xf;
4059 l2Dir = md5_sig[15] & createSubdirsBitmaskL2;
4060
4061 result.prepend(QCString().sprintf("d%x/d%02x/",l1Dir,l2Dir));
4062 }
4063 //printf("*** convertNameToFile(%s)->%s\n",qPrint(name),qPrint(result));
4064 return result;
4065}
QCString & prepend(const char *s)
Definition qcstring.h:407
static int g_usedNamesCount
Definition util.cpp:4005
QCString escapeCharsInString(const QCString &name, bool allowDots, bool allowUnderscore)
Definition util.cpp:3839
static std::mutex g_usedNamesMutex
Definition util.cpp:4004
static std::unordered_map< std::string, int > g_usedNames
Definition util.cpp:4003

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

Referenced by addRelatedPage(), buildExampleList(), ClassDefImpl::ClassDefImpl(), ClassDefImpl::deepCopy(), DocAnchor::DocAnchor(), DocCite::DocCite(), ModuleDefImpl::getOutputFileBase(), DocParser::handleAHref(), PageDefImpl::PageDefImpl(), CCodeParser::parseCode(), FortranCodeParser::parseCode(), VHDLCodeParser::parseCode(), RefList::RefList(), FileDefImpl::setDiskNameLocal(), 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 6705 of file util.cpp.

6711{
6712 bool extractPrivate = Config_getBool(EXTRACT_PRIVATE);
6713
6714 // default representing 1-1 mapping
6715 *outListType1=inListType;
6716 *outListType2=MemberListType::Invalid();
6717
6718 if (inProt==Protection::Public)
6719 {
6720 if (inListType.isPrivate())
6721 {
6722 *outListType1=MemberListType::Invalid();
6723 }
6724 }
6725 else if (inProt==Protection::Protected)
6726 {
6727 if (inListType.isPrivate() || inListType.isPublic())
6728 {
6729 *outListType1=MemberListType::Invalid();
6730 }
6731 else if (inListType.isProtected())
6732 {
6733 *outListType2=inListType.toPublic();
6734 }
6735 }
6736 else if (inProt==Protection::Private)
6737 {
6738 if (inListType.isPublic() || inListType.isProtected())
6739 {
6740 *outListType1=MemberListType::Invalid();
6741 }
6742 else if (inListType.isPrivate())
6743 {
6744 if (extractPrivate)
6745 {
6746 *outListType1=inListType.toPublic();
6747 *outListType2=inListType.toProtected();
6748 }
6749 else
6750 {
6751 *outListType1=MemberListType::Invalid();
6752 }
6753 }
6754 }
6755
6756 //printf("convertProtectionLevel(type=%s prot=%d): %s,%s\n",
6757 // qPrint(inListType.to_string()),inProt,qPrint(outListType1->to_string()),qPrint(outListType2->to_string()));
6758}
constexpr bool isProtected() const
Definition types.h:380
MemberListType toProtected() const
Definition types.h:438
MemberListType toPublic() const
Definition types.h:426
static MemberListType Invalid()
Definition types.h:371
constexpr bool isPrivate() const
Definition types.h:382
ML_TYPES constexpr bool isPublic() const
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 4472 of file util.cpp.

4473{
4474 if (s.isEmpty()) return s;
4475 GrowBuf growBuf;
4476 const char *p=s.data();
4477 char c = 0;
4478 while ((c=*p++))
4479 {
4480 switch (c)
4481 {
4482 case '<': growBuf.addStr("&lt;"); break;
4483 case '>': growBuf.addStr("&gt;"); break;
4484 case '&': if (keepEntities)
4485 {
4486 const char *e=p;
4487 char ce = 0;
4488 while ((ce=*e++))
4489 {
4490 if (ce==';' || (!(isId(ce) || ce=='#'))) break;
4491 }
4492 if (ce==';') // found end of an entity
4493 {
4494 // copy entry verbatim
4495 growBuf.addChar(c);
4496 while (p<e) growBuf.addChar(*p++);
4497 }
4498 else
4499 {
4500 growBuf.addStr("&amp;");
4501 }
4502 }
4503 else
4504 {
4505 growBuf.addStr("&amp;");
4506 }
4507 break;
4508 case '\'': growBuf.addStr("&#39;"); break;
4509 case '"': growBuf.addStr("&quot;"); break;
4510 default:
4511 {
4512 uint8_t uc = static_cast<uint8_t>(c);
4513 if (uc<32 && !isspace(c))
4514 {
4515 growBuf.addStr("&#x24");
4516 growBuf.addChar(hex[uc>>4]);
4517 growBuf.addChar(hex[uc&0xF]);
4518 growBuf.addChar(';');
4519 }
4520 else
4521 {
4522 growBuf.addChar(c);
4523 }
4524 }
4525 break;
4526 }
4527 }
4528 growBuf.addChar(0);
4529 return growBuf.get();
4530}
static constexpr auto hex
bool isId(int c)
Definition util.h:208

References GrowBuf::addChar(), GrowBuf::addStr(), QCString::data(), GrowBuf::get(), hex, QCString::isEmpty(), and isId().

Referenced by HtmlCodeGenerator::_writeCodeLink(), HtmlHelp::addContentsItem(), convertToHtmlAndTruncate(), FTVHelp::Private::generateLink(), DefinitionImpl::navigationPathAsString(), HtmlDocVisitor::operator()(), HtmlDocVisitor::operator()(), HtmlDocVisitor::operator()(), HtmlGenerator::startFile(), HtmlDocVisitor::startLink(), substituteHtmlKeywords(), HtmlHelpIndex::writeFields(), HtmlGenerator::writeInheritedSectionTitle(), HtmlGenerator::writeLocalToc(), 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 4381 of file util.cpp.

4382{
4383 if (s.isEmpty()) return s;
4384 GrowBuf growBuf;
4385 const char *p = s.data();
4386 char c = 0;
4387 bool first = true;
4388 while ((c=*p++))
4389 {
4390 char encChar[4];
4391 if ((c>='0' && c<='9') || (c>='a' && c<='z') || (c>='A' && c<='Z') || c=='-' || c==':' || c=='.')
4392 { // any permissive character except _
4393 if (first && c>='0' && c<='9') growBuf.addChar('a'); // don't start with a digit
4394 growBuf.addChar(c);
4395 }
4396 else
4397 {
4398 encChar[0]='_';
4399 encChar[1]=hex[static_cast<unsigned char>(c)>>4];
4400 encChar[2]=hex[static_cast<unsigned char>(c)&0xF];
4401 encChar[3]=0;
4402 growBuf.addStr(encChar);
4403 }
4404 first=FALSE;
4405 }
4406 growBuf.addChar(0);
4407 return growBuf.get();
4408}

References GrowBuf::addChar(), GrowBuf::addStr(), QCString::data(), FALSE, GrowBuf::get(), hex, and QCString::isEmpty().

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

◆ convertToJSString()

QCString convertToJSString ( const QCString & s)

Definition at line 4532 of file util.cpp.

4533{
4534 if (s.isEmpty()) return s;
4535 GrowBuf growBuf;
4536 const char *p=s.data();
4537 char c = 0;
4538 while ((c=*p++))
4539 {
4540 switch (c)
4541 {
4542 case '"': growBuf.addStr("\\\""); break;
4543 case '\\': if (*p=='u' && *(p+1)=='{') growBuf.addStr("\\");
4544 else growBuf.addStr("\\\\");
4545 break;
4546 default: growBuf.addChar(c); break;
4547 }
4548 }
4549 growBuf.addChar(0);
4550 return convertCharEntitiesToUTF8(growBuf.get());
4551}
QCString convertCharEntitiesToUTF8(const QCString &str)
Definition util.cpp:4553

References GrowBuf::addChar(), GrowBuf::addStr(), convertCharEntitiesToUTF8(), QCString::data(), GrowBuf::get(), and QCString::isEmpty().

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

◆ convertToXML()

QCString convertToXML ( const QCString & s,
bool keepEntities )

Converts a string to an XML-encoded string

Definition at line 4421 of file util.cpp.

4422{
4423 if (s.isEmpty()) return s;
4424 GrowBuf growBuf;
4425 const char *p = s.data();
4426 char c = 0;
4427 while ((c=*p++))
4428 {
4429 switch (c)
4430 {
4431 case '<': growBuf.addStr("&lt;"); break;
4432 case '>': growBuf.addStr("&gt;"); break;
4433 case '&': if (keepEntities)
4434 {
4435 const char *e=p;
4436 char ce = 0;
4437 while ((ce=*e++))
4438 {
4439 if (ce==';' || (!(isId(ce) || ce=='#'))) break;
4440 }
4441 if (ce==';') // found end of an entity
4442 {
4443 // copy entry verbatim
4444 growBuf.addChar(c);
4445 while (p<e) growBuf.addChar(*p++);
4446 }
4447 else
4448 {
4449 growBuf.addStr("&amp;");
4450 }
4451 }
4452 else
4453 {
4454 growBuf.addStr("&amp;");
4455 }
4456 break;
4457 case '\'': growBuf.addStr("&apos;"); break;
4458 case '"': growBuf.addStr("&quot;"); break;
4459 case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8:
4460 case 11: case 12: case 13: case 14: case 15: case 16: case 17: case 18:
4461 case 19: case 20: case 21: case 22: case 23: case 24: case 25: case 26:
4462 case 27: case 28: case 29: case 30: case 31:
4463 break; // skip invalid XML characters (see http://www.w3.org/TR/2000/REC-xml-20001006#NT-Char)
4464 default: growBuf.addChar(c); break;
4465 }
4466 }
4467 growBuf.addChar(0);
4468 return growBuf.get();
4469}

References GrowBuf::addChar(), GrowBuf::addStr(), QCString::data(), GrowBuf::get(), QCString::isEmpty(), and isId().

Referenced by DocSets::addContentsItem(), EclipseHelp::addContentsItem(), Qhp::addFile(), Sitemap::addIndexFile(), Qhp::addIndexItem(), XmlDocVisitor::filter(), generateXMLForClass(), generateXMLForConcept(), generateXMLForDir(), generateXMLForFile(), generateXMLForGroup(), generateXMLForMember(), generateXMLForModule(), generateXMLForNamespace(), generateXMLForPage(), 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(), VhdlDocGen::writeTagFile(), writeTemplateArgumentList(), DocSets::writeToken(), DotNode::writeXML(), writeXMLLink(), and writeXMLString().

◆ copyFile()

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

4415{
4416 if (s.isEmpty()) return s;
4417 return "a" + s;
4418}

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

6404{
6405 QCString result = url;
6406 if (!relPath.isEmpty() && !isURL(url))
6407 {
6408 result.prepend(relPath);
6409 }
6410 return result;
6411}
bool isURL(const QCString &url)
Checks whether the given url starts with a supported protocol.
Definition util.cpp:6391

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

6204{
6205 QCString url;
6206 if (!ref.isEmpty())
6207 {
6208 url = externalRef(relPath,ref,href);
6209 }
6210 if (!targetFileName.isEmpty())
6211 {
6212 QCString fn = targetFileName;
6213 if (ref.isEmpty())
6214 {
6215 if (!anchor.isEmpty() && isLocalFile)
6216 {
6217 fn=""; // omit file name for local links
6218 }
6219 else
6220 {
6221 url = relPath;
6222 }
6223 }
6224 url+=fn;
6225 }
6226 if (!anchor.isEmpty()) url+="#"+anchor;
6227 //printf("createHtmlUrl(relPath=%s,local=%d,target=%s,anchor=%s)=%s\n",qPrint(relPath),isLocalFile,qPrint(targetFileName),qPrint(anchor),qPrint(url));
6228 return url;
6229}
QCString externalRef(const QCString &relPath, const QCString &ref, bool href)
Definition util.cpp:6231

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

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

◆ createSubDirs()

void createSubDirs ( const Dir & d)

Definition at line 4149 of file util.cpp.

4150{
4151 if (Config_getBool(CREATE_SUBDIRS))
4152 {
4153 // create up to 4096 subdirectories
4154 int createSubdirsLevelPow2 = 1 << Config_getInt(CREATE_SUBDIRS_LEVEL);
4155 for (int l1=0; l1<16; l1++)
4156 {
4157 QCString subdir;
4158 subdir.sprintf("d%x",l1);
4159 if (!d.exists(subdir.str()) && !d.mkdir(subdir.str()))
4160 {
4161 term("Failed to create output directory '{}'\n",subdir);
4162 }
4163 for (int l2=0; l2<createSubdirsLevelPow2; l2++)
4164 {
4165 QCString subsubdir;
4166 subsubdir.sprintf("d%x/d%02x",l1,l2);
4167 if (!d.exists(subsubdir.str()) && !d.mkdir(subsubdir.str()))
4168 {
4169 term("Failed to create output directory '{}'\n",subsubdir);
4170 }
4171 }
4172 }
4173 }
4174}
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 7399 of file util.cpp.

7400{
7401 QCString result=name;
7402 if (result.endsWith("-g"))
7403 {
7404 int idx = result.find('-');
7405 result = result.left(idx)+templArgs;
7406 }
7407 return result;
7408}

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

Referenced by ClassDefImpl::className().

◆ detab()

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

Definition at line 7196 of file util.cpp.

7197{
7198 int tabSize = Config_getInt(TAB_SIZE);
7199 size_t size = s.length();
7200 GrowBuf out(size);
7201 const char *data = s.data();
7202 size_t i=0;
7203 int col=0;
7204 constexpr auto doxy_nbsp = "&_doxy_nbsp;"; // doxygen escape command for UTF-8 nbsp
7205 const int maxIndent=1000000; // value representing infinity
7206 int minIndent=maxIndent;
7207 bool skip = false;
7208 while (i<size)
7209 {
7210 char c = data[i++];
7211 switch(c)
7212 {
7213 case '\t': // expand tab
7214 {
7215 int stop = tabSize - (col%tabSize);
7216 //printf("expand at %d stop=%d\n",col,stop);
7217 col+=stop;
7218 while (stop--) out.addChar(' ');
7219 }
7220 break;
7221 case '\\':
7222 if (data[i] == '\\') // escaped command -> ignore
7223 {
7224 out.addChar(c);
7225 out.addChar(data[i++]);
7226 col+=2;
7227 }
7228 else if (i+5<size && literal_at(data+i,"iskip")) // \iskip command
7229 {
7230 i+=5;
7231 skip = true;
7232 }
7233 else if (i+8<size && literal_at(data+i,"endiskip")) // \endiskip command
7234 {
7235 i+=8;
7236 skip = false;
7237 }
7238 else // some other command
7239 {
7240 out.addChar(c);
7241 col++;
7242 }
7243 break;
7244 case '\n': // reset column counter
7245 out.addChar(c);
7246 col=0;
7247 break;
7248 case ' ': // increment column counter
7249 out.addChar(c);
7250 col++;
7251 break;
7252 default: // non-whitespace => update minIndent
7253 if (c<0 && i<size) // multibyte sequence
7254 {
7255 // special handling of the UTF-8 nbsp character 0xC2 0xA0
7256 int nb = isUTF8NonBreakableSpace(data);
7257 if (nb>0)
7258 {
7259 out.addStr(doxy_nbsp);
7260 i+=nb-1;
7261 }
7262 else
7263 {
7264 int bytes = getUTF8CharNumBytes(c);
7265 for (int j=0;j<bytes-1 && c;j++)
7266 {
7267 out.addChar(c);
7268 c = data[i++];
7269 }
7270 out.addChar(c);
7271 }
7272 }
7273 else
7274 {
7275 out.addChar(c);
7276 }
7277 if (!skip && col<minIndent) minIndent=col;
7278 col++;
7279 }
7280 }
7281 if (minIndent!=maxIndent) refIndent=minIndent; else refIndent=0;
7282 out.addChar(0);
7283 //printf("detab(\n%s\n)=[\n%s\n]\n",qPrint(s),qPrint(out.get()));
7284 return out.get();
7285}
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 GrowBuf::addChar(), GrowBuf::addStr(), Config_getInt, QCString::data(), GrowBuf::get(), getUTF8CharNumBytes(), isUTF8NonBreakableSpace(), QCString::length(), and literal_at().

Referenced by Markdown::process().

◆ determineAbsoluteIncludeName()

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

Definition at line 4109 of file util.cpp.

4110{
4111 bool searchIncludes = Config_getBool(SEARCH_INCLUDES);
4112 QCString absIncFileName = incFileName;
4113 FileInfo fi(curFile.str());
4114 if (fi.exists())
4115 {
4116 QCString absName = QCString(fi.dirPath(TRUE))+"/"+incFileName;
4117 FileInfo fi2(absName.str());
4118 if (fi2.exists())
4119 {
4120 absIncFileName=fi2.absFilePath();
4121 }
4122 else if (searchIncludes) // search in INCLUDE_PATH as well
4123 {
4124 const StringVector &includePath = Config_getList(INCLUDE_PATH);
4125 for (const auto &incPath : includePath)
4126 {
4127 FileInfo fi3(incPath);
4128 if (fi3.exists() && fi3.isDir())
4129 {
4130 absName = QCString(fi3.absFilePath())+"/"+incFileName;
4131 //printf("trying absName=%s\n",qPrint(absName));
4132 FileInfo fi4(absName.str());
4133 if (fi4.exists())
4134 {
4135 absIncFileName=fi4.absFilePath();
4136 break;
4137 }
4138 //printf( "absIncFileName = %s\n", qPrint(absIncFileName) );
4139 }
4140 }
4141 }
4142 //printf( "absIncFileName = %s\n", qPrint(absIncFileName) );
4143 }
4144 return absIncFileName;
4145}
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 readIncludeFile(), and ModuleManager::resolveImports().

◆ escapeCharsInString()

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

Definition at line 3839 of file util.cpp.

3840{
3841 if (name.isEmpty()) return name;
3842 bool caseSenseNames = getCaseSenseNames();
3843 bool allowUnicodeNames = Config_getBool(ALLOW_UNICODE_NAMES);
3844 GrowBuf growBuf;
3845 signed char c = 0;
3846 const char *p=name.data();
3847 while ((c=*p++)!=0)
3848 {
3849 switch(c)
3850 {
3851 case '_': if (allowUnderscore) growBuf.addChar('_'); else growBuf.addStr("__"); break;
3852 case '-': growBuf.addChar('-'); break;
3853 case ':': growBuf.addStr("_1"); break;
3854 case '/': growBuf.addStr("_2"); break;
3855 case '<': growBuf.addStr("_3"); break;
3856 case '>': growBuf.addStr("_4"); break;
3857 case '*': growBuf.addStr("_5"); break;
3858 case '&': growBuf.addStr("_6"); break;
3859 case '|': growBuf.addStr("_7"); break;
3860 case '.': if (allowDots) growBuf.addChar('.'); else growBuf.addStr("_8"); break;
3861 case '!': growBuf.addStr("_9"); break;
3862 case ',': growBuf.addStr("_00"); break;
3863 case ' ': growBuf.addStr("_01"); break;
3864 case '{': growBuf.addStr("_02"); break;
3865 case '}': growBuf.addStr("_03"); break;
3866 case '?': growBuf.addStr("_04"); break;
3867 case '^': growBuf.addStr("_05"); break;
3868 case '%': growBuf.addStr("_06"); break;
3869 case '(': growBuf.addStr("_07"); break;
3870 case ')': growBuf.addStr("_08"); break;
3871 case '+': growBuf.addStr("_09"); break;
3872 case '=': growBuf.addStr("_0a"); break;
3873 case '$': growBuf.addStr("_0b"); break;
3874 case '\\': growBuf.addStr("_0c"); break;
3875 case '@': growBuf.addStr("_0d"); break;
3876 case ']': growBuf.addStr("_0e"); break;
3877 case '[': growBuf.addStr("_0f"); break;
3878 case '#': growBuf.addStr("_0g"); break;
3879 case '"': growBuf.addStr("_0h"); break;
3880 case '~': growBuf.addStr("_0i"); break;
3881 case '\'': growBuf.addStr("_0j"); break;
3882 case ';': growBuf.addStr("_0k"); break;
3883 case '`': growBuf.addStr("_0l"); break;
3884 default:
3885 if (c<0)
3886 {
3887 bool doEscape = true;
3888 if (allowUnicodeNames)
3889 {
3890 int charLen = getUTF8CharNumBytes(c);
3891 if (charLen>0)
3892 {
3893 growBuf.addStr(p-1,charLen);
3894 p+=charLen;
3895 doEscape = false;
3896 }
3897 }
3898 if (doEscape) // not a valid unicode char or escaping needed
3899 {
3900 char ids[5];
3901 unsigned char id = static_cast<unsigned char>(c);
3902 ids[0]='_';
3903 ids[1]='x';
3904 ids[2]=hex[id>>4];
3905 ids[3]=hex[id&0xF];
3906 ids[4]=0;
3907 growBuf.addStr(ids);
3908 }
3909 }
3910 else if (caseSenseNames || !isupper(c))
3911 {
3912 growBuf.addChar(c);
3913 }
3914 else
3915 {
3916 growBuf.addChar('_');
3917 growBuf.addChar(static_cast<char>(tolower(c)));
3918 }
3919 break;
3920 }
3921 }
3922 growBuf.addChar(0);
3923 return growBuf.get();
3924}
bool getCaseSenseNames()
Definition util.cpp:3829

References GrowBuf::addChar(), GrowBuf::addStr(), Config_getBool, QCString::data(), GrowBuf::get(), getCaseSenseNames(), getUTF8CharNumBytes(), hex, and QCString::isEmpty().

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

6188{
6189 bool extLinksInWindow = Config_getBool(EXT_LINKS_IN_WINDOW);
6190 if (extLinksInWindow)
6191 return "target=\"_blank\" ";
6192 else if (parent)
6193 return "target=\"_parent\" ";
6194 else
6195 return "";
6196}
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:1324

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

6232{
6233 QCString result;
6234 if (!ref.isEmpty())
6235 {
6236 auto it = Doxygen::tagDestinationMap.find(ref.str());
6238 {
6239 result = it->second;
6240 size_t l = result.length();
6241 if (!relPath.isEmpty() && l>0 && result.at(0)=='.')
6242 { // relative path -> prepend relPath.
6243 result.prepend(relPath);
6244 l+=relPath.length();
6245 }
6246 if (l>0 && result.at(l-1)!='/') result+='/';
6247 if (!href) result.append("\" ");
6248 }
6249 }
6250 else
6251 {
6252 result = relPath;
6253 }
6254 return result;
6255}
static StringMap tagDestinationMap
Definition doxygen.h:116
char & at(size_t i)
Returns a reference to the character at index i.
Definition qcstring.h:578
QCString & append(char c)
Definition qcstring.h:381

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

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

4722{
4723 static const reg::Ex re_norm(R"(\a[\w:]*)");
4724 static const reg::Ex re_fortran(R"(\a[\w:()=]*)");
4725 const reg::Ex *re = &re_norm;
4726
4727 name.clear();
4728 templSpec.clear();
4729 if (type.isEmpty()) return -1;
4730 size_t typeLen=type.length();
4731 if (typeLen>0)
4732 {
4733 if (lang == SrcLangExt::Fortran)
4734 {
4735 if (type[pos]==',') return -1;
4736 if (!type.lower().startsWith("type"))
4737 {
4738 re = &re_fortran;
4739 }
4740 }
4741 std::string s = type.str();
4742 reg::Iterator it(s,*re,static_cast<int>(pos));
4744
4745 if (it!=end)
4746 {
4747 const auto &match = *it;
4748 size_t i = match.position();
4749 size_t l = match.length();
4750 size_t ts = i+l;
4751 size_t te = ts;
4752 size_t tl = 0;
4753
4754 while (ts<typeLen && type[static_cast<uint32_t>(ts)]==' ') ts++,tl++; // skip any whitespace
4755 if (ts<typeLen && type[static_cast<uint32_t>(ts)]=='<') // assume template instance
4756 {
4757 // locate end of template
4758 te=ts+1;
4759 int brCount=1;
4760 while (te<typeLen && brCount!=0)
4761 {
4762 if (type[static_cast<uint32_t>(te)]=='<')
4763 {
4764 if (te<typeLen-1 && type[static_cast<uint32_t>(te)+1]=='<') te++; else brCount++;
4765 }
4766 if (type[static_cast<uint32_t>(te)]=='>')
4767 {
4768 if (te<typeLen-1 && type[static_cast<uint32_t>(te)+1]=='>') te++; else brCount--;
4769 }
4770 te++;
4771 }
4772 }
4773 name = match.str();
4774 if (te>ts)
4775 {
4776 templSpec = QCString(type).mid(ts,te-ts);
4777 tl+=te-ts;
4778 pos=static_cast<int>(i+l+tl);
4779 }
4780 else // no template part
4781 {
4782 pos=static_cast<int>(i+l);
4783 }
4784 //printf("extractClassNameFromType([in] type=%s,[out] pos=%d,[out] name=%s,[out] templ=%s)=TRUE i=%d\n",
4785 // qPrint(type),pos,qPrint(name),qPrint(templSpec),i);
4786 return static_cast<int>(i);
4787 }
4788 }
4789 pos = static_cast<int>(typeLen);
4790 //printf("extractClassNameFromType([in] type=%s,[out] pos=%d,[out] name=%s,[out] templ=%s)=FALSE\n",
4791 // qPrint(type),pos,qPrint(name),qPrint(templSpec));
4792 return -1;
4793}
bool startsWith(const char *s) const
Definition qcstring.h:492
QCString lower() const
Definition qcstring.h:234
void clear()
Definition qcstring.h:169

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

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

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

6655{
6656 std::string s = docs.str();
6657 static const reg::Ex re(R"(\[([ inout,]+)\])");
6658 reg::Iterator it(s,re);
6660 if (it!=end)
6661 {
6662 const auto &match = *it;
6663 size_t p = match.position();
6664 size_t l = match.length();
6665 if (p==0 && l>2)
6666 {
6667 // make dir the part inside [...] without separators
6668 std::string dir = match[1].str();
6669 // strip , and ' ' from dir
6670 dir.erase(std::remove_if(dir.begin(),dir.end(),
6671 [](const char c) { return c==' ' || c==','; }
6672 ),dir.end());
6673 unsigned char ioMask=0;
6674 size_t inIndex = dir.find( "in");
6675 if ( inIndex!=std::string::npos) dir.erase( inIndex,2),ioMask|=(1<<0);
6676 size_t outIndex = dir.find("out");
6677 if (outIndex!=std::string::npos) dir.erase(outIndex,3),ioMask|=(1<<1);
6678 if (dir.empty() && ioMask!=0) // only in and/or out attributes found
6679 {
6680 docs = s.substr(l); // strip attributes
6681 if (ioMask==((1<<0)|(1<<1))) return "[in,out]";
6682 else if (ioMask==(1<<0)) return "[in]";
6683 else if (ioMask==(1<<1)) return "[out]";
6684 }
6685 }
6686 }
6687 return "";
6688}

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

Referenced by inlineArgListToDoc().

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

4209{
4210 int i=0, p=0;
4211 QCString clName=scopeName;
4212 NamespaceDef *nd = nullptr;
4213 if (!clName.isEmpty() && (nd=getResolvedNamespace(clName)) && getClass(clName)==nullptr)
4214 { // the whole name is a namespace (and not a class)
4215 namespaceName=nd->name();
4216 className.clear();
4217 goto done;
4218 }
4219 p=static_cast<int>(clName.length())-2;
4220 while (p>=0 && (i=clName.findRev("::",p))!=-1)
4221 // see if the first part is a namespace (and not a class)
4222 {
4223 //printf("Trying %s\n",qPrint(clName.left(i)));
4224 if (i>0 && (nd=getResolvedNamespace(clName.left(i))) && getClass(clName.left(i))==nullptr)
4225 {
4226 //printf("found!\n");
4227 namespaceName=nd->name();
4228 className=clName.right(clName.length()-i-2);
4229 goto done;
4230 }
4231 p=i-2; // try a smaller piece of the scope
4232 }
4233 //printf("not found!\n");
4234
4235 // not found, so we just have to guess.
4236 className=scopeName;
4237 namespaceName.clear();
4238
4239done:
4240 if (className.isEmpty() && !namespaceName.isEmpty() && !allowEmptyClass)
4241 {
4242 // class and namespace with the same name, correct to return the class.
4243 className=namespaceName;
4244 namespaceName.clear();
4245 }
4246 //printf("extractNamespace '%s' => '%s|%s'\n",qPrint(scopeName),
4247 // qPrint(className),qPrint(namespaceName));
4248 if (className.endsWith("-p"))
4249 {
4250 className = className.left(className.length()-2);
4251 }
4252 return;
4253}
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 1441 of file util.cpp.

1442{
1443 if (name.isEmpty()) return QCString();
1444 bool fileOpened=false;
1445 if (name[0]=='-' && name[1]==0) // read from stdin
1446 {
1447 std::string contents;
1448 std::string line;
1449 while (getline(std::cin,line))
1450 {
1451 contents+=line+'\n';
1452 }
1453 return QCString(contents);
1454 }
1455 else // read from file
1456 {
1457 FileInfo fi(name.str());
1458 if (!fi.exists() || !fi.isFile())
1459 {
1460 err("file '{}' not found\n",name);
1461 return "";
1462 }
1463 std::string buf;
1464 fileOpened=readInputFile(name,buf,filter,isSourceCode);
1465 if (fileOpened)
1466 {
1467 addTerminalCharIfMissing(buf,'\n');
1468 return buf;
1469 }
1470 }
1471 if (!fileOpened)
1472 {
1473 err("cannot open file '{}' for reading\n",name);
1474 }
1475 return "";
1476}
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:6006

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

6566{
6567 bool allExternals = Config_getBool(ALLEXTERNALS);
6568 bool isDocFile = fd->isDocumentationFile();
6569 genSourceFile = !isDocFile && fd->generateSourceFile();
6570 return ( ((allExternals && fd->isLinkable()) ||
6572 ) &&
6573 !isDocFile
6574 );
6575}
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 6086 of file util.cpp.

6087{
6088 std::string tf;
6089 std::string t = title.str();
6090 static const reg::Ex re(R"(%[a-z_A-Z]+)");
6091 reg::Iterator it(t,re);
6093 size_t p = 0;
6094 for (; it!=end ; ++it)
6095 {
6096 const auto &match = *it;
6097 size_t i = match.position();
6098 size_t l = match.length();
6099 if (i>p) tf+=t.substr(p,i-p);
6100 tf+=match.str().substr(1); // skip %
6101 p=i+l;
6102 }
6103 tf+=t.substr(p);
6104 return QCString(tf);
6105}

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

Referenced by addToIndices(), createJavaScriptSearchIndex(), PerlModGenerator::generatePerlModForPage(), generateSqlite3ForPage(), generateXMLForPage(), mainPageHasOwnTitle(), SearchTerm::makeTitle(), SearchIndexExternal::setCurrentDoc(), HtmlGenerator::startFile(), writeExampleIndex(), writeIndex(), writeJavasScriptSearchDataPage(), HtmlGenerator::writeLocalToc(), and writePages().

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

5491{
5492 static reg::Ex re(R"(\s*(<\a+>)\s*)");
5493 std::string s = sentence.str();
5494 reg::Iterator it(s,re);
5496 std::string result;
5497 bool found=false;
5498 size_t p=0;
5499 for ( ; it!=end ; ++it)
5500 {
5501 const auto match = *it;
5502 std::string part = match[1].str();
5503 if (part!=word)
5504 {
5505 size_t i = match.position();
5506 size_t l = match.length();
5507 result+=s.substr(p,i-p);
5508 result+=match.str();
5509 p=i+l;
5510 }
5511 else
5512 {
5513 found=true;
5514 size_t i = match[1].position();
5515 size_t l = match[1].length();
5516 result+=s.substr(p,i-p);
5517 p=i+l;
5518 }
5519 }
5520 result+=s.substr(p);
5521 sentence = QCString(result).simplifyWhiteSpace();
5522 return found;
5523}
QCString simplifyWhiteSpace() const
return a copy of this string with leading and trailing whitespace removed and multiple whitespace cha...
Definition qcstring.cpp:185
bool found
Definition util.cpp:984

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

Referenced by isVarWithConstructor().

◆ findFileDef()

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

Definition at line 3408 of file util.cpp.

3409{
3410 ambig=FALSE;
3411 if (n.isEmpty()) return nullptr;
3412
3413
3414 const int maxAddrSize = 20;
3415 char addr[maxAddrSize];
3416 qsnprintf(addr,maxAddrSize,"%p:",reinterpret_cast<const void*>(fnMap));
3417 QCString key = addr;
3418 key+=n;
3419
3420 std::lock_guard<std::mutex> lock(g_findFileDefMutex);
3421 FindFileCacheElem *cachedResult = g_findFileDefCache.find(key.str());
3422 //printf("key=%s cachedResult=%p\n",qPrint(key),cachedResult);
3423 if (cachedResult)
3424 {
3425 ambig = cachedResult->isAmbig;
3426 //printf("cached: fileDef=%p\n",cachedResult->fileDef);
3427 return cachedResult->fileDef;
3428 }
3429 else
3430 {
3431 cachedResult = g_findFileDefCache.insert(key.str(),FindFileCacheElem(nullptr,FALSE));
3432 }
3433
3434 QCString name=Dir::cleanDirPath(n.str());
3435 QCString path;
3436 if (name.isEmpty()) return nullptr;
3437 int slashPos=std::max(name.findRev('/'),name.findRev('\\'));
3438 if (slashPos!=-1)
3439 {
3440 path=removeLongPathMarker(name.left(slashPos+1));
3441 name=name.right(name.length()-slashPos-1);
3442 }
3443 if (name.isEmpty()) return nullptr;
3444 const FileName *fn = fnMap->find(name);
3445 if (fn)
3446 {
3447 //printf("fn->size()=%zu\n",fn->size());
3448 if (fn->size()==1)
3449 {
3450 const std::unique_ptr<FileDef> &fd = fn->front();
3451 bool isSamePath = Portable::fileSystemIsCaseSensitive() ?
3452 fd->getPath().right(path.length())==path :
3453 fd->getPath().right(path.length()).lower()==path.lower();
3454 if (path.isEmpty() || isSamePath)
3455 {
3456 cachedResult->fileDef = fd.get();
3457 return fd.get();
3458 }
3459 }
3460 else // file name alone is ambiguous
3461 {
3462 int count=0;
3463 FileDef *lastMatch=nullptr;
3464 QCString pathStripped = stripFromIncludePath(path);
3465 for (const auto &fd_p : *fn)
3466 {
3467 FileDef *fd = fd_p.get();
3468 QCString fdStripPath = stripFromIncludePath(fd->getPath());
3469 if (path.isEmpty() || fdStripPath.right(pathStripped.length())==pathStripped)
3470 {
3471 count++;
3472 lastMatch=fd;
3473 }
3474 }
3475
3476 ambig=(count>1);
3477 cachedResult->isAmbig = ambig;
3478 cachedResult->fileDef = lastMatch;
3479 return lastMatch;
3480 }
3481 }
3482 else
3483 {
3484 //printf("not found!\n");
3485 }
3486 return nullptr;
3487}
static std::string cleanDirPath(const std::string &path)
Definition dir.cpp:355
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:487
#define qsnprintf
Definition qcstring.h:49
Cache element for the file name to FileDef mapping cache.
Definition util.cpp:3398
FileDef * fileDef
Definition util.cpp:3400
QCString stripFromIncludePath(const QCString &path)
Definition util.cpp:340
static Cache< std::string, FindFileCacheElem > g_findFileDefCache(5000)
static std::mutex g_findFileDefMutex
Definition util.cpp:3406
QCString removeLongPathMarker(QCString path)
Definition util.cpp:298

References Dir::cleanDirPath(), 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(), findFile(), findFilePath(), generateFileRef(), generateFileSources(), DocParser::handleLinkedWord(), DocbookDocVisitor::operator()(), XmlDocVisitor::operator()(), DocDiaFile::parse(), DocDotFile::parse(), DocMscFile::parse(), DocPlantUmlFile::parse(), parseFilesMultiThreading(), parseFilesSingleThreading(), Markdown::Private::processLink(), readIncludeFile(), readTextFileByName(), ModuleManager::resolveImports(), resolveLink(), ModuleManager::resolvePartitions(), resolveRef(), and setFileName().

◆ findFilePath()

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

Definition at line 3491 of file util.cpp.

3492{
3493 ambig=false;
3494 QCString result;
3495 bool found=false;
3496 if (!found)
3497 {
3498 FileInfo fi(file.str());
3499 if (fi.exists())
3500 {
3501 result=fi.absFilePath();
3502 found=true;
3503 }
3504 }
3505 if (!found)
3506 {
3507 const StringVector &examplePathList = Config_getList(EXAMPLE_PATH);
3508 for (const auto &s : examplePathList)
3509 {
3510 std::string absFileName = s+(Portable::pathSeparator()+file).str();
3511 FileInfo fi(absFileName);
3512 if (fi.exists())
3513 {
3514 result=fi.absFilePath();
3515 found=true;
3516 }
3517 }
3518 }
3519
3520 if (!found)
3521 {
3522 // as a fallback we also look in the exampleNameDict
3524 if (fd && !ambig)
3525 {
3526 result=fd->absFilePath();
3527 }
3528 }
3529 return result;
3530}
static FileNameLinkedMap * exampleNameLinkedMap
Definition doxygen.h:103
virtual QCString absFilePath() const =0
QCString pathSeparator()
Definition portable.cpp:391
FileDef * findFileDef(const FileNameLinkedMap *fnMap, const QCString &n, bool &ambig)
Definition util.cpp:3408

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

Referenced by readIncludeFile(), and 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 7138 of file util.cpp.

7139{
7141 return reg::search(s,match,re) ? static_cast<int>(match.position()) : -1;
7142}
Object representing the matching results.
Definition regex.h:153
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:748

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

7131{
7132 auto it = std::find(sv.begin(),sv.end(),s);
7133 return it!=sv.end() ? static_cast<int>(it-sv.begin()) : -1;
7134}

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

◆ fixSpaces()

QCString fixSpaces ( const QCString & s)
inline

Definition at line 471 of file util.h.

471{ 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:477

References substitute().

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

◆ generateAnonymousAnchor()

QCString generateAnonymousAnchor ( const QCString & fileName,
int count )

Definition at line 4067 of file util.cpp.

4068{
4069 QCString fn = stripFromPath(fileName)+":"+QCString().setNum(count);
4070 const int sig_size=16;
4071 uint8_t md5_sig[sig_size];
4072 MD5Buffer(fn.data(),static_cast<unsigned int>(fn.length()),md5_sig);
4073 char result[sig_size*3+2];
4074 char *p = result;
4075 *p++='@';
4076 for (int i=0;i<sig_size;i++)
4077 {
4078 static const char oct[]="01234567";
4079 uint8_t byte = md5_sig[i];
4080 *p++=oct[(byte>>6)&7];
4081 *p++=oct[(byte>>3)&7];
4082 *p++=oct[(byte>>0)&7];
4083 }
4084 *p='\0';
4085 return result;
4086}
QCString & setNum(short n)
Definition qcstring.h:444
static QCString stripFromPath(const QCString &p, const StringVector &l)
Definition util.cpp:309

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

◆ generateFileRef()

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

Definition at line 3380 of file util.cpp.

3381{
3382 //printf("generateFileRef(%s,%s)\n",name,text);
3383 QCString linkText = text.isEmpty() ? text : name;
3384 //FileInfo *fi;
3385 bool ambig = false;
3387 if (fd && fd->isLinkable())
3388 // link to documented input file
3389 ol.writeObjectLink(fd->getReference(),fd->getOutputFileBase(),QCString(),linkText);
3390 else
3391 ol.docify(linkText);
3392}
static FileNameLinkedMap * inputNameLinkedMap
Definition doxygen.h:105
void writeObjectLink(const QCString &ref, const QCString &file, const QCString &anchor, const QCString &name)
Definition outputlist.h:440
void docify(const QCString &s)
Definition outputlist.h:438

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

291{
292 const int maxMarkerStrLen = 20;
293 char result[maxMarkerStrLen];
294 qsnprintf(result,maxMarkerStrLen,"@%d",id);
295 return result;
296}

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

3830{
3831 auto caseSenseNames = Config_getEnum(CASE_SENSE_NAMES);
3832
3833 if (caseSenseNames == CASE_SENSE_NAMES_t::YES) return true;
3834 else if (caseSenseNames == CASE_SENSE_NAMES_t::NO) return false;
3836}
#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 2822 of file util.cpp.

2823{
2824 if (false) // set this to true to try the old and new routine side-by-side and compare the results
2825 {
2826 printf("@@ ------ getDefsOld start\n");
2827 GetDefResult result = getDefsOld(input);
2828 printf("@@ ------ getDefsOld end\n");
2829 printf("@@ ------ getDefsNew start\n");
2830 GetDefResult newResult = getDefsNew(input);
2831 printf("@@ ------ getDefsNew end\n");
2832 if (result.found!=newResult.found ||
2833 result.md!=newResult.md ||
2834 result.cd!=newResult.cd ||
2835 result.fd!=newResult.fd ||
2836 result.nd!=newResult.nd ||
2837 result.gd!=newResult.gd
2838 )
2839 {
2840 printf("@@ getDefsOld(scName=%s, mbName=%s, args=%s, forceEmptyScope=%d "
2841 "currentFile=%s checkCV=%d)=%d md=%s (%p) cd=%s fd=%s nd=%s gd=%s\n",
2842 qPrint(input.scopeName), qPrint(input.memberName), qPrint(input.args),
2843 input.forceEmptyScope, qPrint(input.currentFile?input.currentFile->name():QCString()),
2844 input.checkCV,
2845 result.found,
2846 qPrint(result.md ? result.md->name() : QCString()),
2847 (void*)result.md,
2848 qPrint(result.cd ? result.cd->name() : QCString()),
2849 qPrint(result.fd ? result.fd->name() : QCString()),
2850 qPrint(result.nd ? result.nd->name() : QCString()),
2851 qPrint(result.gd ? result.gd->name() : QCString())
2852 );
2853 printf("@@ ------ getDefsOld start\n");
2854 printf("@@ getDefsNew(scName=%s, mbName=%s, args=%s, forceEmptyScope=%d "
2855 "currentFile=%s checkCV=%d)=%d md=%s (%p) cd=%s fd=%s nd=%s gd=%s\n",
2856 qPrint(input.scopeName), qPrint(input.memberName), qPrint(input.args),
2857 input.forceEmptyScope, qPrint(input.currentFile?input.currentFile->name():QCString()),
2858 input.checkCV,
2859 newResult.found,
2860 qPrint(newResult.md ? newResult.md->name() : QCString()),
2861 (void*)newResult.md,
2862 qPrint(newResult.cd ? newResult.cd->name() : QCString()),
2863 qPrint(newResult.fd ? newResult.fd->name() : QCString()),
2864 qPrint(newResult.nd ? newResult.nd->name() : QCString()),
2865 qPrint(newResult.gd ? newResult.gd->name() : QCString())
2866 );
2867 }
2868 return result; // use return newResult to use the result of the new routine
2869 }
2870 else // do one of the two getDefs routines (comment out the other one)
2871 {
2872 return getDefsNew(input);
2873 }
2874}
const char * qPrint(const char *s)
Definition qcstring.h:672
bool forceEmptyScope
Definition util.h:116
const FileDef * currentFile
Definition util.h:117
QCString scopeName
Definition util.h:113
bool checkCV
Definition util.h:118
QCString args
Definition util.h:115
QCString memberName
Definition util.h:114
const MemberDef * md
Definition util.h:125
const FileDef * fd
Definition util.h:127
const GroupDef * gd
Definition util.h:129
bool found
Definition util.h:124
const ClassDef * cd
Definition util.h:126
const NamespaceDef * nd
Definition util.h:128
GetDefResult getDefsOld(const GetDefInput &input)
Definition util.cpp:2348
GetDefResult getDefsNew(const GetDefInput &input)
Definition util.cpp:2273

References GetDefInput::args, GetDefResult::cd, GetDefInput::checkCV, GetDefInput::currentFile, GetDefResult::fd, GetDefInput::forceEmptyScope, GetDefResult::found, GetDefResult::gd, getDefsNew(), getDefsOld(), GetDefResult::md, GetDefInput::memberName, Definition::name(), GetDefResult::nd, qPrint(), and GetDefInput::scopeName.

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

◆ getDotImageExtension()

QCString getDotImageExtension ( )

Definition at line 6765 of file util.cpp.

6766{
6767 QCString imgExt = Config_getEnumAsString(DOT_IMAGE_FORMAT);
6768 int i= imgExt.find(':'); // strip renderer part when using e.g. 'png:cairo:gd' as format
6769 return i==-1 ? imgExt : imgExt.left(i);
6770}
#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 6173 of file util.cpp.

6174{
6175 InputFileEncoding elem;
6176 auto getter = [](const InputFileEncoding &e) { return e.pattern; };
6177 if (genericPatternMatch(fi,Doxygen::inputFileEncodingList,elem,getter)) // check for file specific encoding
6178 {
6179 return elem.encoding;
6180 }
6181 else // fall back to default encoding
6182 {
6183 return Config_getString(INPUT_ENCODING);
6184 }
6185}
static InputFileEncodingList inputFileEncodingList
Definition doxygen.h:140
#define Config_getString(name)
Definition config.h:32
QCString encoding
Definition doxygen.h:71
bool genericPatternMatch(const FileInfo &fi, const PatternList &patList, PatternElem &elem, PatternGet getter)
Definition util.cpp:6110

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

1370{
1371 // sanity check
1372 if (name.isEmpty()) return "";
1373
1374 const StringVector& filterSrcList = Config_getList(FILTER_SOURCE_PATTERNS);
1375 const StringVector& filterList = Config_getList(FILTER_PATTERNS);
1376
1377 QCString filterName;
1378 bool found=FALSE;
1379 if (isSourceCode && !filterSrcList.empty())
1380 { // first look for source filter pattern list
1381 filterName = getFilterFromList(name,filterSrcList,found);
1382 }
1383 if (!found && filterName.isEmpty())
1384 { // then look for filter pattern list
1385 filterName = getFilterFromList(name,filterList,found);
1386 }
1387 if (!found)
1388 { // then use the generic input filter
1389 return Config_getString(INPUT_FILTER);
1390 }
1391 else
1392 {
1393 /* remove surrounding double quotes */
1394 if (filterName.length()>=2 && filterName[0]=='"' && filterName[static_cast<int>(filterName.length())-1]=='"')
1395 {
1396 filterName = filterName.mid(1,filterName.length()-2);
1397 }
1398 return filterName;
1399 }
1400}
static QCString getFilterFromList(const QCString &name, const StringVector &filterList, bool &found)
Definition util.cpp:1328

References Config_getList, Config_getString, FALSE, found, 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 5732 of file util.cpp.

5733{
5734 // try the extension
5735 auto lang = getLanguageFromFileName(fileName, SrcLangExt::Unknown);
5736 if (lang == SrcLangExt::Unknown)
5737 {
5738 // try the language names
5739 QCString langName = fileName.lower();
5740 if (langName.at(0)=='.') langName = langName.mid(1);
5741 auto it = std::find_if(g_lang2extMap.begin(),g_lang2extMap.end(),
5742 [&langName](const auto &info) { return info.langName==langName; });
5743 if (it != g_lang2extMap.end())
5744 {
5745 lang = it->parserId;
5746 fileName = it->defExt;
5747 }
5748 else // default to C++
5749 {
5750 return SrcLangExt::Cpp;
5751 }
5752 }
5753 return lang;
5754}
SrcLangExt getLanguageFromFileName(const QCString &fileName, SrcLangExt defLang)
Definition util.cpp:5714
static std::vector< Lang2ExtMap > g_lang2extMap
Definition util.cpp:5585

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

5715{
5716 FileInfo fi(fileName.str());
5717 // we need only the part after the last ".", newer implementations of FileInfo have 'suffix()' for this.
5718 QCString extName = QCString(fi.extension(FALSE)).lower();
5719 if (extName.isEmpty()) extName=".no_extension";
5720 if (extName.at(0)!='.') extName.prepend(".");
5721 auto it = g_extLookup.find(extName.str());
5722 if (it!=g_extLookup.end()) // listed extension
5723 {
5724 //printf("getLanguageFromFileName(%s)=%x\n",qPrint(fi.extension()),*pVal);
5725 return it->second;
5726 }
5727 //printf("getLanguageFromFileName(%s) not found!\n",qPrint(fileName));
5728 return defLang; // not listed => assume C-ish language.
5729}
static std::unordered_map< std::string, SrcLangExt > g_extLookup
Definition util.cpp:5575

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

Referenced by MemberDefImpl::_writeMultiLineInitializer(), ClassDefImpl::ClassDefImpl(), convertCppComments(), DocRef::DocRef(), FileDefImpl::FileDefImpl(), generateExampleDocs(), getLanguageFromCodeLang(), guessSection(), FileDefImpl::isDocumentationFile(), COutlineParser::needsPreprocessing(), DocbookDocVisitor::operator()(), DocbookDocVisitor::operator()(), HtmlDocVisitor::operator()(), HtmlDocVisitor::operator()(), LatexDocVisitor::operator()(), LatexDocVisitor::operator()(), ManDocVisitor::operator()(), ManDocVisitor::operator()(), RTFDocVisitor::operator()(), RTFDocVisitor::operator()(), XmlDocVisitor::operator()(), XmlDocVisitor::operator()(), CodeFragmentManager::parseCodeFragment(), parseFilesMultiThreading(), parseFilesSingleThreading(), parseMain(), Markdown::Private::processLink(), readCodeFragment(), setContext(), setFileName(), validatingParseDoc(), and writeXMLCodeBlock().

◆ getLanguageSpecificSeparator()

QCString getLanguageSpecificSeparator ( SrcLangExt lang,
bool classScope = FALSE )

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

Definition at line 6375 of file util.cpp.

6376{
6377 if (lang==SrcLangExt::Java || lang==SrcLangExt::CSharp || lang==SrcLangExt::VHDL || lang==SrcLangExt::Python)
6378 {
6379 return ".";
6380 }
6381 else if (lang==SrcLangExt::PHP && !classScope)
6382 {
6383 return "\\";
6384 }
6385 else
6386 {
6387 return "::";
6388 }
6389}

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

4596{
4597 return theTranslator->trOverloadText();
4598 //"This is an overloaded member function, "
4599 // "provided for convenience. It differs from the above "
4600 // "function only in what argument(s) it accepts.";
4601}
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 3745 of file util.cpp.

3746{
3747 if (name.isEmpty()) return 0;
3748 const StringVector &sl = Config_getList(IGNORE_PREFIX);
3749 for (const auto &s : sl)
3750 {
3751 const char *ps=s.c_str();
3752 const char *pd=name.data();
3753 int i=0;
3754 while (*ps!=0 && *pd!=0 && *ps==*pd) ps++,pd++,i++;
3755 if (*ps==0 && *pd!=0)
3756 {
3757 return i;
3758 }
3759 }
3760 return 0;
3761}

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

7288{
7289 QCString projectCookie = Config_getString(HTML_PROJECT_COOKIE);
7290 if (projectCookie.isEmpty()) return QCString();
7291 uint8_t md5_sig[16];
7292 char sigStr[34];
7293 MD5Buffer(projectCookie.data(),static_cast<unsigned int>(projectCookie.length()),md5_sig);
7294 MD5SigToString(md5_sig,sigStr);
7295 sigStr[32]='_'; sigStr[33]=0;
7296 return sigStr;
7297}

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

5135{
5136 int sl=static_cast<int>(s.length());
5137 int sp=p;
5138 int count=0;
5139 bool done=false;
5140 if (sp>=sl) return -1;
5141 while (sp<sl)
5142 {
5143 char c=s.at(sp);
5144 if (c==':') sp++,p++; else break;
5145 }
5146 while (sp<sl)
5147 {
5148 char c=s.at(sp);
5149 switch (c)
5150 {
5151 case ':': // found next part
5152 goto found;
5153 case '<': // skip template specifier
5154 count=1;sp++;
5155 done=false;
5156 while (sp<sl && !done)
5157 {
5158 // TODO: deal with << and >> operators!
5159 c=s.at(sp++);
5160 switch(c)
5161 {
5162 case '<': count++; break;
5163 case '>': count--; if (count==0) done=true; break;
5164 default: break;
5165 }
5166 }
5167 break;
5168 default:
5169 sp++;
5170 break;
5171 }
5172 }
5173found:
5174 *l=sp-p;
5175 //printf("getScopeFragment(%s,%d)=%s\n",qPrint(s),p,qPrint(s.mid(p,*l)));
5176 return p;
5177}

References QCString::at(), found, 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 349 of file util.cpp.

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

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(), Preprocessor::processFile(), setFileName(), and warnUndocumentedNamespaces().

◆ initDefaultExtensionMapping()

void initDefaultExtensionMapping ( )

Definition at line 5641 of file util.cpp.

5642{
5643 // NOTE: when adding an extension, also add the extension in config.xml
5644 // extension parser id
5645 updateLanguageMapping(".dox", "c");
5646 updateLanguageMapping(".txt", "c"); // see bug 760836
5647 updateLanguageMapping(".doc", "c");
5648 updateLanguageMapping(".c", "c");
5649 updateLanguageMapping(".C", "c");
5650 updateLanguageMapping(".cc", "c");
5651 updateLanguageMapping(".CC", "c");
5652 updateLanguageMapping(".cxx", "c");
5653 updateLanguageMapping(".cpp", "c");
5654 updateLanguageMapping(".c++", "c");
5655 updateLanguageMapping(".cxxm", "c"); // C++20 modules
5656 updateLanguageMapping(".cppm", "c"); // C++20 modules
5657 updateLanguageMapping(".ccm", "c"); // C++20 modules
5658 updateLanguageMapping(".c++m", "c"); // C++20 modules
5659 updateLanguageMapping(".ii", "c");
5660 updateLanguageMapping(".ixx", "c");
5661 updateLanguageMapping(".ipp", "c");
5662 updateLanguageMapping(".i++", "c");
5663 updateLanguageMapping(".inl", "c");
5664 updateLanguageMapping(".h", "c");
5665 updateLanguageMapping(".H", "c");
5666 updateLanguageMapping(".hh", "c");
5667 updateLanguageMapping(".HH", "c");
5668 updateLanguageMapping(".hxx", "c");
5669 updateLanguageMapping(".hpp", "c");
5670 updateLanguageMapping(".h++", "c");
5671 updateLanguageMapping(".idl", "idl");
5672 updateLanguageMapping(".ddl", "idl");
5673 updateLanguageMapping(".odl", "idl");
5674 updateLanguageMapping(".java", "java");
5675 //updateLanguageMapping(".as", "javascript"); // not officially supported
5676 //updateLanguageMapping(".js", "javascript"); // not officially supported
5677 updateLanguageMapping(".cs", "csharp");
5678 updateLanguageMapping(".d", "d");
5679 updateLanguageMapping(".php", "php");
5680 updateLanguageMapping(".php4", "php");
5681 updateLanguageMapping(".php5", "php");
5682 updateLanguageMapping(".inc", "php");
5683 updateLanguageMapping(".phtml", "php");
5684 updateLanguageMapping(".m", "objective-c");
5685 updateLanguageMapping(".M", "objective-c");
5686 updateLanguageMapping(".mm", "c"); // see bug746361
5687 updateLanguageMapping(".py", "python");
5688 updateLanguageMapping(".pyw", "python");
5689 updateLanguageMapping(".f", "fortran");
5690 updateLanguageMapping(".for", "fortran");
5691 updateLanguageMapping(".f90", "fortran");
5692 updateLanguageMapping(".f95", "fortran");
5693 updateLanguageMapping(".f03", "fortran");
5694 updateLanguageMapping(".f08", "fortran");
5695 updateLanguageMapping(".f18", "fortran");
5696 updateLanguageMapping(".vhd", "vhdl");
5697 updateLanguageMapping(".vhdl", "vhdl");
5698 updateLanguageMapping(".ucf", "vhdl");
5699 updateLanguageMapping(".qsf", "vhdl");
5700 updateLanguageMapping(".md", "md");
5701 updateLanguageMapping(".markdown", "md");
5702 updateLanguageMapping(".ice", "slice");
5703 updateLanguageMapping(".l", "lex");
5704 updateLanguageMapping(".doxygen_lex_c", "c"); // this is a placeholder so we can map initializations
5705 // in the lex scanning to cpp
5706}

References updateLanguageMapping().

Referenced by initDoxygen().

◆ inlineArgListToDoc()

QCString inlineArgListToDoc ( const ArgumentList & al)

Definition at line 1156 of file util.cpp.

1157{
1158 QCString paramDocs;
1159 if (al.hasDocumentation())
1160 {
1161 for (const Argument &a : al)
1162 {
1163 if (a.hasDocumentation())
1164 {
1165 QCString docsWithoutDir = a.docs;
1166 QCString direction = extractDirection(docsWithoutDir);
1167 paramDocs+=" \\ilinebr @param"+direction+" "+a.name+" "+docsWithoutDir;
1168 }
1169 }
1170 }
1171 return paramDocs;
1172}
bool hasDocumentation() const
Definition arguments.cpp:21
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:6654

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

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

◆ inlineTemplateArgListToDoc()

QCString inlineTemplateArgListToDoc ( const ArgumentList & al)

Definition at line 1174 of file util.cpp.

1175{
1176 QCString paramDocs;
1177 if (al.hasTemplateDocumentation())
1178 {
1179 for (const Argument &a : al)
1180 {
1181 if (!a.docs.isEmpty())
1182 {
1183 if (!a.name.isEmpty())
1184 {
1185 paramDocs+=" \\ilinebr @tparam "+a.name+" "+a.docs;
1186 }
1187 else if (!a.type.isEmpty())
1188 {
1189 QCString type = a.type;
1190 type.stripPrefix("class ");
1191 type.stripPrefix("typename ");
1192 type = type.stripWhiteSpace();
1193 paramDocs+=" \\ilinebr @tparam "+type+" "+a.docs;
1194 }
1195 }
1196 }
1197 }
1198 return paramDocs;
1199}
bool hasTemplateDocumentation() const
Definition arguments.cpp:29
bool stripPrefix(const QCString &prefix)
Definition qcstring.h:198

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

4256{
4257 QCString result=scope;
4258 if (!templ.isEmpty() && scope.find('<')==-1)
4259 {
4260 int si=0, pi=0;
4261 ClassDef *cd=nullptr;
4262 while (
4263 (si=scope.find("::",pi))!=-1 && !getClass(scope.left(si)+templ) &&
4264 ((cd=getClass(scope.left(si)))==nullptr || cd->templateArguments().empty())
4265 )
4266 {
4267 //printf("Tried '%s'\n",qPrint((scope.left(si)+templ)));
4268 pi=si+2;
4269 }
4270 if (si==-1) // not nested => append template specifier
4271 {
4272 result+=templ;
4273 }
4274 else // nested => insert template specifier before after first class name
4275 {
4276 result=scope.left(si) + templ + scope.right(scope.length()-si);
4277 }
4278 }
4279 //printf("insertTemplateSpecifierInScope('%s','%s')=%s\n",
4280 // qPrint(scope),qPrint(templ),qPrint(result));
4281 return result;
4282}
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 7158 of file util.cpp.

7159{
7160 QCString result;
7161 int residual = n;
7162
7163 char modVal[2];
7164 modVal[1] = 0;
7165 while (residual > 0)
7166 {
7167 modVal[0] = (upper ? 'A': 'a') + (residual-1)%26;
7168 result = modVal + result;
7169 residual = (residual-1) / 26;
7170 }
7171 return result;
7172}

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

◆ integerToRoman()

QCString integerToRoman ( int n,
bool upper = true )

Definition at line 7174 of file util.cpp.

7175{
7176 static const char *str_romans_upper[] = { "M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I" };
7177 static const char *str_romans_lower[] = { "m", "cm", "d", "cd", "c", "xc", "l", "xl", "x", "ix", "v", "iv", "i" };
7178 static const int values[] = { 1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1 };
7179 static const char **str_romans = upper ? str_romans_upper : str_romans_lower;
7180
7181 QCString result;
7182 int residual = n;
7183
7184 for (int i = 0; i < 13; ++i)
7185 {
7186 while (residual - values[i] >= 0)
7187 {
7188 result += str_romans[i];
7189 residual -= values[i];
7190 }
7191 }
7192
7193 return result;
7194}

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

◆ isId()

◆ isIdJS()

bool isIdJS ( int c)
inline

Definition at line 212 of file util.h.

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

Referenced by SearchTerm::termEncoded().

◆ isURL()

bool isURL ( const QCString & url)

Checks whether the given url starts with a supported protocol.

Definition at line 6391 of file util.cpp.

6392{
6393 static const std::unordered_set<std::string> schemes = {
6394 "http", "https", "ftp", "ftps", "sftp", "file", "news", "irc", "ircs"
6395 };
6396 QCString loc_url = url.stripWhiteSpace();
6397 int colonPos = loc_url.find(':');
6398 return colonPos!=-1 && schemes.find(loc_url.left(colonPos).str())!=schemes.end();
6399}

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

7146{
7147 std::string result;
7148 bool first=true;
7149 for (const auto &s : sv)
7150 {
7151 if (!first) result+=delimiter;
7152 first=false;
7153 result+=s;
7154 }
7155 return result;
7156}

Referenced by handleAnchor(), handleFormatBlock(), and handleImage().

◆ langToString()

QCString langToString ( SrcLangExt lang)

Returns a string representation of lang.

Definition at line 6369 of file util.cpp.

6370{
6371 return to_string(lang);
6372}
static const char * to_string(Protection prot)
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 892 of file util.cpp.

893{
894 size_t sl=scope.length();
895 size_t nl=name.length();
896 return (name==scope || // equal
897 (name.left(sl)==scope && // substring
898 nl>sl+1 && name.at(sl)==':' && name.at(sl+1)==':' // scope
899 )
900 );
901}

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

6349{
6350 int result = 1;
6351
6352 // find the character positions of the first marker
6353 int m1 = text.find(marker);
6354 if (m1==-1) return result;
6355
6356 // find start line positions for the markers
6357 bool found=false;
6358 int p=0, i=0;
6359 while (!found && (i=text.find('\n',p))!=-1)
6360 {
6361 found = (p<=m1 && m1<i); // found the line with the start marker
6362 p=i+1;
6363 result++;
6364 }
6365 return result;
6366}

References QCString::find(), and found.

Referenced by readIncludeFile().

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

908{
909 if (text.isEmpty()) return;
910 //printf("linkify='%s'\n",qPrint(text));
911 std::string_view txtStr=text.view();
912 size_t strLen = txtStr.length();
913 if (strLen==0) return;
914
915 static const reg::Ex regExp(R"((::)?\a[\w~!\\.:$"]*)");
916 reg::Iterator it(txtStr,regExp);
918
919 //printf("linkifyText scope=%s fileScope=%s strtxt=%s strlen=%zu external=%d\n",
920 // scope ? qPrint(scope->name()):"<none>",
921 // fileScope ? qPrint(fileScope->name()) : "<none>",
922 // qPrint(txtStr),strLen,external);
923 size_t index=0;
924 size_t skipIndex=0;
925 size_t floatingIndex=0;
926 for (; it!=end ; ++it) // for each word from the text string
927 {
928 const auto &match = *it;
929 size_t newIndex = match.position();
930 size_t matchLen = match.length();
931 floatingIndex+=newIndex-skipIndex+matchLen;
932 if (newIndex>0 && txtStr.at(newIndex-1)=='0') // ignore hex numbers (match x00 in 0x00)
933 {
934 std::string_view part = txtStr.substr(skipIndex,newIndex+matchLen-skipIndex);
935 out.writeString(part,keepSpaces);
936 skipIndex=index=newIndex+matchLen;
937 continue;
938 }
939
940 // add non-word part to the result
941 bool insideString=FALSE;
942 for (size_t i=index;i<newIndex;i++)
943 {
944 if (txtStr.at(i)=='"') insideString=!insideString;
945 if (txtStr.at(i)=='\\') i++; // skip next character it is escaped
946 }
std::string_view view() const
Definition qcstring.h:161
skipIndex
Definition util.cpp:1095

References end(), FALSE, QCString::isEmpty(), skipIndex, QCString::view(), 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 3219 of file util.cpp.

3220{
3221 //bool optimizeOutputJava = Config_getBool(OPTIMIZE_OUTPUT_JAVA);
3222 QCString result=link;
3223 if (!result.isEmpty())
3224 {
3225 // replace # by ::
3226 result=substitute(result,"#","::");
3227 // replace . by ::
3228 if (!isFileName && result.find('<')==-1) result=substitute(result,".","::",3);
3229 // strip leading :: prefix if present
3230 if (result.at(0)==':' && result.at(1)==':')
3231 {
3232 result=result.right(result.length()-2);
3233 }
3235 if (sep!="::")
3236 {
3237 result=substitute(result,"::",sep);
3238 }
3239 }
3240 //printf("linkToText(%s,lang=%d)=%s\n",qPrint(link),lang,qPrint(result));
3241 return result;
3242}
QCString getLanguageSpecificSeparator(SrcLangExt lang, bool classScope)
Returns the scope separator to use given the programming language lang.
Definition util.cpp:6375

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

6761{
6762 return Doxygen::mainPage!=nullptr && Doxygen::mainPage->hasTitle();
6763}
static std::unique_ptr< PageDef > mainPage
Definition doxygen.h:101

References Doxygen::mainPage.

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

◆ mangleCSharpGenericName()

QCString mangleCSharpGenericName ( const QCString & name)

Definition at line 7389 of file util.cpp.

7390{
7391 int idx = name.find('<');
7392 if (idx!=-1)
7393 {
7394 return name.left(idx)+"-"+QCString().setNum(name.contains(",")+1)+"-g";
7395 }
7396 return name;
7397}
int contains(char c, bool cs=TRUE) const
Definition qcstring.cpp:143

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 ArgumentList * srcAl,
const Definition * dstScope,
const FileDef * dstFileScope,
const ArgumentList * dstAl,
bool checkCV,
SrcLangExt lang )

Definition at line 1958 of file util.cpp.

1961{
1962 ASSERT(srcScope!=nullptr && dstScope!=nullptr);
1963
1964 AUTO_TRACE("srcScope='{}' dstScope='{}' srcArgs='{}' dstArgs='{}' checkCV={} lang={}",
1965 srcScope->name(),dstScope->name(),srcAl?argListToString(*srcAl):"",dstAl?argListToString(*dstAl):"",checkCV,lang);
1966
1967 if (srcAl==nullptr || dstAl==nullptr)
1968 {
1969 bool match = srcAl==dstAl;
1970 if (match)
1971 {
1972 MATCH
1973 return TRUE;
1974 }
1975 else
1976 {
1977 NOMATCH
1978 return FALSE;
1979 }
1980 }
1981
1982 // handle special case with void argument
1983 if ( srcAl->empty() && dstAl->size()==1 && dstAl->front().type=="void" )
1984 { // special case for finding match between func() and func(void)
1985 Argument a;
1986 a.type = "void";
1987 const_cast<ArgumentList*>(srcAl)->push_back(a);
1988 MATCH
1989 return TRUE;
1990 }
1991 if ( dstAl->empty() && srcAl->size()==1 && srcAl->front().type=="void" )
1992 { // special case for finding match between func(void) and func()
1993 Argument a;
1994 a.type = "void";
1995 const_cast<ArgumentList*>(dstAl)->push_back(a);
1996 MATCH
1997 return TRUE;
1998 }
1999
2000 if (srcAl->size() != dstAl->size())
2001 {
2002 NOMATCH
2003 return FALSE; // different number of arguments -> no match
2004 }
2005
2006 if (checkCV)
2007 {
2008 if (srcAl->constSpecifier() != dstAl->constSpecifier())
2009 {
2010 NOMATCH
2011 return FALSE; // one member is const, the other not -> no match
2012 }
2013 if (srcAl->volatileSpecifier() != dstAl->volatileSpecifier())
2014 {
2015 NOMATCH
2016 return FALSE; // one member is volatile, the other not -> no match
2017 }
2018 }
2019
2020 if (srcAl->refQualifier() != dstAl->refQualifier())
2021 {
2022 NOMATCH
2023 return FALSE; // one member is has a different ref-qualifier than the other
2024 }
2025
2026 // so far the argument list could match, so we need to compare the types of
2027 // all arguments.
2028 auto srcIt = srcAl->begin();
2029 auto dstIt = dstAl->begin();
2030 for (;srcIt!=srcAl->end() && dstIt!=dstAl->end();++srcIt,++dstIt)
2031 {
2032 Argument &srcA = const_cast<Argument&>(*srcIt);
2033 Argument &dstA = const_cast<Argument&>(*dstIt);
2034 if (!matchArgument2(srcScope,srcFileScope,srcA,
2035 dstScope,dstFileScope,dstA,
2036 lang)
2037 )
2038 {
2039 NOMATCH
2040 return FALSE;
2041 }
2042 }
2043 MATCH
2044 return TRUE; // all arguments match
2045}
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 AUTO_TRACE(...)
Definition docnode.cpp:46
#define MATCH
Definition util.cpp:1853
QCString argListToString(const ArgumentList &al, bool useCanonicalType, bool showDefVals)
Definition util.cpp:1201
#define NOMATCH
Definition util.cpp:1854
static bool matchArgument2(const Definition *srcScope, const FileDef *srcFileScope, Argument &srcA, const Definition *dstScope, const FileDef *dstFileScope, Argument &dstA, SrcLangExt lang)
Definition util.cpp:1892

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(), TRUE, Argument::type, and ArgumentList::volatileSpecifier().

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

◆ matchTemplateArguments()

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

Definition at line 2196 of file util.cpp.

2197{
2198 AUTO_TRACE("srcAl=%s dstAl=%s",argListToString(srcAl),argListToString(dstAl));
2199 if (srcAl.size()!=dstAl.size()) // different number of template parameters -> overload
2200 {
2201 AUTO_TRACE_EXIT("different number of parameters");
2202 return false;
2203 }
2204 auto isUnconstraintTemplate = [](const QCString &type)
2205 {
2206 return type=="typename" || type=="class" || type.startsWith("typename ") || type.startsWith("class ");
2207 };
2208 auto srcIt = srcAl.begin();
2209 auto dstIt = dstAl.begin();
2210 while (srcIt!=srcAl.end() && dstIt!=dstAl.end())
2211 {
2212 const Argument &srcA = *srcIt;
2213 const Argument &dstA = *dstIt;
2214 if ((!isUnconstraintTemplate(srcA.type) || !isUnconstraintTemplate(dstA.type)) && srcA.type!=dstA.type) // different constraints -> overload
2215 {
2216 AUTO_TRACE_EXIT("different constraints");
2217 return false;
2218 }
2219 ++srcIt;
2220 ++dstIt;
2221 }
2222 AUTO_TRACE_EXIT("same");
2223 // no overload with respect to the template parameters
2224 return true;
2225}
#define AUTO_TRACE_EXIT(...)
Definition docnode.cpp:48

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

2053{
2054 AUTO_TRACE("srcAl='{}',dstAl='{}',forceNameOverwrite={}",
2055 qPrint(argListToString(srcAl)),qPrint(argListToString(dstAl)),forceNameOverwrite);
2056
2057 if (srcAl.size()!=dstAl.size())
2058 {
2059 return; // invalid argument lists -> do not merge
2060 }
2061
2062 auto srcIt=srcAl.begin();
2063 auto dstIt=dstAl.begin();
2064 while (srcIt!=srcAl.end() && dstIt!=dstAl.end())
2065 {
2066 Argument &srcA = *srcIt;
2067 Argument &dstA = *dstIt;
2068
2069 AUTO_TRACE_ADD("before merge: src=[type='{}',name='{}',def='{}'] dst=[type='{}',name='{}',def='{}']",
2070 srcA.type,srcA.name,srcA.defval,
2071 dstA.type,dstA.name,dstA.defval);
2072 if (srcA.defval.isEmpty() && !dstA.defval.isEmpty())
2073 {
2074 //printf("Defval changing '%s'->'%s'\n",qPrint(srcA.defval),qPrint(dstA.defval));
2075 srcA.defval=dstA.defval;
2076 }
2077 else if (!srcA.defval.isEmpty() && dstA.defval.isEmpty())
2078 {
2079 //printf("Defval changing '%s'->'%s'\n",qPrint(dstA.defval),qPrint(srcA.defval));
2080 dstA.defval=srcA.defval;
2081 }
2082
2083 // fix wrongly detected const or volatile specifiers before merging.
2084 // example: "const A *const" is detected as type="const A *" name="const"
2085 if (srcA.name=="const" || srcA.name=="volatile")
2086 {
2087 srcA.type+=" "+srcA.name;
2088 srcA.name.clear();
2089 }
2090 if (dstA.name=="const" || dstA.name=="volatile")
2091 {
2092 dstA.type+=" "+dstA.name;
2093 dstA.name.clear();
2094 }
2095
2096 if (srcA.type==dstA.type)
2097 {
2098 //printf("1. merging %s:%s <-> %s:%s\n",qPrint(srcA.type),qPrint(srcA.name),qPrint(dstA.type),qPrint(dstA.name));
2099 if (srcA.name.isEmpty() && !dstA.name.isEmpty())
2100 {
2101 //printf("type: '%s':='%s'\n",qPrint(srcA.type),qPrint(dstA.type));
2102 //printf("name: '%s':='%s'\n",qPrint(srcA.name),qPrint(dstA.name));
2103 srcA.type = dstA.type;
2104 srcA.name = dstA.name;
2105 }
2106 else if (!srcA.name.isEmpty() && dstA.name.isEmpty())
2107 {
2108 //printf("type: '%s':='%s'\n",qPrint(dstA.type),qPrint(srcA.type));
2109 //printf("name: '%s':='%s'\n",qPrint(dstA.name),qPrint(srcA.name));
2110 dstA.type = srcA.type;
2111 dstA.name = srcA.name;
2112 }
2113 else if (!srcA.name.isEmpty() && !dstA.name.isEmpty())
2114 {
2115 //printf("srcA.name=%s dstA.name=%s\n",qPrint(srcA.name),qPrint(dstA.name));
2116 if (forceNameOverwrite)
2117 {
2118 srcA.name = dstA.name;
2119 }
2120 else
2121 {
2122 if (srcA.docs.isEmpty() && !dstA.docs.isEmpty())
2123 {
2124 srcA.name = dstA.name;
2125 }
2126 else if (!srcA.docs.isEmpty() && dstA.docs.isEmpty())
2127 {
2128 dstA.name = srcA.name;
2129 }
2130 }
2131 }
2132 }
2133 else
2134 {
2135 //printf("2. merging '%s':'%s' <-> '%s':'%s'\n",qPrint(srcA.type),qPrint(srcA.name),qPrint(dstA.type),qPrint(dstA.name));
2136 srcA.type=srcA.type.stripWhiteSpace();
2137 dstA.type=dstA.type.stripWhiteSpace();
2138 if (srcA.type+" "+srcA.name==dstA.type) // "unsigned long:int" <-> "unsigned long int:bla"
2139 {
2140 srcA.type+=" "+srcA.name;
2141 srcA.name=dstA.name;
2142 }
2143 else if (dstA.type+" "+dstA.name==srcA.type) // "unsigned long int bla" <-> "unsigned long int"
2144 {
2145 dstA.type+=" "+dstA.name;
2146 dstA.name=srcA.name;
2147 }
2148 else if (srcA.name.isEmpty() && !dstA.name.isEmpty())
2149 {
2150 srcA.name = dstA.name;
2151 }
2152 else if (dstA.name.isEmpty() && !srcA.name.isEmpty())
2153 {
2154 dstA.name = srcA.name;
2155 }
2156 }
2157 int i1=srcA.type.find("::"),
2158 i2=dstA.type.find("::"),
2159 j1=static_cast<int>(srcA.type.length())-i1-2,
2160 j2=static_cast<int>(dstA.type.length())-i2-2;
2161 if (i1!=-1 && i2==-1 && srcA.type.right(j1)==dstA.type)
2162 {
2163 //printf("type: '%s':='%s'\n",qPrint(dstA.type),qPrint(srcA.type));
2164 //printf("name: '%s':='%s'\n",qPrint(dstA.name),qPrint(srcA.name));
2165 dstA.type = srcA.type.left(i1+2)+dstA.type;
2166 dstA.name = srcA.name;
2167 }
2168 else if (i1==-1 && i2!=-1 && dstA.type.right(j2)==srcA.type)
2169 {
2170 //printf("type: '%s':='%s'\n",qPrint(srcA.type),qPrint(dstA.type));
2171 //printf("name: '%s':='%s'\n",qPrint(dstA.name),qPrint(srcA.name));
2172 srcA.type = dstA.type.left(i2+2)+srcA.type;
2173 srcA.name = dstA.name;
2174 }
2175 if (srcA.docs.isEmpty() && !dstA.docs.isEmpty())
2176 {
2177 srcA.docs = dstA.docs;
2178 }
2179 else if (dstA.docs.isEmpty() && !srcA.docs.isEmpty())
2180 {
2181 dstA.docs = srcA.docs;
2182 }
2183 //printf("Merge argument '%s|%s' '%s|%s'\n",
2184 // qPrint(srcA.type), qPrint(srcA.name),
2185 // qPrint(dstA.type), qPrint(dstA.name));
2186 ++srcIt;
2187 ++dstIt;
2188 AUTO_TRACE_ADD("after merge: src=[type='{}',name='{}',def='{}'] dst=[type='{}',name='{}',def='{}']",
2189 srcA.type,srcA.name,srcA.defval,
2190 dstA.type,dstA.name,dstA.defval);
2191 }
2192}
#define AUTO_TRACE_ADD(...)
Definition docnode.cpp:47
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 7337 of file util.cpp.

7338{
7339 if (Config_getBool(CALL_GRAPH) !=md1->hasCallGraph()) md2->overrideCallGraph(md1->hasCallGraph());
7340 if (Config_getBool(CALLER_GRAPH)!=md1->hasCallerGraph()) md2->overrideCallerGraph(md1->hasCallerGraph());
7341 if (Config_getBool(CALL_GRAPH) !=md2->hasCallGraph()) md1->overrideCallGraph( md2->hasCallGraph());
7342 if (Config_getBool(CALLER_GRAPH)!=md2->hasCallerGraph()) md1->overrideCallerGraph(md2->hasCallerGraph());
7343
7344 if (Config_getBool(SHOW_ENUM_VALUES) !=md1->hasEnumValues()) md2->overrideEnumValues(md1->hasEnumValues());
7345 if (Config_getBool(SHOW_ENUM_VALUES) !=md2->hasEnumValues()) md1->overrideEnumValues( md2->hasEnumValues());
7346
7347 if (Config_getBool(REFERENCED_BY_RELATION)!=md1->hasReferencedByRelation()) md2->overrideReferencedByRelation(md1->hasReferencedByRelation());
7348 if (Config_getBool(REFERENCES_RELATION) !=md1->hasReferencesRelation()) md2->overrideReferencesRelation(md1->hasReferencesRelation());
7349 if (Config_getBool(REFERENCED_BY_RELATION)!=md2->hasReferencedByRelation()) md1->overrideReferencedByRelation(md2->hasReferencedByRelation());
7350 if (Config_getBool(REFERENCES_RELATION) !=md2->hasReferencesRelation()) md1->overrideReferencesRelation(md2->hasReferencesRelation());
7351
7352 if (Config_getBool(INLINE_SOURCES)!=md1->hasInlineSource()) md2->overrideInlineSource(md1->hasInlineSource());
7353 if (Config_getBool(INLINE_SOURCES)!=md2->hasInlineSource()) md1->overrideInlineSource(md2->hasInlineSource());
7354}
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 5089 of file util.cpp.

5090{
5091 AUTO_TRACE("leftScope='{}' rightScope='{}'",leftScope,rightScope);
5092 // case leftScope=="A" rightScope=="A::B" => result = "A::B"
5093 if (leftScopeMatch(leftScope,rightScope))
5094 {
5095 AUTO_TRACE_EXIT("case1={}",rightScope);
5096 return rightScope;
5097 }
5098 QCString result;
5099 int i=0,p=static_cast<int>(leftScope.length());
5100
5101 // case leftScope=="A::B" rightScope=="B::C" => result = "A::B::C"
5102 // case leftScope=="A::B" rightScope=="B" => result = "A::B"
5103 bool found=FALSE;
5104 while ((i=leftScope.findRev("::",p))>0)
5105 {
5106 if (leftScopeMatch(rightScope,leftScope.right(leftScope.length()-i-2)))
5107 {
5108 result = leftScope.left(i+2)+rightScope;
5109 found=TRUE;
5110 }
5111 p=i-1;
5112 }
5113 if (found)
5114 {
5115 AUTO_TRACE_EXIT("case2={}",result);
5116 return result;
5117 }
5118
5119 // case leftScope=="A" rightScope=="B" => result = "A::B"
5120 result=leftScope;
5121 if (!result.isEmpty() && !rightScope.isEmpty()) result+="::";
5122 result+=rightScope;
5123 AUTO_TRACE_EXIT("case3={}",result);
5124 return result;
5125}
bool leftScopeMatch(const QCString &scope, const QCString &name)
Definition util.cpp:892

References AUTO_TRACE, AUTO_TRACE_EXIT, FALSE, QCString::findRev(), found, 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 4795 of file util.cpp.

4799{
4800 // skip until <
4801 int p=name.find('<');
4802 if (p==-1) return name;
4803 p++;
4804 QCString result = name.left(p);
4805
4806 std::string s = name.mid(p).str();
4807 static const reg::Ex re(R"([\a:][\w:]*)");
4808 reg::Iterator it(s,re);
4810 size_t pi=0;
4811 // for each identifier in the template part (e.g. B<T> -> T)
4812 for (; it!=end ; ++it)
4813 {
4814 const auto &match = *it;
4815 size_t i = match.position();
4816 size_t l = match.length();
4817 result += s.substr(pi,i-pi);
4818 QCString n(match.str());
4819 bool found=FALSE;
4820 for (const Argument &formArg : formalArgs)
4821 {
4822 if (formArg.name == n)
4823 {
4824 found=TRUE;
4825 break;
4826 }
4827 }
4828 if (!found)
4829 {
4830 // try to resolve the type
4831 SymbolResolver resolver;
4832 const ClassDef *cd = resolver.resolveClass(context,n);
4833 if (cd)
4834 {
4835 result+=cd->name();
4836 }
4837 else
4838 {
4839 result+=n;
4840 }
4841 }
4842 else
4843 {
4844 result+=n;
4845 }
4846 pi=i+l;
4847 }
4848 result+=s.substr(pi);
4849 //printf("normalizeNonTemplateArgumentInString(%s)=%s\n",qPrint(name),qPrint(result));
4850 return removeRedundantWhiteSpace(result);
4851}
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(), found, 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 6772 of file util.cpp.

6773{
6774 assert(!f.is_open());
6775 bool fileOpened=FALSE;
6776 bool writeToStdout=outFile=="-";
6777 if (writeToStdout) // write to stdout
6778 {
6779 f.basic_ios<char>::rdbuf(std::cout.rdbuf());
6780 fileOpened = true;
6781 }
6782 else // write to file
6783 {
6784 FileInfo fi(outFile.str());
6785 if (fi.exists()) // create a backup
6786 {
6787 Dir dir;
6788 FileInfo backup(fi.filePath()+".bak");
6789 if (backup.exists()) // remove existing backup
6790 dir.remove(backup.filePath());
6791 dir.rename(fi.filePath(),fi.filePath()+".bak");
6792 }
6793 f = Portable::openOutputStream(outFile);
6794 fileOpened = f.is_open();
6795 }
6796 return fileOpened;
6797}
bool remove(const std::string &path, bool acceptsAbsPath=true) const
Definition dir.cpp:314
bool rename(const std::string &orgName, const std::string &newName, bool acceptsAbsPath=true) const
Definition dir.cpp:321
std::ofstream openOutputStream(const QCString &name, bool append=false)
Definition portable.cpp:665

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

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

◆ parseCommentAsText()

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

Definition at line 5872 of file util.cpp.

5874{
5875 if (doc.isEmpty()) return "";
5876 //printf("parseCommentAsText(%s)\n",qPrint(doc));
5877 TextStream t;
5878 auto parser { createDocParser() };
5879 auto ast { validatingParseDoc(*parser.get(),
5880 fileName,lineNr,
5881 scope,md,doc,FALSE,FALSE,
5882 QCString(),FALSE,FALSE,Config_getBool(MARKDOWN_SUPPORT)) };
5883 auto astImpl = dynamic_cast<const DocNodeAST*>(ast.get());
5884 if (astImpl)
5885 {
5886 TextDocVisitor visitor(t);
5887 std::visit(visitor,astImpl->root);
5888 }
5889 QCString result = convertCharEntitiesToUTF8(t.str().c_str()).stripWhiteSpace();
5890 int i=0;
5891 int charCnt=0;
5892 int l=static_cast<int>(result.length());
5893 while ((i=nextUTF8CharPosition(result,l,i))<l)
5894 {
5895 charCnt++;
5896 if (charCnt>=80) break;
5897 }
5898 if (charCnt>=80) // try to truncate the string
5899 {
5900 while ((i=nextUTF8CharPosition(result,l,i))<l && charCnt<100)
5901 {
5902 charCnt++;
5903 if (result.at(i)==',' ||
5904 result.at(i)=='.' ||
5905 result.at(i)=='!' ||
5906 result.at(i)=='?' ||
5907 result.at(i)=='}') // good for UTF-16 characters and } otherwise also a good point to stop the string
5908 {
5909 i++; // we want to be "behind" last inspected character
5910 break;
5911 }
5912 }
5913 }
5914 if ( i < l) result=result.left(i)+"...";
5915 return result.data();
5916}
Class representing the abstract syntax tree of a documentation block.
Definition docnode.h:1460
Concrete visitor implementation for TEXT output.
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:229
IDocParserPtr createDocParser()
factory function to create a parser
Definition docparser.cpp:55
IDocNodeASTPtr validatingParseDoc(IDocParser &parserIntf, const QCString &fileName, int startLine, const Definition *ctx, const MemberDef *md, const QCString &input, bool indexWords, bool isExample, const QCString &exampleName, bool singleLine, bool linkFromIndex, bool markdownSupport)
static int nextUTF8CharPosition(const QCString &utf8Str, uint32_t len, uint32_t startPos)
Definition util.cpp:5828

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

Referenced by PageDefImpl::addSectionsToIndex(), and DefinitionImpl::computeTooltip().

◆ patternMatch()

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

Definition at line 6166 of file util.cpp.

6167{
6168 std::string elem;
6169 auto getter = [](std::string s) { return QCString(s); };
6170 return genericPatternMatch(fi,patList,elem,getter);
6171}

References genericPatternMatch().

Referenced by checkAndOpenFile(), and readDir().

◆ processMarkup()

QCString processMarkup ( const QCString & s)

◆ projectLogoFile()

QCString projectLogoFile ( )

Definition at line 3650 of file util.cpp.

3651{
3652 QCString projectLogo = Config_getString(PROJECT_LOGO);
3653 if (!projectLogo.isEmpty())
3654 {
3655 // check for optional width= and height= specifier
3656 int wi = projectLogo.find(" width=");
3657 if (wi!=-1) // and strip them
3658 {
3659 projectLogo = projectLogo.left(wi);
3660 }
3661 int hi = projectLogo.find(" height=");
3662 if (hi!=-1)
3663 {
3664 projectLogo = projectLogo.left(hi);
3665 }
3666 }
3667 //printf("projectlogo='%s'\n",qPrint(projectLogo));
3668 return projectLogo;
3669}

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

Referenced by copyLogo(), and substituteKeywords().

◆ protectionLevelVisible()

bool protectionLevelVisible ( Protection prot)

Definition at line 6415 of file util.cpp.

6416{
6417 bool extractPrivate = Config_getBool(EXTRACT_PRIVATE);
6418 bool extractPackage = Config_getBool(EXTRACT_PACKAGE);
6419
6420 return (prot!=Protection::Private && prot!=Protection::Package) ||
6421 (prot==Protection::Private && extractPrivate) ||
6422 (prot==Protection::Package && extractPackage);
6423}

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

6007{
6008 // try to open file
6009 FileInfo fi(fileName.str());
6010 if (!fi.exists()) return FALSE;
6011 QCString filterName = getFileFilter(fileName,isSourceCode);
6012 if (filterName.isEmpty() || !filter)
6013 {
6014 std::ifstream f = Portable::openInputStream(fileName,true);
6015 if (!f.is_open())
6016 {
6017 err("could not open file {}\n",fileName);
6018 return FALSE;
6019 }
6020 // read the file
6021 auto fileSize = fi.size();
6022 contents.resize(fileSize);
6023 f.read(contents.data(),fileSize);
6024 if (f.fail())
6025 {
6026 err("problems while reading file {}\n",fileName);
6027 return FALSE;
6028 }
6029 }
6030 else
6031 {
6032 QCString cmd=filterName+" \""+fileName+"\"";
6033 Debug::print(Debug::ExtCmd,0,"Executing popen(`{}`)\n",cmd);
6034 FILE *f=Portable::popen(cmd,"r");
6035 if (!f)
6036 {
6037 err("could not execute filter {}\n",filterName);
6038 return FALSE;
6039 }
6040 const int bufSize=4096;
6041 char buf[bufSize];
6042 int numRead = 0;
6043 while ((numRead=static_cast<int>(fread(buf,1,bufSize,f)))>0)
6044 {
6045 //printf(">>>>>>>>Reading %d bytes\n",numRead);
6046 contents.append(buf,numRead);
6047 }
6049 Debug::print(Debug::FilterOutput, 0, "Filter output\n");
6050 Debug::print(Debug::FilterOutput,0,"-------------\n{}\n-------------\n",contents);
6051 }
6052
6053 if (contents.size()>=2 &&
6054 static_cast<uint8_t>(contents[0])==0xFF &&
6055 static_cast<uint8_t>(contents[1])==0xFE // Little endian BOM
6056 ) // UCS-2LE encoded file
6057 {
6058 transcodeCharacterBuffer(fileName,contents,"UCS-2LE","UTF-8");
6059 }
6060 else if (contents.size()>=2 &&
6061 static_cast<uint8_t>(contents[0])==0xFE &&
6062 static_cast<uint8_t>(contents[1])==0xFF // big endian BOM
6063 ) // UCS-2BE encoded file
6064 {
6065 transcodeCharacterBuffer(fileName,contents,"UCS-2BE","UTF-8");
6066 }
6067 else if (contents.size()>=3 &&
6068 static_cast<uint8_t>(contents[0])==0xEF &&
6069 static_cast<uint8_t>(contents[1])==0xBB &&
6070 static_cast<uint8_t>(contents[2])==0xBF
6071 ) // UTF-8 encoded file
6072 {
6073 contents.erase(0,3); // remove UTF-8 BOM: no translation needed
6074 }
6075 else // transcode according to the INPUT_ENCODING setting
6076 {
6077 // do character transcoding if needed.
6078 transcodeCharacterBuffer(fileName,contents,getEncoding(fi),"UTF-8");
6079 }
6080
6081 filterCRLF(contents);
6082 return true;
6083}
@ 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:676
FILE * popen(const QCString &name, const QCString &type)
Definition portable.cpp:496
int pclose(FILE *stream)
Definition portable.cpp:505
static void filterCRLF(std::string &contents)
Definition util.cpp:1302
static void transcodeCharacterBuffer(const QCString &fileName, std::string &contents, const QCString &inputEncoding, const QCString &outputEncoding)
Definition util.cpp:5970
QCString getEncoding(const FileInfo &fi)
Definition util.cpp:6173
QCString getFileFilter(const QCString &name, bool isSourceCode)
Definition util.cpp:1369

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 checkAndOpenFile(), fileToString(), HtmlDocVisitor::operator()(), RTFDocVisitor::operator()(), parseFile(), parseInput(), readIncludeFile(), 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 6819 of file util.cpp.

6820{
6821 int column=0;
6822 bool skipLine=FALSE;
6823
6824 if (format == FortranFormat::Fixed) return TRUE;
6825 if (format == FortranFormat::Free) return FALSE;
6826
6827 int tabSize=Config_getInt(TAB_SIZE);
6828 size_t sizCont = contents.length();
6829 for (size_t i=0;i<sizCont;i++)
6830 {
6831 column++;
6832
6833 switch(contents.at(i))
6834 {
6835 case '\n':
6836 column=0;
6837 skipLine=FALSE;
6838 break;
6839 case '\t':
6840 column += tabSize-1;
6841 break;
6842 case ' ':
6843 break;
6844 case '\000':
6845 return FALSE;
6846 case '#':
6847 skipLine=TRUE;
6848 break;
6849 case 'C':
6850 case 'c':
6851 if (column==1)
6852 {
6853 return !keyWordsFortranC(contents.data()+i);
6854 }
6855 // fallthrough
6856 case '*':
6857 if (column==1) return TRUE;
6858 if (skipLine) break;
6859 return FALSE;
6860 case '!':
6861 if (column!=6) skipLine=TRUE;
6862 break;
6863 default:
6864 if (skipLine) break;
6865 if (column>=7) return TRUE;
6866 return FALSE;
6867 }
6868 }
6869 return FALSE;
6870}
static bool keyWordsFortranC(const char *contents)
Definition util.cpp:6799

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

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

◆ relativePathToRoot()

QCString relativePathToRoot ( const QCString & name)

Definition at line 4088 of file util.cpp.

4089{
4090 QCString result;
4091 if (Config_getBool(CREATE_SUBDIRS))
4092 {
4093 if (name.isEmpty())
4094 {
4095 return REL_PATH_TO_ROOT;
4096 }
4097 else
4098 {
4099 int i = name.findRev('/');
4100 if (i!=-1)
4101 {
4102 result=REL_PATH_TO_ROOT;
4103 }
4104 }
4105 }
4106 return result;
4107}
#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 172 of file util.cpp.

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

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

7063{
7064 std::string out;
7065 out.reserve(s.length());
7066 const char *p=s.data();
7067 if (p)
7068 {
7069 char c = 0;
7070 while ((c=*p++))
7071 {
7072 if (c=='\n')
7073 {
7074 const char *e = p;
7075 while (*e==' ' || *e=='\t') e++;
7076 if (*e=='\n')
7077 {
7078 p=e;
7079 }
7080 else out+=c;
7081 }
7082 else
7083 {
7084 out+=c;
7085 }
7086 }
7087 }
7088 //printf("removeEmptyLines(%s)=%s\n",qPrint(s),qPrint(out));
7089 return out;
7090}

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

Referenced by substituteHtmlKeywords(), and substituteLatexKeywords().

◆ removeLongPathMarker()

QCString removeLongPathMarker ( QCString path)

Definition at line 298 of file util.cpp.

299{
300#if defined(_WIN32)
301 if (path.startsWith("//?/")) // strip leading "\\?\" part from path
302 {
303 path=path.mid(4);
304 }
305#endif
306 return path;
307}

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

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

◆ removeRedundantWhiteSpace()

QCString removeRedundantWhiteSpace ( const QCString & s)

Definition at line 578 of file util.cpp.

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

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

Referenced by addFrom(), addGlobalFunction(), addMethodToClass(), addVariable(), addVariableToClass(), argListToString(), buildFunctionList(), buildInterfaceAndServiceList(), buildTypedefList(), ClassDefImpl::ClassDefImpl(), extractCanonicalType(), findClassRelation(), DocParser::findDocsForMemberOrCompound(), findMember(), findUsedClassesForClass(), findUsingDeclImports(), generateFunctionLink(), generateFunctionLink(), generateLink(), 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 229 of file util.cpp.

230{
231 if (s.isEmpty()) return s;
232 static const reg::Ex marker(R"(@\d+)");
233 std::string result = reg::replace(s.str(),marker,
234 !replacement.isEmpty() ? replacement.data() : "__anonymous__");
235 //printf("replaceAnonymousScopes('%s')='%s'\n",qPrint(s),qPrint(result));
236 return QCString(result);
237}
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:770

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

6285{
6286 if (str.isEmpty()) return QCString();
6287 std::string result;
6288 std::string s=str.str();
6289 static const reg::Ex re(R"(##[0-9A-Fa-f][0-9A-Fa-f])");
6290 reg::Iterator it(s,re);
6292 int hue = Config_getInt(HTML_COLORSTYLE_HUE);
6293 int sat = Config_getInt(HTML_COLORSTYLE_SAT);
6294 int gamma = Config_getInt(HTML_COLORSTYLE_GAMMA);
6295 size_t sl=s.length();
6296 size_t p=0;
6297 for (; it!=end ; ++it)
6298 {
6299 const auto &match = *it;
6300 size_t i = match.position();
6301 size_t l = match.length();
6302 if (i>p) result+=s.substr(p,i-p);
6303 std::string lumStr = match.str().substr(2);
6304#define HEXTONUM(x) (((x)>='0' && (x)<='9') ? ((x)-'0') : \
6305 ((x)>='a' && (x)<='f') ? ((x)-'a'+10) : \
6306 ((x)>='A' && (x)<='F') ? ((x)-'A'+10) : 0)
6307
6308 double r = 0,g = 0,b = 0;
6309 int level = HEXTONUM(lumStr[0])*16+HEXTONUM(lumStr[1]);
6310 ColoredImage::hsl2rgb(hue/360.0,sat/255.0,
6311 pow(level/255.0,gamma/100.0),&r,&g,&b);
6312 int red = static_cast<int>(r*255.0);
6313 int green = static_cast<int>(g*255.0);
6314 int blue = static_cast<int>(b*255.0);
6315 char colStr[8];
6316 colStr[0]='#';
6317 colStr[1]=hex[red>>4];
6318 colStr[2]=hex[red&0xf];
6319 colStr[3]=hex[green>>4];
6320 colStr[4]=hex[green&0xf];
6321 colStr[5]=hex[blue>>4];
6322 colStr[6]=hex[blue&0xf];
6323 colStr[7]=0;
6324 //printf("replacing %s->%s (level=%d)\n",qPrint(lumStr),colStr,level);
6325 result+=colStr;
6326 p=i+l;
6327 }
6328 if (p<sl) result+=s.substr(p);
6329 return QCString(result);
6330}
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 3245 of file util.cpp.

3253{
3254 *resContext=nullptr;
3255
3256 QCString linkRef=lr;
3257 if (lang==SrcLangExt::CSharp)
3258 {
3259 linkRef = mangleCSharpGenericName(linkRef);
3260 }
3261 QCString linkRefWithoutTemplates = stripTemplateSpecifiersFromScope(linkRef,FALSE);
3262 AUTO_TRACE("scName='{}',ref='{}'",scName,lr);
3263 const FileDef *fd = nullptr;
3264 const GroupDef *gd = nullptr;
3265 const PageDef *pd = nullptr;
3266 const ClassDef *cd = nullptr;
3267 const DirDef *dir = nullptr;
3268 const ConceptDef *cnd = nullptr;
3269 const ModuleDef *modd = nullptr;
3270 const NamespaceDef *nd = nullptr;
3271 const SectionInfo *si = nullptr;
3272 bool ambig = false;
3273 if (linkRef.isEmpty()) // no reference name!
3274 {
3275 AUTO_TRACE_EXIT("no_ref");
3276 return FALSE;
3277 }
3278 else if ((pd=Doxygen::pageLinkedMap->find(linkRef))) // link to a page
3279 {
3280 gd = pd->getGroupDef();
3281 if (gd)
3282 {
3283 if (!pd->name().isEmpty()) si=SectionManager::instance().find(pd->name());
3284 *resContext=gd;
3285 if (si) resAnchor = si->label();
3286 }
3287 else
3288 {
3289 *resContext=pd;
3290 }
3291 AUTO_TRACE_EXIT("page");
3292 return TRUE;
3293 }
3294 else if ((si=SectionManager::instance().find(prefix+linkRef)))
3295 {
3296 *resContext=si->definition();
3297 resAnchor = si->label();
3298 AUTO_TRACE_EXIT("section");
3299 return TRUE;
3300 }
3301 else if ((pd=Doxygen::exampleLinkedMap->find(linkRef))) // link to an example
3302 {
3303 *resContext=pd;
3304 AUTO_TRACE_EXIT("example");
3305 return TRUE;
3306 }
3307 else if ((gd=Doxygen::groupLinkedMap->find(linkRef))) // link to a group
3308 {
3309 *resContext=gd;
3310 AUTO_TRACE_EXIT("group");
3311 return TRUE;
3312 }
3313 else if ((fd=findFileDef(Doxygen::inputNameLinkedMap,linkRef,ambig)) // file link
3314 && fd->isLinkable())
3315 {
3316 *resContext=fd;
3317 AUTO_TRACE_EXIT("file");
3318 return TRUE;
3319 }
3320 else if ((cd=getClass(linkRef))) // class link
3321 {
3322 *resContext=cd;
3323 resAnchor=cd->anchor();
3324 AUTO_TRACE_EXIT("class");
3325 return TRUE;
3326 }
3327 else if (lang==SrcLangExt::Java &&
3328 (cd=getClass(linkRefWithoutTemplates))) // Java generic class link
3329 {
3330 *resContext=cd;
3331 resAnchor=cd->anchor();
3332 AUTO_TRACE_EXIT("generic");
3333 return TRUE;
3334 }
3335 else if ((cd=getClass(linkRef+"-p"))) // Obj-C protocol link
3336 {
3337 *resContext=cd;
3338 resAnchor=cd->anchor();
3339 AUTO_TRACE_EXIT("protocol");
3340 return TRUE;
3341 }
3342 else if ((cnd=getConcept(linkRef))) // C++20 concept definition
3343 {
3344 *resContext=cnd;
3345 resAnchor=cnd->anchor();
3346 AUTO_TRACE_EXIT("concept");
3347 return TRUE;
3348 }
3349 else if ((modd=ModuleManager::instance().modules().find(linkRef)))
3350 {
3351 *resContext=modd;
3352 resAnchor=modd->anchor();
3353 AUTO_TRACE_EXIT("module");
3354 return TRUE;
3355 }
3356 else if ((nd=Doxygen::namespaceLinkedMap->find(linkRef)))
3357 {
3358 *resContext=nd;
3359 AUTO_TRACE_EXIT("namespace");
3360 return TRUE;
3361 }
3362 else if ((dir=Doxygen::dirLinkedMap->find(FileInfo(linkRef.str()).absFilePath()+"/"))
3363 && dir->isLinkable()) // TODO: make this location independent like filedefs
3364 {
3365 *resContext=dir;
3366 AUTO_TRACE_EXIT("directory");
3367 return TRUE;
3368 }
3369 else // probably a member reference
3370 {
3371 const MemberDef *md = nullptr;
3372 bool res = resolveRef(scName,lr,TRUE,resContext,&md,lang);
3373 if (md) resAnchor=md->anchor();
3374 AUTO_TRACE_EXIT("member? res={}",res);
3375 return res;
3376 }
3377}
virtual QCString anchor() const =0
A model of a directory symbol.
Definition dirdef.h:110
static NamespaceLinkedMap * namespaceLinkedMap
Definition doxygen.h:115
static PageLinkedMap * exampleLinkedMap
Definition doxygen.h:99
static DirLinkedMap * dirLinkedMap
Definition doxygen.h:129
static GroupLinkedMap * groupLinkedMap
Definition doxygen.h:114
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
ConceptDef * getConcept(const QCString &n)
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:2964
QCString mangleCSharpGenericName(const QCString &name)
Definition util.cpp:7389
QCString stripTemplateSpecifiersFromScope(const QCString &fullName, bool parentOnly, QCString *pLastScopeStripped, QCString scopeName, bool allowArtificial)
Definition util.cpp:5022

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

2974{
2975 AUTO_TRACE("scope={} name={} inSeeBlock={}",scName,name,inSeeBlock);
2976 //printf("resolveRef(scope=%s,name=%s,inSeeBlock=%d)\n",qPrint(scName),qPrint(name),inSeeBlock);
2977 QCString tsName = name;
2978 //bool memberScopeFirst = tsName.find('#')!=-1;
2979 QCString fullName = substitute(tsName,"#","::");
2980 if (fullName.find("anonymous_namespace{")==-1)
2981 {
2982 fullName = removeRedundantWhiteSpace(substitute(fullName,".","::",3));
2983 }
2984 else
2985 {
2986 fullName = removeRedundantWhiteSpace(fullName);
2987 }
2988
2989 int templStartPos;
2990 if (lang==SrcLangExt::CSharp && (templStartPos=fullName.find('<'))!=-1)
2991 {
2992 int templEndPos = fullName.findRev('>');
2993 if (templEndPos!=-1)
2994 {
2995 fullName = mangleCSharpGenericName(fullName.left(templEndPos+1))+fullName.mid(templEndPos+1);
2996 AUTO_TRACE_ADD("C# mangled name='{}'",fullName);
2997 }
2998 }
2999
3000 int bracePos=findParameterList(fullName);
3001 int endNamePos=bracePos!=-1 ? bracePos : static_cast<int>(fullName.length());
3002 int scopePos=fullName.findRev("::",endNamePos);
3003 bool explicitScope = fullName.startsWith("::") && // ::scope or #scope
3004 (scopePos>2 || // ::N::A
3005 tsName.startsWith("::") || // ::foo in local scope
3006 scName==nullptr // #foo in global scope
3007 );
3008 bool allowTypeOnly=false;
3009
3010 // default result values
3011 *resContext=nullptr;
3012 *resMember=nullptr;
3013
3014 if (bracePos==-1) // simple name
3015 {
3016 // the following if() was commented out for releases in the range
3017 // 1.5.2 to 1.6.1, but has been restored as a result of bug report 594787.
3018 if (!inSeeBlock && scopePos==-1 && isLowerCase(tsName))
3019 { // link to lower case only name => do not try to autolink
3020 AUTO_TRACE_ADD("false");
3021 return FALSE;
3022 }
3023
3024 ClassDef *cd=nullptr;
3025 NamespaceDef *nd=nullptr;
3026 ConceptDef *cnd=nullptr;
3027 ModuleDef *modd=nullptr;
3028
3029 //printf("scName=%s fullName=%s\n",qPrint(scName),qPrint(fullName));
3030
3031 // check if this is a class or namespace reference
3032 if (scName!=fullName && getScopeDefs(scName,fullName,cd,cnd,nd,modd))
3033 {
3034 //printf("found scopeDef\n");
3035 if (cd) // scope matches that of a class
3036 {
3037 *resContext = cd;
3038 }
3039 else if (cnd)
3040 {
3041 *resContext = cnd;
3042 }
3043 else if (modd)
3044 {
3045 *resContext = modd;
3046 }
3047 else // scope matches that of a namespace
3048 {
3049 ASSERT(nd!=nullptr);
3050 *resContext = nd;
3051 }
3052 AUTO_TRACE_ADD("true");
3053 return TRUE;
3054 }
3055 else if (scName==fullName || (!inSeeBlock && scopePos==-1))
3056 // nothing to link => output plain text
3057 {
3058 //printf("found scName=%s fullName=%s scName==fullName=%d "
3059 // "inSeeBlock=%d scopePos=%d!\n",
3060 // qPrint(scName),qPrint(fullName),scName==fullName,inSeeBlock,scopePos);
3061
3062 // at this point we have a bare word that is not a class or namespace
3063 // we should also allow typedefs or enums to be linked, but not for instance member
3064 // functions, otherwise 'Foo' would always link to the 'Foo()' constructor instead of the
3065 // 'Foo' class. So we use this flag as a filter.
3066 allowTypeOnly=true;
3067 }
3068
3069 // continue search...
3070 }
3071
3072 // extract userscope+name
3073 QCString nameStr=fullName.left(endNamePos);
3074 if (explicitScope) nameStr=nameStr.mid(2);
3075
3076
3077 // extract arguments
3078 QCString argsStr;
3079 if (bracePos!=-1) argsStr=fullName.right(fullName.length()-bracePos);
3080
3081 // strip template specifier
3082 // TODO: match against the correct partial template instantiation
3083 int templPos=nameStr.find('<');
3084 bool tryUnspecializedVersion = FALSE;
3085 if (templPos!=-1 && nameStr.find("operator")==-1)
3086 {
3087 int endTemplPos=nameStr.findRev('>');
3088 if (endTemplPos!=-1)
3089 {
3090 if (!lookForSpecialization)
3091 {
3092 nameStr=nameStr.left(templPos)+nameStr.right(nameStr.length()-endTemplPos-1);
3093 }
3094 else
3095 {
3096 tryUnspecializedVersion = TRUE;
3097 }
3098 }
3099 }
3100
3101 QCString scopeStr=scName;
3102 if (nameStr.length()>scopeStr.length() && leftScopeMatch(scopeStr,nameStr))
3103 {
3104 nameStr=nameStr.mid(scopeStr.length()+2);
3105 }
3106
3107 const GroupDef *gd = nullptr;
3108 const ConceptDef *cnd = nullptr;
3109 const ModuleDef *modd = nullptr;
3110
3111 // check if nameStr is a member or global.
3112 //printf("getDefs(scope=%s,name=%s,args=%s checkScope=%d)\n",
3113 // qPrint(scopeStr), qPrint(nameStr), qPrint(argsStr),checkScope);
3114 GetDefInput input(scopeStr,nameStr,argsStr);
3115 input.forceEmptyScope = explicitScope;
3116 input.currentFile = currentFile;
3117 input.checkCV = true;
3118 GetDefResult result = getDefs(input);
3119 if (result.found)
3120 {
3121 //printf("after getDefs checkScope=%d nameStr=%s\n",checkScope,qPrint(nameStr));
3122 if (checkScope && result.md && result.md->getOuterScope()==Doxygen::globalScope &&
3123 !result.md->isStrongEnumValue() &&
3124 (!scopeStr.isEmpty() || nameStr.find("::")>0))
3125 {
3126 // we did find a member, but it is a global one while we were explicitly
3127 // looking for a scoped variable. See bug 616387 for an example why this check is needed.
3128 // note we do need to support autolinking to "::symbol" hence the >0
3129 //printf("not global member!\n");
3130 *resContext=nullptr;
3131 *resMember=nullptr;
3132 AUTO_TRACE_ADD("false");
3133 return FALSE;
3134 }
3135 //printf("after getDefs md=%p cd=%p fd=%p nd=%p gd=%p\n",md,cd,fd,nd,gd);
3136 if (result.md)
3137 {
3138 if (!allowTypeOnly || result.md->isTypedef() || result.md->isEnumerate())
3139 {
3140 *resMember=result.md;
3141 *resContext=result.md;
3142 }
3143 else // md is not a type, but we explicitly expect one
3144 {
3145 *resContext=nullptr;
3146 *resMember=nullptr;
3147 AUTO_TRACE_ADD("false");
3148 return FALSE;
3149 }
3150 }
3151 else if (result.cd) *resContext=result.cd;
3152 else if (result.nd) *resContext=result.nd;
3153 else if (result.fd) *resContext=result.fd;
3154 else if (result.gd) *resContext=result.gd;
3155 else if (result.cnd) *resContext=result.cnd;
3156 else if (result.modd) *resContext=result.modd;
3157 else
3158 {
3159 *resContext=nullptr; *resMember=nullptr;
3160 AUTO_TRACE_ADD("false");
3161 return FALSE;
3162 }
3163 //printf("member=%s (md=%p) anchor=%s linkable()=%d context=%s\n",
3164 // qPrint(md->name()), md, qPrint(md->anchor()), md->isLinkable(), qPrint((*resContext)->name()));
3165 AUTO_TRACE_ADD("true");
3166 return TRUE;
3167 }
3168 else if (inSeeBlock && !nameStr.isEmpty() && (gd=Doxygen::groupLinkedMap->find(nameStr)))
3169 { // group link
3170 *resContext=gd;
3171 AUTO_TRACE_ADD("true");
3172 return TRUE;
3173 }
3174 else if ((cnd=Doxygen::conceptLinkedMap->find(nameStr)))
3175 {
3176 *resContext=cnd;
3177 AUTO_TRACE_ADD("true");
3178 return TRUE;
3179 }
3180 else if ((modd=ModuleManager::instance().modules().find(nameStr)))
3181 {
3182 *resContext=modd;
3183 AUTO_TRACE_ADD("true");
3184 return TRUE;
3185 }
3186 else if (tsName.find('.')!=-1) // maybe a link to a file
3187 {
3188 bool ambig = false;
3189 const FileDef *fd=findFileDef(Doxygen::inputNameLinkedMap,tsName,ambig);
3190 if (fd && !ambig)
3191 {
3192 *resContext=fd;
3193 AUTO_TRACE_ADD("true");
3194 return TRUE;
3195 }
3196 }
3197
3198 if (tryUnspecializedVersion)
3199 {
3200 bool b = resolveRef(scName,name,inSeeBlock,resContext,resMember,lang,FALSE,nullptr,checkScope);
3201 AUTO_TRACE_ADD("{}",b);
3202 return b;
3203 }
3204 if (bracePos!=-1) // Try without parameters as well, could be a constructor invocation
3205 {
3206 *resContext=getClass(fullName.left(bracePos));
3207 if (*resContext)
3208 {
3209 AUTO_TRACE_ADD("true");
3210 return TRUE;
3211 }
3212 }
3213 //printf("resolveRef: %s not found!\n",qPrint(name));
3214
3215 AUTO_TRACE_ADD("false");
3216 return FALSE;
3217}
virtual Definition * getOuterScope() const =0
static ConceptLinkedMap * conceptLinkedMap
Definition doxygen.h:98
static NamespaceDefMutable * globalScope
Definition doxygen.h:121
virtual bool isStrongEnumValue() const =0
virtual bool isEnumerate() const =0
const ConceptDef * cnd
Definition util.h:130
const ModuleDef * modd
Definition util.h:131
static bool isLowerCase(QCString &s)
Definition util.cpp:2952
GetDefResult getDefs(const GetDefInput &input)
Definition util.cpp:2822
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:836
static bool getScopeDefs(const QCString &docScope, const QCString &scope, ClassDef *&cd, ConceptDef *&cnd, NamespaceDef *&nd, ModuleDef *&modd)
Definition util.cpp:2890

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

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

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

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

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

Referenced by addMemberFunction(), findScopeFromQualifiedName(), getDefsOld(), 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 6885 of file util.cpp.

6886{
6887 if (s.isEmpty()) return s;
6888
6889 // helper to find the end of a block
6890 auto skipBlock = [&markerInfo](const char *p,const SelectionBlock &blk)
6891 {
6892 char c = 0;
6893 while ((c=*p))
6894 {
6895 if (c==markerInfo.markerChar && qstrncmp(p,markerInfo.endStr,markerInfo.endLen)==0) // end marker
6896 {
6897 size_t len = markerInfo.endLen;
6898 bool negate = *(p+markerInfo.endLen)=='!';
6899 if (negate) len++;
6900 size_t blkNameLen = qstrlen(blk.name);
6901 if (qstrncmp(p+len,blk.name,blkNameLen)==0 && // matching marker name
6902 qstrncmp(p+len+blkNameLen,markerInfo.closeStr,markerInfo.closeLen)==0) // matching marker closing
6903 {
6904 //printf("Found end marker %s enabled=%d negate=%d\n",blk.name,blk.enabled,negate);
6905 return p+len+blkNameLen+markerInfo.closeLen;
6906 }
6907 else // not the right marker id
6908 {
6909 p++;
6910 }
6911 }
6912 else // not and end marker
6913 {
6914 p++;
6915 }
6916 }
6917 return p;
6918 };
6919
6920 QCString result;
6921 result.reserve(s.length());
6922 const char *p = s.data();
6923 char c = 0;
6924 while ((c=*p))
6925 {
6926 if (c==markerInfo.markerChar) // potential start of marker
6927 {
6928 if (qstrncmp(p,markerInfo.beginStr,markerInfo.beginLen)==0) // start of begin marker
6929 {
6930 bool found = false;
6931 size_t len = markerInfo.beginLen;
6932 bool negate = *(p+len)=='!';
6933 if (negate) len++;
6934 for (const auto &blk : blockList)
6935 {
6936 size_t blkNameLen = qstrlen(blk.name);
6937 if (qstrncmp(p+len,blk.name,blkNameLen)==0 && // matching marker name
6938 qstrncmp(p+len+blkNameLen,markerInfo.closeStr,markerInfo.closeLen)==0) // matching marker closing
6939 {
6940 bool blockEnabled = blk.enabled!=negate;
6941 //printf("Found start marker %s enabled=%d negate=%d\n",blk.name,blk.enabled,negate);
6942 p+=len+blkNameLen+markerInfo.closeLen;
6943 if (!blockEnabled) // skip until the end of the block
6944 {
6945 //printf("skipping block\n");
6946 p=skipBlock(p,blk);
6947 }
6948 found=true;
6949 break;
6950 }
6951 }
6952 if (!found) // unknown marker id
6953 {
6954 result+=c;
6955 p++;
6956 }
6957 }
6958 else if (qstrncmp(p,markerInfo.endStr,markerInfo.endLen)==0) // start of end marker
6959 {
6960 bool found = false;
6961 size_t len = markerInfo.endLen;
6962 bool negate = *(p+len)=='!';
6963 if (negate) len++;
6964 for (const auto &blk : blockList)
6965 {
6966 size_t blkNameLen = qstrlen(blk.name);
6967 if (qstrncmp(p+len,blk.name,blkNameLen)==0 && // matching marker name
6968 qstrncmp(p+len+blkNameLen,markerInfo.closeStr,markerInfo.closeLen)==0) // matching marker closing
6969 {
6970 //printf("Found end marker %s enabled=%d negate=%d\n",blk.name,blk.enabled,negate);
6971 p+=len+blkNameLen+markerInfo.closeLen;
6972 found=true;
6973 break;
6974 }
6975 }
6976 if (!found) // unknown marker id
6977 {
6978 result+=c;
6979 p++;
6980 }
6981 }
6982 else // not a start or end marker
6983 {
6984 result+=c;
6985 p++;
6986 }
6987 }
6988 else // not a marker character
6989 {
6990 result+=c;
6991 p++;
6992 }
6993 }
6994 //printf("====\n%s\n-----\n%s\n~~~~\n",qPrint(s),qPrint(result));
6995 return result;
6996}
void reserve(size_t size)
Reserve space for size bytes without changing the string contents.
Definition qcstring.h:172
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, found, 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 3534 of file util.cpp.

3535{
3536 QCString result;
3537 QCString name=n;
3538 QCString path;
3539 int slashPos=std::max(name.findRev('/'),name.findRev('\\'));
3540 if (slashPos!=-1)
3541 {
3542 path=name.left(slashPos+1);
3543 name=name.right(name.length()-slashPos-1);
3544 }
3545 const FileName *fn=fnMap->find(name);
3546 if (fn)
3547 {
3548 bool first = true;
3549 for (const auto &fd : *fn)
3550 {
3551 if (path.isEmpty() || fd->getPath().right(path.length())==path)
3552 {
3553 if (!first) result += "\n";
3554 else first = false;
3555 result+=" "+fd->absFilePath();
3556 }
3557 }
3558 }
3559 return result;
3560}

References LinkedMap< T, Hash, KeyEqual, Map >::find(), QCString::findRev(), QCString::isEmpty(), QCString::left(), QCString::length(), and QCString::right().

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

7112{
7113 StringVector result;
7114 reg::Iterator iter(s, delimiter);
7116 size_t p=0;
7117 for ( ; iter != end; ++iter)
7118 {
7119 const auto &match = *iter;
7120 size_t i=match.position();
7121 size_t l=match.length();
7122 if (i>p) result.push_back(s.substr(p,i-p));
7123 p=i+l;
7124 }
7125 if (p<s.length()) result.push_back(s.substr(p));
7126 return result;
7127}

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

7095{
7096 StringVector result;
7097 size_t prev = 0, pos = 0, len = s.length();
7098 do
7099 {
7100 pos = s.find(delimiter, prev);
7101 if (pos == std::string::npos) pos = len;
7102 if (pos>prev) result.push_back(s.substr(prev,pos-prev));
7103 prev = pos + delimiter.length();
7104 }
7105 while (pos<len && prev<len);
7106 return result;
7107}

Referenced by VHDLOutlineParser::addProto(), VHDLOutlineParser::addVhdlType(), FlowChart::alignCommentNode(), VHDLOutlineParser::checkInlineCode(), checkVhdlString(), VHDLOutlineParser::createFunction(), VhdlDocGen::findArchitecture(), getFilteredImageAttributes(), VhdlDocGen::getIndexWord(), DocPara::handleCommand(), DocParser::handleImage(), DocPara::handleInclude(), Qhp::initialize(), VhdlDocGen::parseForBinding(), VhdlDocGen::parseForConfig(), parseIncludeOptions(), writeFuncProto(), VhdlDocGen::writeInlineClassLink(), and VhdlDocGen::writeRecUnitDocu().

◆ stackTrace()

void stackTrace ( )

Definition at line 5942 of file util.cpp.

5943{
5944#ifdef TRACINGSUPPORT
5945 void *backtraceFrames[128];
5946 int frameCount = backtrace(backtraceFrames, 128);
5947 const size_t cmdLen = 40960;
5948 static char cmd[cmdLen];
5949 char *p = cmd;
5950 p += qsnprintf(p,cmdLen,"/usr/bin/atos -p %d ", (int)getpid());
5951 for (int x = 0; x < frameCount; x++)
5952 {
5953 p += qsnprintf(p,cmdLen,"%p ", backtraceFrames[x]);
5954 }
5955 fprintf(stderr,"========== STACKTRACE START ==============\n");
5956 if (FILE *fp = Portable::popen(cmd, "r"))
5957 {
5958 char resBuf[512];
5959 while (size_t len = fread(resBuf, 1, sizeof(resBuf), fp))
5960 {
5961 fwrite(resBuf, 1, len, stderr);
5962 }
5963 Portable::pclose(fp);
5964 }
5965 fprintf(stderr,"============ STACKTRACE END ==============\n");
5966 //fprintf(stderr,"%s\n", frameStrings[x]);
5967#endif
5968}

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

◆ stripAnonymousNamespaceScope()

QCString stripAnonymousNamespaceScope ( const QCString & s)

Definition at line 241 of file util.cpp.

242{
243 int i=0,p=0,l=0;
244 QCString newScope;
245 int sl = static_cast<int>(s.length());
246 while ((i=getScopeFragment(s,p,&l))!=-1)
247 {
248 //printf("Scope fragment %s\n",qPrint(s.mid(i,l)));
249 if (Doxygen::namespaceLinkedMap->find(s.left(i+l))!=nullptr)
250 {
251 if (s.at(i)!='@')
252 {
253 if (!newScope.isEmpty()) newScope+="::";
254 newScope+=s.mid(i,l);
255 }
256 }
257 else if (i<sl)
258 {
259 if (!newScope.isEmpty()) newScope+="::";
260 newScope+=s.right(sl-i);
261 goto done;
262 }
263 p=i+l;
264 }
265done:
266 //printf("stripAnonymousNamespaceScope('%s')='%s'\n",qPrint(s),qPrint(newScope));
267 return newScope;
268}

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

QCString stripExtension ( const QCString & fName)

Definition at line 5430 of file util.cpp.

5431{
5433}
QCString stripExtensionGeneral(const QCString &fName, const QCString &ext)
Definition util.cpp:5420

References Doxygen::htmlFileExtension, and stripExtensionGeneral().

Referenced by anonymous_namespace{tagreader.cpp}::TagFileParser::buildLists(), ClassDefImpl::ClassDefImpl(), and MemberDefImpl::setTagInfo().

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

341{
342 return stripFromPath(path,Config_getList(STRIP_FROM_INC_PATH));
343}

References Config_getList, and stripFromPath().

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

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

333{
334 return stripFromPath(path,Config_getList(STRIP_FROM_PATH));
335}

References Config_getList, and stripFromPath().

◆ stripIndentation()

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

Definition at line 6427 of file util.cpp.

6428{
6429 if (s.isEmpty()) return s; // empty string -> we're done
6430
6431 //printf("stripIndentation:\n%s\n------\n",qPrint(s));
6432 // compute minimum indentation over all lines
6433 const char *p=s.data();
6434 char c=0;
6435 int indent=0;
6436 int minIndent=1000000; // "infinite"
6437 bool searchIndent=true;
6438 int tabSize=Config_getInt(TAB_SIZE);
6439 bool skipFirst = skipFirstLine;
6440 while ((c=*p++))
6441 {
6442 if (c=='\t') indent+=tabSize - (indent%tabSize);
6443 else if (c=='\n') indent=0,searchIndent=true,skipFirst=false;
6444 else if (c==' ') indent++;
6445 else if (searchIndent && !skipFirst)
6446 {
6447 searchIndent=false;
6448 if (indent<minIndent) minIndent=indent;
6449 }
6450 }
6451
6452 // no indent to remove -> we're done
6453 if (minIndent==0) return substitute(s,"@ilinebr","\\ilinebr");
6454
6455 // remove minimum indentation for each line
6456 TextStream result;
6457 p=s.data();
6458 indent=0;
6459 skipFirst=skipFirstLine;
6460 while ((c=*p++))
6461 {
6462 if (c=='\n') // start of new line
6463 {
6464 indent=0;
6465 result << c;
6466 skipFirst=false;
6467 }
6468 else if (indent<minIndent && !skipFirst) // skip until we reach minIndent
6469 {
6470 if (c=='\t')
6471 {
6472 int newIndent = indent+tabSize-(indent%tabSize);
6473 int i=newIndent;
6474 while (i>minIndent) // if a tab crosses the minIndent boundary fill the rest with spaces
6475 {
6476 result << ' ';
6477 i--;
6478 }
6479 indent=newIndent;
6480 }
6481 else // space
6482 {
6483 indent++;
6484 }
6485 }
6486 else if (c=='\\' && literal_at(p,"ilinebr "))
6487 // we also need to remove the indentation after a \ilinebr command at the end of a line
6488 {
6489 result << "\\ilinebr ";
6490 p+=8;
6491 int skipAmount=0;
6492 for (int j=0;j<minIndent;j++) if (*(p+j)==' ') skipAmount++; // test to see if we have the indent
6493 if (skipAmount==minIndent)
6494 {
6495 p+=skipAmount; // remove the indent
6496 }
6497 }
6498 else if (c=='@' && literal_at(p,"ilinebr"))
6499 {
6500 result << "\\ilinebr";
6501 p+=7;
6502 }
6503 else // copy anything until the end of the line
6504 {
6505 result << c;
6506 }
6507 }
6508
6509 //printf("stripIndentation: result=\n%s\n------\n",qPrint(result.str()));
6510
6511 return result.str();
6512}

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

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

◆ stripIndentationVerbatim()

void stripIndentationVerbatim ( QCString & doc,
const int indentationLevel )

Definition at line 6515 of file util.cpp.

6516{
6517 //printf("stripIndentationVerbatim(level=%d):\n%s\n------\n",indentationLevel,qPrint(doc));
6518 if (indentationLevel <= 0 || doc.isEmpty()) return; // nothing to strip
6519
6520 // by stripping content the string will only become shorter so we write the results
6521 // back into the input string and then resize it at the end.
6522 char c = 0;
6523 const char *src = doc.data();
6524 char *dst = doc.rawData();
6525 bool insideIndent = false; // skip the initial line from stripping
6526 int cnt = 0;
6527 while ((c=*src++))
6528 {
6529 // invariant: dst<=src
6530 switch(c)
6531 {
6532 case '\n':
6533 *dst++ = c;
6534 insideIndent = true;
6535 cnt = indentationLevel;
6536 break;
6537 case ' ':
6538 if (insideIndent)
6539 {
6540 if (cnt>0) // count down the spacing until the end of the indent
6541 {
6542 cnt--;
6543 }
6544 else // reached the end of the indent, start of the part of the line to keep
6545 {
6546 insideIndent = false;
6547 *dst++ = c;
6548 }
6549 }
6550 else // part after indent, copy to the output
6551 {
6552 *dst++ = c;
6553 }
6554 break;
6555 default:
6556 insideIndent = false;
6557 *dst++ = c;
6558 break;
6559 }
6560 }
6561 doc.resize(static_cast<uint32_t>(dst-doc.data()));
6562 //printf("stripIndentationVerbatim: result=\n%s\n------\n",qPrint(doc));
6563}
char * rawData()
Returns a writable pointer to the data.
Definition qcstring.h:165
void resize(size_t newlen)
Definition qcstring.h:167

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

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

5534{
5535 if (s.isEmpty()) return QCString();
5536 const char *p = s.data();
5537
5538 // search for leading empty lines
5539 int i=0,li=-1,l=static_cast<int>(s.length());
5540 char c = 0;
5541 while ((c=*p))
5542 {
5543 if (c==' ' || c=='\t' || c=='\r') i++,p++;
5544 else if (c=='\\' && literal_at(p,"\\ilinebr")) i+=8,li=i,p+=8;
5545 else if (c=='\n') i++,li=i,docLine++,p++;
5546 else break;
5547 }
5548
5549 // search for trailing empty lines
5550 int b=l-1,bi=-1;
5551 p=s.data()+b;
5552 while (b>=0)
5553 {
5554 c=*p;
5555 if (c==' ' || c=='\t' || c=='\r') b--,p--;
5556 else if (c=='r' && b>=7 && literal_at(p-7,"\\ilinebr")) bi=b-7,b-=8,p-=8;
5557 else if (c=='>' && b>=11 && literal_at(p-11,"\\ilinebr<br>")) bi=b-11,b-=12,p-=12;
5558 else if (c=='\n') bi=b,b--,p--;
5559 else break;
5560 }
5561
5562 // return whole string if no leading or trailing lines where found
5563 if (li==-1 && bi==-1) return s;
5564
5565 // return substring
5566 if (bi==-1) bi=l;
5567 if (li==-1) li=0;
5568 if (bi<=li) return QCString(); // only empty lines
5569 //printf("docLine='%s' len=%d li=%d bi=%d\n",qPrint(s),s.length(),li,bi);
5570 return s.mid(li,bi-li);
5571}

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

5458{
5459 QCString result=s;
5460 int i=result.findRev('/');
5461 if (i!=-1)
5462 {
5463 result=result.mid(i+1);
5464 }
5465 i=result.findRev('\\');
5466 if (i!=-1)
5467 {
5468 result=result.mid(i+1);
5469 }
5470 return result;
5471}

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

Referenced by LatexGenerator::addLabel(), anonymous_namespace{tagreader.cpp}::TagFileParser::buildLists(), RTFGenerator::endDoxyAnchor(), LatexGenerator::endIndexItem(), LatexGenerator::endIndexValue(), LatexGenerator::endTitleHead(), objectLinkToString(), objectLinkToString(), objectLinkToString(), DocbookDocVisitor::operator()(), DocbookDocVisitor::operator()(), DocbookDocVisitor::operator()(), DocbookDocVisitor::operator()(), DocbookDocVisitor::operator()(), DocbookDocVisitor::operator()(), DocbookDocVisitor::operator()(), DocbookDocVisitor::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(), DocbookGenerator::startSection(), LatexGenerator::startSection(), LatexGenerator::startTextLink(), RTFGenerator::startTextLink(), substituteHtmlKeywords(), substituteKeywords(), LatexGenerator::writeAnchor(), RTFGenerator::writeAnchor(), LatexCodeGenerator::writeCodeLink(), RTFCodeGenerator::writeCodeLink(), DocbookCodeGenerator::writeCodeLinkLine(), MemberList::writeDeclarations(), writeDocbookLink(), LatexCodeGenerator::writeLineNumber(), RTFCodeGenerator::writeLineNumber(), 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 4288 of file util.cpp.

4289{
4290 QCString result = name;
4291 int l = static_cast<int>(result.length());
4292 int p = 0;
4293 bool done = FALSE;
4294 bool skipBracket=FALSE; // if brackets do not match properly, ignore them altogether
4295 int count=0;
4296 int round=0;
4297
4298 do
4299 {
4300 p=l-1; // start at the end of the string
4301 while (p>=0 && count>=0)
4302 {
4303 char c=result.at(p);
4304 switch (c)
4305 {
4306 case ':':
4307 // only exit in the case of ::
4308 //printf("stripScope(%s)=%s\n",name,qPrint(result.right(l-p-1)));
4309 if (p>0 && result.at(p-1)==':' && (count==0 || skipBracket))
4310 {
4311 return result.right(l-p-1);
4312 }
4313 p--;
4314 break;
4315 case '>':
4316 if (skipBracket) // we don't care about brackets
4317 {
4318 p--;
4319 }
4320 else // count open/close brackets
4321 {
4322 if (p>0 && result.at(p-1)=='>') // skip >> operator
4323 {
4324 p-=2;
4325 break;
4326 }
4327 count=1;
4328 //printf("pos < = %d\n",p);
4329 p--;
4330 bool foundMatch=false;
4331 while (p>=0 && !foundMatch)
4332 {
4333 c=result.at(p--);
4334 switch (c)
4335 {
4336 case ')':
4337 round++;
4338 break;
4339 case '(':
4340 round--;
4341 break;
4342 case '>': // ignore > inside (...) to support e.g. (sizeof(T)>0) inside template parameters
4343 if (round==0) count++;
4344 break;
4345 case '<':
4346 if (round==0)
4347 {
4348 if (p>0)
4349 {
4350 if (result.at(p-1) == '<') // skip << operator
4351 {
4352 p--;
4353 break;
4354 }
4355 }
4356 count--;
4357 foundMatch = count==0;
4358 }
4359 break;
4360 default:
4361 //printf("c=%c count=%d\n",c,count);
4362 break;
4363 }
4364 }
4365 }
4366 //printf("pos > = %d\n",p+1);
4367 break;
4368 default:
4369 p--;
4370 }
4371 }
4372 done = count==0 || skipBracket; // reparse if brackets do not match
4373 skipBracket=TRUE;
4374 }
4375 while (!done); // if < > unbalanced repeat ignoring them
4376 //printf("stripScope(%s)=%s\n",name,name);
4377 return name;
4378}

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

5027{
5028 //printf("stripTemplateSpecifiersFromScope(name=%s,scopeName=%s)\n",qPrint(fullName),qPrint(scopeName));
5029 int i=fullName.find('<');
5030 if (i==-1) return fullName;
5031 QCString result;
5032 int p=0;
5033 int l=static_cast<int>(fullName.length());
5034 while (i!=-1)
5035 {
5036 //printf("1:result+=%s\n",qPrint(fullName.mid(p,i-p)));
5037 int e=i+1;
5038 int count=1;
5039 int round=0;
5040 while (e<l && count>0)
5041 {
5042 char c=fullName.at(e++);
5043 switch (c)
5044 {
5045 case '(': round++; break;
5046 case ')': if (round>0) round--; break;
5047 case '<': if (round==0) count++; break;
5048 case '>': if (round==0) count--; break;
5049 default:
5050 break;
5051 }
5052 }
5053 int si= fullName.find("::",e);
5054
5055 if (parentOnly && si==-1) break;
5056 // we only do the parent scope, so we stop here if needed
5057
5058 result+=fullName.mid(p,i-p);
5059 //printf(" trying %s\n",qPrint(mergeScopes(scopeName,result+fullName.mid(i,e-i))));
5060 ClassDef *cd = getClass(mergeScopes(scopeName,result+fullName.mid(i,e-i)));
5061 if (cd!=nullptr && (allowArtificial || !cd->isArtificial()))
5062 {
5063 result+=fullName.mid(i,e-i);
5064 //printf(" 2:result+=%s\n",qPrint(fullName.mid(i,e-i-1)));
5065 }
5066 else if (pLastScopeStripped)
5067 {
5068 //printf(" last stripped scope '%s'\n",qPrint(fullName.mid(i,e-i)));
5069 *pLastScopeStripped=fullName.mid(i,e-i);
5070 }
5071 p=e;
5072 i=fullName.find('<',p);
5073 }
5074 result+=fullName.right(l-p);
5075 //printf("3:result+=%s\n",qPrint(fullName.right(l-p)));
5076 //printf("end result=%s\n",qPrint(result));
5077 return result;
5078}
virtual bool isArtificial() const =0
QCString mergeScopes(const QCString &leftScope, const QCString &rightScope)
Definition util.cpp:5089

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(), getDefsOld(), 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 3564 of file util.cpp.

3565{
3566 std::string substRes;
3567 int line = 1;
3568 const char *p = s.data();
3569 if (p)
3570 {
3571 // reserve some room for expansion
3572 substRes.reserve(s.length()+1024);
3573 char c = 0;
3574 while ((c=*p))
3575 {
3576 bool found = false;
3577 if (c=='$')
3578 {
3579 for (const auto &kw : keywords)
3580 {
3581 size_t keyLen = qstrlen(kw.keyword);
3582 if (qstrncmp(p,kw.keyword,keyLen)==0)
3583 {
3584 const char *startArg = p+keyLen;
3585 bool expectParam = std::holds_alternative<KeywordSubstitution::GetValueWithParam>(kw.getValueVariant);
3586 //printf("%s: expectParam=%d *startArg=%c\n",kw.keyword,expectParam,*startArg);
3587 if (expectParam && *startArg=='(') // $key(value)
3588 {
3589 size_t j=1;
3590 const char *endArg = nullptr;
3591 while ((c=*(startArg+j)) && c!=')' && c!='\n' && c!=0) j++;
3592 if (c==')') endArg=startArg+j;
3593 if (endArg)
3594 {
3595 QCString value = QCString(startArg+1).left(endArg-startArg-1);
3596 auto &&getValue = std::get<KeywordSubstitution::GetValueWithParam>(kw.getValueVariant);
3597 substRes+=getValue(value).str();
3598 p=endArg+1;
3599 //printf("found '%s'->'%s'\n",kw.keyword,qPrint(getValue(value)));
3600 }
3601 else
3602 {
3603 //printf("missing argument\n");
3604 warn(file,line,"Missing argument for '{}'",kw.keyword);
3605 p+=keyLen;
3606 }
3607 }
3608 else if (!expectParam) // $key
3609 {
3610 auto &&getValue = std::get<KeywordSubstitution::GetValue>(kw.getValueVariant);
3611 substRes+=getValue().str();
3612 //printf("found '%s'->'%s'\n",kw.keyword,qPrint(getValue()));
3613 p+=keyLen;
3614 }
3615 else
3616 {
3617 //printf("%s %d Expected arguments, none specified '%s'\n",qPrint(file), line, qPrint(kw.keyword));
3618 warn(file,line,"Expected arguments for '{}' but none were specified",kw.keyword);
3619 p+=keyLen;
3620 }
3621 found = true;
3622 break;
3623 }
3624 }
3625 }
3626 if (!found) // copy
3627 {
3628 if (c=='\n') line++;
3629 substRes+=c;
3630 p++;
3631 }
3632 }
3633 }
3634 return substRes;
3635}

References QCString::data(), found, 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 3716 of file util.cpp.

3718{
3719 return substituteKeywords(file,s,
3720 {
3721 // keyword value getter
3722 { "$title", [&]() { return !title.isEmpty() ? title : projName; } },
3723 { "$datetime", [&]() { return dateToString(DateTimeType::DateTime); } },
3724 { "$date", [&]() { return dateToString(DateTimeType::Date); } },
3725 { "$time", [&]() { return dateToString(DateTimeType::Time); } },
3726 { "$year", [&]() { return yearToString(); } },
3727 { "$doxygenversion", [&]() { return getDoxygenVersion(); } },
3728 { "$projectname", [&]() { return projName; } },
3729 { "$projectnumber", [&]() { return projNum; } },
3730 { "$projectbrief", [&]() { return projBrief; } },
3731 { "$projectlogo", [&]() { return stripPath(projectLogoFile()); } },
3732 { "$logosize", [&]() { return projectLogoSize(); } },
3733 { "$projecticon", [&]() { return stripPath(Config_getString(PROJECT_ICON)); } },
3734 { "$langISO", [&]() { return theTranslator->trISOLang(); } },
3735 { "$showdate", [&](const QCString &fmt) { return showDate(fmt); } }
3736 });
3737}
QCString dateToString(DateTimeType includeTime)
Returns the current date, when includeTime is set also the time is provided.
Definition datetime.cpp:63
QCString yearToString()
Returns the current year as a string.
Definition datetime.cpp:76
Definition message.h:144
QCString stripPath(const QCString &s)
Definition util.cpp:5457
QCString substituteKeywords(const QCString &file, const QCString &s, const KeywordSubstitutionList &keywords)
Definition util.cpp:3564
QCString projectLogoFile()
Definition util.cpp:3650
static QCString projectLogoSize()
Definition util.cpp:3671
static QCString showDate(const QCString &fmt)
Definition util.cpp:3637

References Config_getString, Date, DateTime, dateToString(), QCString::isEmpty(), projectLogoFile(), projectLogoSize(), showDate(), stripPath(), substituteKeywords(), theTranslator, Time, and yearToString().

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

4864{
4865 AUTO_TRACE("name={} formalArgs={} actualArgs={}",nm,argListToString(formalArgs),actualArgs ? argListToString(*actualArgs) : QCString());
4866 if (formalArgs.empty()) return nm;
4867 QCString result;
4868
4869 static const reg::Ex re(R"(\a\w*)");
4870 std::string name = nm.str();
4871 reg::Iterator it(name,re);
4873 size_t p=0;
4874
4875 for (; it!=end ; ++it)
4876 {
4877 const auto &match = *it;
4878 size_t i = match.position();
4879 size_t l = match.length();
4880 if (i>p) result += name.substr(p,i-p);
4881 QCString n(match.str());
4883 if (actualArgs)
4884 {
4885 actIt = actualArgs->begin();
4886 }
4887 //printf(": name=%s\n",qPrint(name));
4888
4889 // if n is a template argument, then we substitute it
4890 // for its template instance argument.
4891 bool found=FALSE;
4892 for (auto formIt = formalArgs.begin();
4893 formIt!=formalArgs.end() && !found;
4894 ++formIt
4895 )
4896 {
4897 Argument formArg = *formIt;
4898 Argument actArg;
4899 if (actualArgs && actIt!=actualArgs->end())
4900 {
4901 actArg = *actIt;
4902 }
4903 if (formArg.type.startsWith("class ") && formArg.name.isEmpty())
4904 {
4905 formArg.name = formArg.type.mid(6);
4906 formArg.type = "class";
4907 }
4908 else if (formArg.type.startsWith("typename ") && formArg.name.isEmpty())
4909 {
4910 formArg.name = formArg.type.mid(9);
4911 formArg.type = "typename";
4912 }
4913 else if (formArg.type.startsWith("class...")) // match 'class... name' to 'name...'
4914 {
4915 formArg.name += "...";
4916 formArg.type = formArg.type.left(5)+formArg.type.mid(8);
4917 }
4918 else if (formArg.type.startsWith("typename...")) // match 'typename... name' to 'name...'
4919 {
4920 formArg.name += "...";
4921 formArg.type = formArg.type.left(8)+formArg.type.mid(11);
4922 }
4923 //printf(": n=%s formArg->type='%s' formArg->name='%s' formArg->defval='%s' actArg->type='%s' actArg->name='%s' \n",
4924 // qPrint(n),qPrint(formArg.type),qPrint(formArg.name),qPrint(formArg.defval),qPrint(actArg.type),qPrint(actArg.name));
4925 if (formArg.type=="class" || formArg.type=="typename" || formArg.type.startsWith("template"))
4926 {
4927 if (formArg.name==n && actualArgs && actIt!=actualArgs->end() && !actArg.type.isEmpty()) // base class is a template argument
4928 {
4929 static constexpr auto hasRecursion = [](const QCString &prefix,const QCString &nameArg,const QCString &subst) -> bool
4930 {
4931 int ii=0;
4932 int pp=0;
4933
4934 ii = subst.find('<');
4935 //printf("prefix='%s' subst='%s'\n",qPrint(prefix.mid(prefix.length()-ii-2,ii+1)),qPrint(subst.left(ii+1)));
4936 if (ii!=-1 && static_cast<int>(prefix.length())>=ii+2 && prefix.mid(prefix.length()-ii-2,ii+1)==subst.left(ii+1))
4937 {
4938 return true; // don't replace 'A< ' with 'A< A<...', see issue #10951
4939 }
4940
4941 while ((ii=subst.find(nameArg,pp))!=-1)
4942 {
4943 bool beforeNonWord = ii==0 || !isId(subst.at(ii-1));
4944 bool afterNonWord = subst.length()==ii+nameArg.length() || !isId(subst.at(ii+nameArg.length()));
4945 if (beforeNonWord && afterNonWord)
4946 {
4947 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
4948 }
4949 pp=ii+static_cast<int>(nameArg.length());
4950 }
4951 return false;
4952 };
4953 // replace formal argument with the actual argument of the instance
4954 AUTO_TRACE_ADD("result={} n={} type={} hasRecursion={}",result,n,actArg.type,hasRecursion(result,n,actArg.type));
4955 if (!hasRecursion(result,n,actArg.type))
4956 // the scope guard is to prevent recursive lockup for
4957 // template<class A> class C : public<A::T>,
4958 // where A::T would become A::T::T here,
4959 // since n==A and actArg->type==A::T
4960 // see bug595833 for an example
4961 //
4962 // Also prevent recursive substitution if n is part of actArg.type, i.e.
4963 // n='A' in argType='S< A >' would produce 'S< S< A > >'
4964 {
4965 if (actArg.name.isEmpty())
4966 {
4967 result += actArg.type;
4968 }
4969 else
4970 // for case where the actual arg is something like "unsigned int"
4971 // the "int" part is in actArg->name.
4972 {
4973 result += actArg.type+" "+actArg.name;
4974 }
4975 found=TRUE;
4976 }
4977 }
4978 else if (formArg.name==n &&
4979 (actualArgs==nullptr || actIt==actualArgs->end()) &&
4980 !formArg.defval.isEmpty() &&
4981 formArg.defval!=nm /* to prevent recursion */
4982 )
4983 {
4984 result += substituteTemplateArgumentsInString(formArg.defval,formalArgs,actualArgs);
4985 found=TRUE;
4986 }
4987 }
4988 else if (formArg.name==n &&
4989 (actualArgs==nullptr || actIt==actualArgs->end()) &&
4990 !formArg.defval.isEmpty() &&
4991 formArg.defval!=nm /* to prevent recursion */
4992 )
4993 {
4994 result += substituteTemplateArgumentsInString(formArg.defval,formalArgs,actualArgs);
4995 found=TRUE;
4996 }
4997 if (actualArgs && actIt!=actualArgs->end())
4998 {
4999 actIt++;
5000 }
5001 }
5002 if (!found)
5003 {
5004 result += n;
5005 }
5006 p=i+l;
5007 }
5008 result+=name.substr(p);
5009 result=result.simplifyWhiteSpace();
5010 AUTO_TRACE_EXIT("result={}",result);
5011 return result.stripWhiteSpace();
5012}
typename Vec::const_iterator const_iterator
Definition arguments.h:69
QCString substituteTemplateArgumentsInString(const QCString &nm, const ArgumentList &formalArgs, const ArgumentList *actualArgs)
Definition util.cpp:4860

References argListToString(), AUTO_TRACE, AUTO_TRACE_ADD, AUTO_TRACE_EXIT, ArgumentList::begin(), Argument::defval, ArgumentList::empty(), ArgumentList::end(), end(), FALSE, found, 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 1246 of file util.cpp.

1247{
1248 QCString result;
1249 if (al.empty()) return result;
1250 result="<";
1251 bool first=true;
1252 for (const auto &a : al)
1253 {
1254 if (a.defval.isEmpty() || includeDefault)
1255 {
1256 if (!first) result+=", ";
1257 if (!a.name.isEmpty()) // add template argument name
1258 {
1259 if (lang==SrcLangExt::Java || lang==SrcLangExt::CSharp)
1260 {
1261 result+=a.type+" ";
1262 }
1263 result+=a.name;
1264 }
1265 else // extract name from type
1266 {
1267 int i = static_cast<int>(a.type.length())-1;
1268 while (i>=0 && isId(a.type.at(i))) i--;
1269 if (i>0)
1270 {
1271 result+=a.type.right(a.type.length()-i-1);
1272 if (a.type.find("...")!=-1)
1273 {
1274 result+="...";
1275 }
1276 }
1277 else // nothing found -> take whole name
1278 {
1279 result+=a.type;
1280 }
1281 }
1282 if (!a.typeConstraint.isEmpty() && lang==SrcLangExt::Java)
1283 {
1284 result+=" extends "; // TODO: now Java specific, C# has where...
1285 result+=a.typeConstraint;
1286 }
1287 first=false;
1288 }
1289 }
1290 result+=">";
1291 return removeRedundantWhiteSpace(result);
1292}

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

1404{
1405 const char *outputEncoding = "UTF-8";
1406 if (inputEncoding==nullptr || qstricmp(inputEncoding,outputEncoding)==0) return true;
1407 size_t inputSize=input.length();
1408 size_t outputSize=inputSize*4;
1409 QCString output(outputSize, QCString::ExplicitSize);
1410 void *cd = portable_iconv_open(outputEncoding,inputEncoding);
1411 if (cd==reinterpret_cast<void *>(-1))
1412 {
1413 return false;
1414 }
1415 bool ok=true;
1416 size_t iLeft=inputSize;
1417 size_t oLeft=outputSize;
1418 const char *inputPtr = input.data();
1419 char *outputPtr = output.rawData();
1420 if (!portable_iconv(cd, &inputPtr, &iLeft, &outputPtr, &oLeft))
1421 {
1422 outputSize-=static_cast<int>(oLeft);
1423 output.resize(outputSize);
1424 output.at(outputSize)='\0';
1425 // replace input
1426 input=output.str();
1427 //printf("iconv: input size=%d output size=%d\n[%s]\n",size,newSize,qPrint(srcBuf));
1428 }
1429 else
1430 {
1431 ok=false;
1432 }
1434 return ok;
1435}
@ ExplicitSize
Definition qcstring.h:133
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:442

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

3927{
3928 if (s.isEmpty()) return s;
3929 bool caseSenseNames = getCaseSenseNames();
3930 QCString result;
3931 const char *p = s.data();
3932 if (p)
3933 {
3934 char c = 0;
3935 while ((c=*p++))
3936 {
3937 if (c=='_') // 2 or 3 character escape
3938 {
3939 switch (*p)
3940 {
3941 case '_': result+=c; p++; break; // __ -> '_'
3942 case '1': result+=':'; p++; break; // _1 -> ':'
3943 case '2': result+='/'; p++; break; // _2 -> '/'
3944 case '3': result+='<'; p++; break; // _3 -> '<'
3945 case '4': result+='>'; p++; break; // _4 -> '>'
3946 case '5': result+='*'; p++; break; // _5 -> '*'
3947 case '6': result+='&'; p++; break; // _6 -> '&'
3948 case '7': result+='|'; p++; break; // _7 -> '|'
3949 case '8': result+='.'; p++; break; // _8 -> '.'
3950 case '9': result+='!'; p++; break; // _9 -> '!'
3951 case '0': // 3 character escape
3952 switch (*(p+1))
3953 {
3954 case '0': result+=','; p+=2; break; // _00 -> ','
3955 case '1': result+=' '; p+=2; break; // _01 -> ' '
3956 case '2': result+='{'; p+=2; break; // _02 -> '{'
3957 case '3': result+='}'; p+=2; break; // _03 -> '}'
3958 case '4': result+='?'; p+=2; break; // _04 -> '?'
3959 case '5': result+='^'; p+=2; break; // _05 -> '^'
3960 case '6': result+='%'; p+=2; break; // _06 -> '%'
3961 case '7': result+='('; p+=2; break; // _07 -> '('
3962 case '8': result+=')'; p+=2; break; // _08 -> ')'
3963 case '9': result+='+'; p+=2; break; // _09 -> '+'
3964 case 'a': result+='='; p+=2; break; // _0a -> '='
3965 case 'b': result+='$'; p+=2; break; // _0b -> '$'
3966 case 'c': result+='\\'; p+=2; break;// _0c -> '\'
3967 case 'd': result+='@'; p+=2; break; // _0d -> '@'
3968 case 'e': result+=']'; p+=2; break; // _0e -> ']'
3969 case 'f': result+='['; p+=2; break; // _0f -> '['
3970 case 'g': result+='#'; p+=2; break; // _0g -> '#'
3971 case 'h': result+='"'; p+=2; break; // _0h -> '"'
3972 case 'i': result+='~'; p+=2; break; // _0i -> '~'
3973 case 'j': result+='\''; p+=2; break;// _0j -> '\'
3974 case 'k': result+=';'; p+=2; break; // _0k -> ';'
3975 case 'l': result+='`'; p+=2; break; // _0l -> '`'
3976 default: // unknown escape, just pass underscore character as-is
3977 result+=c;
3978 break;
3979 }
3980 break;
3981 default:
3982 if (!caseSenseNames && c>='a' && c<='z') // lower to upper case escape, _a -> 'A'
3983 {
3984 result+=static_cast<char>(toupper(*p));
3985 p++;
3986 }
3987 else // unknown escape, pass underscore character as-is
3988 {
3989 result+=c;
3990 }
3991 break;
3992 }
3993 }
3994 else // normal character; pass as is
3995 {
3996 result+=c;
3997 }
3998 }
3999 }
4000 return result;
4001}

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

◆ updateColumnCount()

size_t updateColumnCount ( const char * s,
size_t col )

Definition at line 7356 of file util.cpp.

7357{
7358 if (s)
7359 {
7360 const int tabSize = Config_getInt(TAB_SIZE);
7361 char c;
7362 while ((c=*s++))
7363 {
7364 switch(c)
7365 {
7366 case '\t': col+=tabSize - (col%tabSize);
7367 break;
7368 case '\n': col=0;
7369 break;
7370 default:
7371 col++;
7372 if (c<0) // multi-byte character
7373 {
7374 int numBytes = getUTF8CharNumBytes(c);
7375 for (int i=0;i<numBytes-1 && (c=*s++);i++) {} // skip over extra chars
7376 if (c==0) return col; // end of string half way a multibyte char
7377 }
7378 break;
7379 }
7380 }
7381 }
7382 return col;
7383}

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

5610{
5611 QCString langName = language.lower();
5612 auto it1 = std::find_if(g_lang2extMap.begin(),g_lang2extMap.end(),
5613 [&langName](const auto &info) { return info.langName==langName; });
5614 if (it1 == g_lang2extMap.end()) return false;
5615
5616 // found the language
5617 SrcLangExt parserId = it1->parserId;
5618 QCString extName = extension.lower();
5619 if (extName.isEmpty()) return FALSE;
5620 if (extName.at(0)!='.') extName.prepend(".");
5621 auto it2 = g_extLookup.find(extName.str());
5622 if (it2!=g_extLookup.end())
5623 {
5624 g_extLookup.erase(it2); // language was already register for this ext
5625 }
5626 //printf("registering extension %s\n",qPrint(extName));
5627 g_extLookup.emplace(extName.str(),parserId);
5628 if (!Doxygen::parserManager->registerExtension(extName,it1->parserName))
5629 {
5630 err("Failed to assign extension {} to parser {} for language {}\n",
5631 extName.data(),it1->parserName,language);
5632 }
5633 else
5634 {
5635 //msg("Registered extension {} to language parser {}...\n",
5636 // extName,language);
5637 }
5638 return TRUE;
5639}
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 6260 of file util.cpp.

6261{
6262 int hue = Config_getInt(HTML_COLORSTYLE_HUE);
6263 int sat = Config_getInt(HTML_COLORSTYLE_SAT);
6264 int gamma = Config_getInt(HTML_COLORSTYLE_GAMMA);
6265 while (data->name)
6266 {
6267 QCString fileName = dir+"/"+data->name;
6268 ColoredImage img(data->width,data->height,data->content,data->alpha,
6269 sat,hue,gamma);
6270 if (!img.save(fileName))
6271 {
6272 fprintf(stderr,"Warning: Cannot open file %s for writing\n",data->name);
6273 }
6274 Doxygen::indexList->addImageFile(data->name);
6275 data++;
6276 }
6277}
Class representing a bitmap image colored based on hue/sat/gamma settings.
Definition image.h:56
static IndexList * indexList
Definition doxygen.h:134
const unsigned char * content
Definition util.h:419
unsigned short height
Definition util.h:418
const unsigned char * alpha
Definition util.h:420
unsigned short width
Definition util.h:417
const char * name
Definition util.h:416

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

Referenced by ResourceMgr::copyResourceAs().

◆ writeExamples()

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

Definition at line 1127 of file util.cpp.

1128{
1129 auto replaceFunc = [&list,&ol](size_t entryIndex)
1130 {
1131 const auto &e = list[entryIndex];
1132 ol.pushGeneratorState();
1136 // link for Html / man
1137 //printf("writeObjectLink(file=%s)\n",qPrint(e->file));
1138 ol.writeObjectLink(QCString(),e.file,e.anchor,e.name);
1139 ol.popGeneratorState();
1140
1141 ol.pushGeneratorState();
1144 // link for Latex / pdf with anchor because the sources
1145 // are not hyperlinked (not possible with a verbatim environment).
1146 ol.writeObjectLink(QCString(),e.file,QCString(),e.name);
1147 ol.popGeneratorState();
1148 };
1149
1150 writeMarkerList(ol, theTranslator->trWriteList(static_cast<int>(list.size())).str(), list.size(), replaceFunc);
1151
1152 ol.writeString(".");
1153}
void writeString(const QCString &text)
Definition outputlist.h:412
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:1103

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

◆ writeMarkerList()

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

Definition at line 1103 of file util.cpp.

1105{
1106 static const reg::Ex marker(R"(@(\d+))");
1107 reg::Iterator it(markerText,marker);
1109 size_t index=0;
1110 // now replace all markers in inheritLine with links to the classes
1111 for ( ; it!=end ; ++it)
1112 {
1113 const auto &match = *it;
1114 size_t newIndex = match.position();
1115 size_t matchLen = match.length();
1116 ol.parseText(markerText.substr(index,newIndex-index));
1117 unsigned long entryIndex = std::stoul(match[1].str());
1118 if (entryIndex<static_cast<unsigned long>(numMarkers))
1119 {
1120 replaceFunc(entryIndex);
1121 }
1122 index=newIndex+matchLen;
1123 }
1124 ol.parseText(markerText.substr(index));
1125}
void parseText(const QCString &textStr)

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

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

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

5921{
5922 if (al.empty()) return;
5923 ol.startConstraintList(theTranslator->trTypeConstraints());
5924 for (const Argument &a : al)
5925 {
5927 ol.parseText(a.name);
5928 ol.endConstraintParam();
5930 linkifyText(TextGeneratorOLImpl(ol),d,nullptr,nullptr,a.type);
5931 ol.endConstraintType();
5933 ol.generateDoc(d->docFile(),d->docLine(),d,nullptr,a.docs,TRUE,FALSE,
5934 QCString(),FALSE,FALSE,Config_getBool(MARKDOWN_SUPPORT));
5935 ol.endConstraintDocs();
5936 }
5937 ol.endConstraintList();
5938}
virtual int docLine() const =0
void endConstraintType()
Definition outputlist.h:713
void endConstraintList()
Definition outputlist.h:719
void startConstraintParam()
Definition outputlist.h:707
void startConstraintDocs()
Definition outputlist.h:715
void startConstraintType()
Definition outputlist.h:711
void endConstraintDocs()
Definition outputlist.h:717
void generateDoc(const QCString &fileName, int startLine, const Definition *ctx, const MemberDef *md, const QCString &docStr, bool indexWords, bool isExample, const QCString &exampleName, bool singleLine, bool linkFromIndex, bool markdownSupport)
void endConstraintParam()
Definition outputlist.h:709
void startConstraintList(const QCString &header)
Definition outputlist.h:705
Implements TextGeneratorIntf for an OutputDocInterface stream.
Definition util.h:77
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:904

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

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