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, bool keepEntities=false)
QCString getOverloadDocs ()
void addMembersToMemberGroup (MemberList *ml, MemberGroupList *pMemberGroups, const Definition *context)
int extractClassNameFromType (const QCString &type, int &pos, QCString &name, QCString &templSpec, SrcLangExt=SrcLangExt::Unknown)
QCString normalizeNonTemplateArgumentsInString (const QCString &name, const Definition *context, const ArgumentList &formalArgs)
QCString substituteTemplateArgumentsInString (const QCString &name, const ArgumentList &formalArgs, const ArgumentList *actualArgs)
QCString stripTemplateSpecifiersFromScope (const QCString &fullName, bool parentOnly=TRUE, QCString *lastScopeStripped=nullptr, QCString scopeName=QCString(), bool allowArtificial=true)
QCString resolveTypeDef (const Definition *d, const QCString &name, const Definition **typedefContext=nullptr)
QCString mergeScopes (const QCString &leftScope, const QCString &rightScope)
int getScopeFragment (const QCString &s, int p, int *l)
void addRefItem (const RefItemVector &sli, const QCString &key, const QCString &prefix, const QCString &name, const QCString &title, const QCString &args, const Definition *scope)
PageDefaddRelatedPage (const QCString &name, const QCString &ptitle, const QCString &doc, const QCString &fileName, int docLine, int startLine, const RefItemVector &sli=RefItemVector(), GroupDef *gd=nullptr, const TagInfo *tagInfo=nullptr, bool xref=FALSE, SrcLangExt lang=SrcLangExt::Unknown)
bool getCaseSenseNames ()
QCString escapeCharsInString (const QCString &name, bool allowDots, bool allowUnderscore=FALSE)
QCString unescapeCharsInString (const QCString &s)
void addGroupListToTitle (OutputList &ol, const Definition *d)
QCString linkToText (SrcLangExt lang, const QCString &link, bool isFileName)
bool checkExtension (const QCString &fName, const QCString &ext)
void addHtmlExtensionIfMissing (QCString &fName)
QCString stripExtensionGeneral (const QCString &fName, const QCString &ext)
QCString stripExtension (const QCString &fName)
int computeQualifiedIndex (const QCString &name)
 Return the index of the last :: in the string name that is still before the first <.
void addDirPrefix (QCString &fileName)
QCString relativePathToRoot (const QCString &name)
QCString determineAbsoluteIncludeName (const QCString &curFile, const QCString &incFileName)
void createSubDirs (const Dir &d)
void clearSubDirs (const Dir &d)
QCString removeLongPathMarker (QCString path)
QCString stripPath (const QCString &s)
bool containsWord (const QCString &s, const char *word)
 returns TRUE iff string s contains word w
bool findAndRemoveWord (QCString &s, const char *word)
 removes occurrences of whole word from sentence, while keeps internal spaces and reducing multiple sequences of spaces.
QCString stripLeadingAndTrailingEmptyLines (const QCString &s, int &docLine)
 Special version of QCString::stripWhiteSpace() that only strips completely blank lines.
bool updateLanguageMapping (const QCString &extension, const QCString &parser)
SrcLangExt getLanguageFromFileName (const QCString &fileName, SrcLangExt defLang=SrcLangExt::Cpp)
SrcLangExt getLanguageFromCodeLang (QCString &fileName)
 Routine to handle the language attribute of the \code command.
QCString getFileNameExtension (const QCString &fn)
void initDefaultExtensionMapping ()
void addCodeOnlyMappings ()
bool checkIfTypedef (const Definition *scope, const FileDef *fileScope, const QCString &n)
QCString parseCommentAsText (const Definition *scope, const MemberDef *member, const QCString &doc, const QCString &fileName, int lineNr)
QCString parseCommentAsHtml (const Definition *scope, const MemberDef *member, const QCString &doc, const QCString &fileName, int lineNr)
bool transcodeCharacterStringToUTF8 (std::string &input, const char *inputEncoding)
QCString recodeString (const QCString &str, const char *fromEncoding, const char *toEncoding)
void writeTypeConstraints (OutputList &ol, const Definition *d, const ArgumentList &al)
QCString convertCharEntitiesToUTF8 (const QCString &s)
void stackTrace ()
bool readInputFile (const QCString &fileName, std::string &contents, bool filter=TRUE, bool isSourceCode=FALSE)
 read a file name fileName and optionally filter and transcode it
QCString filterTitle (const QCString &title)
bool patternMatch (const FileInfo &fi, const StringVector &patList)
QCString externalLinkTarget (const bool parent=false)
QCString createHtmlUrl (const QCString &relPath, const QCString &ref, bool href, bool islocalFile, const QCString &targetFileName, const QCString &anchor)
QCString externalRef (const QCString &relPath, const QCString &ref, bool href)
int nextUtf8CharPosition (const QCString &utf8Str, uint32_t len, uint32_t startPos)
void writeMarkerList (OutputList &ol, const std::string &markerText, size_t numMarkers, std::function< void(size_t)> replaceFunc)
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 5712 of file util.cpp.

5713{
5714 updateLanguageMapping(".xml", "xml");
5715 updateLanguageMapping(".sql", "sql");
5716}
bool updateLanguageMapping(const QCString &extension, const QCString &language)
Definition util.cpp:5613

References updateLanguageMapping().

Referenced by generateOutput().

◆ addDirPrefix()

void addDirPrefix ( QCString & fileName)

◆ addGroupListToTitle()

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

◆ addHtmlExtensionIfMissing()

void addHtmlExtensionIfMissing ( QCString & fName)

Definition at line 5412 of file util.cpp.

5413{
5414 if (fName.isEmpty()) return;
5415 int i_fs = fName.findRev('/');
5416 int i_bs = fName.findRev('\\');
5417 int i = fName.find('.',std::max({ i_fs, i_bs ,0})); // search for . after path part
5418 if (i==-1)
5419 {
5421 }
5422}
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 4607 of file util.cpp.

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

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

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

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

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

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

7034{
7035 if (s.isEmpty()) return;
7036
7037 const char *p = s.data();
7038 char c = 0;
7039 while ((c=*p))
7040 {
7041 if (c==markerInfo.markerChar) // potential start of marker
7042 {
7043 if (qstrncmp(p,markerInfo.beginStr,markerInfo.beginLen)==0) // start of begin marker
7044 {
7045 size_t len = markerInfo.beginLen;
7046 bool negate = *(p+len)=='!';
7047 if (negate) len++;
7048 p += len;
7049 QCString marker;
7050 while (*p)
7051 {
7052 if (markerInfo.closeLen==0 && *p=='\n') // matching end of line
7053 {
7054 warn(fileName,-1,"Remaining begin replacement with marker '{}'",marker);
7055 break;
7056 }
7057 else if (markerInfo.closeLen!= 0 && qstrncmp(p,markerInfo.closeStr,markerInfo.closeLen)==0) // matching marker closing
7058 {
7059 p += markerInfo.closeLen;
7060 warn(fileName,-1,"Remaining begin replacement with marker '{}'",marker);
7061 break;
7062 }
7063 marker += *p;
7064 p++;
7065 }
7066 }
7067 else if (qstrncmp(p,markerInfo.endStr,markerInfo.endLen)==0) // start of end marker
7068 {
7069 size_t len = markerInfo.endLen;
7070 bool negate = *(p+len)=='!';
7071 if (negate) len++;
7072 p += len;
7073 QCString marker;
7074 while (*p)
7075 {
7076 if (markerInfo.closeLen==0 && *p=='\n') // matching end of line
7077 {
7078 warn(fileName,-1,"Remaining end replacement with marker '{}'",marker);
7079 break;
7080 }
7081 else if (markerInfo.closeLen!= 0 && qstrncmp(p,markerInfo.closeStr,markerInfo.closeLen)==0) // matching marker closing
7082 {
7083 p += markerInfo.closeLen;
7084 warn(fileName,-1,"Remaining end replacement with marker '{}'",marker);
7085 break;
7086 }
7087 marker += *p;
7088 p++;
7089 }
7090 }
7091 }
7092 p++;
7093 }
7094}
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 5407 of file util.cpp.

5408{
5409 return fName.right(ext.length())==ext;
5410}

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

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

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

Referenced by isVarWithConstructor().

◆ clearSubDirs()

void clearSubDirs ( const Dir & d)

Definition at line 4180 of file util.cpp.

4181{
4182 if (Config_getBool(CREATE_SUBDIRS))
4183 {
4184 // remove empty subdirectories
4185 int createSubdirsLevelPow2 = 1 << Config_getInt(CREATE_SUBDIRS_LEVEL);
4186 for (int l1=0;l1<16;l1++)
4187 {
4188 QCString subdir;
4189 subdir.sprintf("d%x",l1);
4190 for (int l2=0; l2 < createSubdirsLevelPow2; l2++)
4191 {
4192 QCString subsubdir;
4193 subsubdir.sprintf("d%x/d%02x",l1,l2);
4194 if (d.exists(subsubdir.str()) && d.isEmpty(subsubdir.str()))
4195 {
4196 d.rmdir(subsubdir.str());
4197 }
4198 }
4199 if (d.exists(subdir.str()) && d.isEmpty(subdir.str()))
4200 {
4201 d.rmdir(subdir.str());
4202 }
4203 }
4204 }
4205}
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 7335 of file util.cpp.

7336{
7337 int l = static_cast<int>(name.length());
7338 int lastSepPos = -1;
7339 const char *p = name.data();
7340 int i=l-2;
7341 int sharpCount=0;
7342 // --- begin optimized version of ts=name.findRev(">::");
7343 int ts = -1;
7344 while (i>=0)
7345 {
7346 if (p[i]=='>')
7347 {
7348 if (sharpCount==0 && p[i+1]==':' && p[i+2]==':')
7349 {
7350 ts=i;
7351 break;
7352 }
7353 sharpCount++;
7354 }
7355 else if (p[i]=='<')
7356 {
7357 sharpCount--;
7358 }
7359 i--;
7360 }
7361 // --- end optimized version
7362 if (ts==-1) ts=0; else p+=++ts;
7363 for (i=ts;i<l-1;i++)
7364 {
7365 char c=*p++;
7366 if (c==':' && *p==':') lastSepPos=i;
7367 if (c=='<') break;
7368 }
7369 return lastSepPos;
7370}

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

5479{
5480 if (str.isEmpty() || word==nullptr) return false;
5481 static const reg::Ex re(R"(\a+)");
5482 std::string s = str.str();
5483 for (reg::Iterator it(s,re) ; it!=reg::Iterator() ; ++it)
5484 {
5485 if (it->str()==word) return true;
5486 }
5487 return false;
5488}
Class representing a regular expression.
Definition regex.h:39
Class to iterate through matches.
Definition regex.h:232

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

◆ convertCharEntitiesToUTF8()

QCString convertCharEntitiesToUTF8 ( const QCString & s)

Definition at line 4557 of file util.cpp.

4558{
4559 if (str.isEmpty()) return QCString();
4560
4561 std::string s = str.data();
4562 static const reg::Ex re(R"(&\a\w*;)");
4563 reg::Iterator it(s,re);
4565
4566 GrowBuf growBuf;
4567 size_t p=0, i=0, l=0;
4568 for (; it!=end ; ++it)
4569 {
4570 const auto &match = *it;
4571 p = match.position();
4572 l = match.length();
4573 if (p>i)
4574 {
4575 growBuf.addStr(s.substr(i,p-i));
4576 }
4577 QCString entity(match.str());
4579 const char *code=nullptr;
4580 if (symType!=HtmlEntityMapper::Sym_Unknown && (code=HtmlEntityMapper::instance().utf8(symType)))
4581 {
4582 growBuf.addStr(code);
4583 }
4584 else
4585 {
4586 growBuf.addStr(entity);
4587 }
4588 i=p+l;
4589 }
4590 growBuf.addStr(s.substr(i));
4591 growBuf.addChar(0);
4592 //printf("convertCharEntitiesToUTF8(%s)->%s\n",qPrint(s),growBuf.get());
4593 return growBuf.get();
4594}
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 6907 of file util.cpp.

6908{
6910 QCString parserName = Doxygen::parserManager->getParserName(ext);
6911
6912 if (parserName == "fortranfixed") return FortranFormat::Fixed;
6913 else if (parserName == "fortranfree") return FortranFormat::Free;
6914
6916}
static ParserManager * parserManager
Definition doxygen.h:131
QCString getFileNameExtension(const QCString &fn)
Definition util.cpp:5760

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

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

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

6746{
6747 bool extractPrivate = Config_getBool(EXTRACT_PRIVATE);
6748
6749 // default representing 1-1 mapping
6750 *outListType1=inListType;
6751 *outListType2=MemberListType::Invalid();
6752
6753 if (inProt==Protection::Public)
6754 {
6755 if (inListType.isPrivate())
6756 {
6757 *outListType1=MemberListType::Invalid();
6758 }
6759 }
6760 else if (inProt==Protection::Protected)
6761 {
6762 if (inListType.isPrivate() || inListType.isPublic())
6763 {
6764 *outListType1=MemberListType::Invalid();
6765 }
6766 else if (inListType.isProtected())
6767 {
6768 *outListType2=inListType.toPublic();
6769 }
6770 }
6771 else if (inProt==Protection::Private)
6772 {
6773 if (inListType.isPublic() || inListType.isProtected())
6774 {
6775 *outListType1=MemberListType::Invalid();
6776 }
6777 else if (inListType.isPrivate())
6778 {
6779 if (extractPrivate)
6780 {
6781 *outListType1=inListType.toPublic();
6782 *outListType2=inListType.toProtected();
6783 }
6784 else
6785 {
6786 *outListType1=MemberListType::Invalid();
6787 }
6788 }
6789 }
6790
6791 //printf("convertProtectionLevel(type=%s prot=%d): %s,%s\n",
6792 // qPrint(inListType.to_string()),inProt,qPrint(outListType1->to_string()),qPrint(outListType2->to_string()));
6793}
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 4476 of file util.cpp.

4477{
4478 if (s.isEmpty()) return s;
4479 GrowBuf growBuf;
4480 const char *p=s.data();
4481 char c = 0;
4482 while ((c=*p++))
4483 {
4484 switch (c)
4485 {
4486 case '<': growBuf.addStr("&lt;"); break;
4487 case '>': growBuf.addStr("&gt;"); break;
4488 case '&': if (keepEntities)
4489 {
4490 const char *e=p;
4491 char ce = 0;
4492 while ((ce=*e++))
4493 {
4494 if (ce==';' || (!(isId(ce) || ce=='#'))) break;
4495 }
4496 if (ce==';') // found end of an entity
4497 {
4498 // copy entry verbatim
4499 growBuf.addChar(c);
4500 while (p<e) growBuf.addChar(*p++);
4501 }
4502 else
4503 {
4504 growBuf.addStr("&amp;");
4505 }
4506 }
4507 else
4508 {
4509 growBuf.addStr("&amp;");
4510 }
4511 break;
4512 case '\'': growBuf.addStr("&#39;"); break;
4513 case '"': growBuf.addStr("&quot;"); break;
4514 default:
4515 {
4516 uint8_t uc = static_cast<uint8_t>(c);
4517 if (uc<32 && !isspace(c))
4518 {
4519 growBuf.addStr("&#x24");
4520 growBuf.addChar(hex[uc>>4]);
4521 growBuf.addChar(hex[uc&0xF]);
4522 growBuf.addChar(';');
4523 }
4524 else
4525 {
4526 growBuf.addChar(c);
4527 }
4528 }
4529 break;
4530 }
4531 }
4532 growBuf.addChar(0);
4533 return growBuf.get();
4534}
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::writeLogoAsString(), writeMapArea(), HtmlGenerator::writePageFooter(), ClassDefImpl::writeQuickMemberLinks(), FileDefImpl::writeQuickMemberLinks(), GroupDefImpl::writeQuickMemberLinks(), NamespaceDefImpl::writeQuickMemberLinks(), and HtmlGenerator::writeSearchPage().

◆ convertToId()

QCString convertToId ( const QCString & s)

Converts a string to a HTML id string

Definition at line 4385 of file util.cpp.

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

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

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

◆ convertToJSString()

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

Definition at line 4536 of file util.cpp.

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

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

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

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

4419{
4420 if (s.isEmpty()) return s;
4421 return "a" + s;
4422}

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

6439{
6440 QCString result = url;
6441 if (!relPath.isEmpty() && !isURL(url))
6442 {
6443 result.prepend(relPath);
6444 }
6445 return result;
6446}
bool isURL(const QCString &url)
Checks whether the given url starts with a supported protocol.
Definition util.cpp:6426

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

6239{
6240 QCString url;
6241 if (!ref.isEmpty())
6242 {
6243 url = externalRef(relPath,ref,href);
6244 }
6245 if (!targetFileName.isEmpty())
6246 {
6247 QCString fn = targetFileName;
6248 if (ref.isEmpty())
6249 {
6250 if (!anchor.isEmpty() && isLocalFile)
6251 {
6252 fn=""; // omit file name for local links
6253 }
6254 else
6255 {
6256 url = relPath;
6257 }
6258 }
6259 url+=fn;
6260 }
6261 if (!anchor.isEmpty()) url+="#"+anchor;
6262 //printf("createHtmlUrl(relPath=%s,local=%d,target=%s,anchor=%s)=%s\n",qPrint(relPath),isLocalFile,qPrint(targetFileName),qPrint(anchor),qPrint(url));
6263 return url;
6264}
QCString externalRef(const QCString &relPath, const QCString &ref, bool href)
Definition util.cpp:6266

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

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

7435{
7436 QCString result=name;
7437 if (result.endsWith("-g"))
7438 {
7439 int idx = result.find('-');
7440 result = result.left(idx)+templArgs;
7441 }
7442 return result;
7443}

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

Referenced by ClassDefImpl::className().

◆ detab()

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

Definition at line 7231 of file util.cpp.

7232{
7233 int tabSize = Config_getInt(TAB_SIZE);
7234 size_t size = s.length();
7235 GrowBuf out(size);
7236 const char *data = s.data();
7237 size_t i=0;
7238 int col=0;
7239 constexpr auto doxy_nbsp = "&_doxy_nbsp;"; // doxygen escape command for UTF-8 nbsp
7240 const int maxIndent=1000000; // value representing infinity
7241 int minIndent=maxIndent;
7242 bool skip = false;
7243 while (i<size)
7244 {
7245 char c = data[i++];
7246 switch(c)
7247 {
7248 case '\t': // expand tab
7249 {
7250 int stop = tabSize - (col%tabSize);
7251 //printf("expand at %d stop=%d\n",col,stop);
7252 col+=stop;
7253 while (stop--) out.addChar(' ');
7254 }
7255 break;
7256 case '\\':
7257 if (data[i] == '\\') // escaped command -> ignore
7258 {
7259 out.addChar(c);
7260 out.addChar(data[i++]);
7261 col+=2;
7262 }
7263 else if (i+5<size && literal_at(data+i,"iskip")) // \iskip command
7264 {
7265 i+=5;
7266 skip = true;
7267 }
7268 else if (i+8<size && literal_at(data+i,"endiskip")) // \endiskip command
7269 {
7270 i+=8;
7271 skip = false;
7272 }
7273 else // some other command
7274 {
7275 out.addChar(c);
7276 col++;
7277 }
7278 break;
7279 case '\n': // reset column counter
7280 out.addChar(c);
7281 col=0;
7282 break;
7283 case ' ': // increment column counter
7284 out.addChar(c);
7285 col++;
7286 break;
7287 default: // non-whitespace => update minIndent
7288 if (c<0 && i<size) // multibyte sequence
7289 {
7290 // special handling of the UTF-8 nbsp character 0xC2 0xA0
7291 int nb = isUTF8NonBreakableSpace(data);
7292 if (nb>0)
7293 {
7294 out.addStr(doxy_nbsp);
7295 i+=nb-1;
7296 }
7297 else
7298 {
7299 int bytes = getUTF8CharNumBytes(c);
7300 for (int j=0;j<bytes-1 && c;j++)
7301 {
7302 out.addChar(c);
7303 c = data[i++];
7304 }
7305 out.addChar(c);
7306 }
7307 }
7308 else
7309 {
7310 out.addChar(c);
7311 }
7312 if (!skip && col<minIndent) minIndent=col;
7313 col++;
7314 }
7315 }
7316 if (minIndent!=maxIndent) refIndent=minIndent; else refIndent=0;
7317 out.addChar(0);
7318 //printf("detab(\n%s\n)=[\n%s\n]\n",qPrint(s),qPrint(out.get()));
7319 return out.get();
7320}
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 4113 of file util.cpp.

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

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

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

6223{
6224 bool extLinksInWindow = Config_getBool(EXT_LINKS_IN_WINDOW);
6225 if (extLinksInWindow)
6226 return "target=\"_blank\" ";
6227 else if (parent)
6228 return "target=\"_parent\" ";
6229 else
6230 return "";
6231}
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:1330

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

6267{
6268 QCString result;
6269 if (!ref.isEmpty())
6270 {
6271 auto it = Doxygen::tagDestinationMap.find(ref.str());
6273 {
6274 result = it->second;
6275 size_t l = result.length();
6276 if (!relPath.isEmpty() && l>0 && result.at(0)=='.')
6277 { // relative path -> prepend relPath.
6278 result.prepend(relPath);
6279 l+=relPath.length();
6280 }
6281 if (l>0 && result.at(l-1)!='/') result+='/';
6282 if (!href) result.append("\" ");
6283 }
6284 }
6285 else
6286 {
6287 result = relPath;
6288 }
6289 return result;
6290}
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 4725 of file util.cpp.

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

6690{
6691 std::string s = docs.str();
6692 static const reg::Ex re(R"(\[([ inout,]+)\])");
6693 reg::Iterator it(s,re);
6695 if (it!=end)
6696 {
6697 const auto &match = *it;
6698 size_t p = match.position();
6699 size_t l = match.length();
6700 if (p==0 && l>2)
6701 {
6702 // make dir the part inside [...] without separators
6703 std::string dir = match[1].str();
6704 // strip , and ' ' from dir
6705 dir.erase(std::remove_if(dir.begin(),dir.end(),
6706 [](const char c) { return c==' ' || c==','; }
6707 ),dir.end());
6708 unsigned char ioMask=0;
6709 size_t inIndex = dir.find( "in");
6710 if ( inIndex!=std::string::npos) dir.erase( inIndex,2),ioMask|=(1<<0);
6711 size_t outIndex = dir.find("out");
6712 if (outIndex!=std::string::npos) dir.erase(outIndex,3),ioMask|=(1<<1);
6713 if (dir.empty() && ioMask!=0) // only in and/or out attributes found
6714 {
6715 docs = s.substr(l); // strip attributes
6716 if (ioMask==((1<<0)|(1<<1))) return "[in,out]";
6717 else if (ioMask==(1<<0)) return "[in]";
6718 else if (ioMask==(1<<1)) return "[out]";
6719 }
6720 }
6721 }
6722 return "";
6723}

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

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

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

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

6601{
6602 bool allExternals = Config_getBool(ALLEXTERNALS);
6603 bool isDocFile = fd->isDocumentationFile();
6604 genSourceFile = !isDocFile && fd->generateSourceFile();
6605 return ( ((allExternals && fd->isLinkable()) ||
6607 ) &&
6608 !isDocFile
6609 );
6610}
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 6127 of file util.cpp.

6128{
6129 std::string tf;
6130 std::string t = title.str();
6131 static const reg::Ex re(R"(%[a-z_A-Z]+)");
6132 reg::Iterator it(t,re);
6134 size_t p = 0;
6135 for (; it!=end ; ++it)
6136 {
6137 const auto &match = *it;
6138 size_t i = match.position();
6139 size_t l = match.length();
6140 if (i>p) tf+=t.substr(p,i-p);
6141 tf+=match.str().substr(1); // skip %
6142 p=i+l;
6143 }
6144 tf+=t.substr(p);
6145 return QCString(tf);
6146}

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

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

◆ findAndRemoveWord()

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

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

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

Definition at line 5494 of file util.cpp.

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

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

Referenced by isVarWithConstructor().

◆ findFileDef()

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

Definition at line 3416 of file util.cpp.

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

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

3500{
3501 ambig=false;
3502 QCString result;
3503 bool found=false;
3504 if (!found)
3505 {
3506 FileInfo fi(file.str());
3507 if (fi.exists())
3508 {
3509 result=fi.absFilePath();
3510 found=true;
3511 }
3512 }
3513 if (!found)
3514 {
3515 const StringVector &examplePathList = Config_getList(EXAMPLE_PATH);
3516 for (const auto &s : examplePathList)
3517 {
3518 std::string absFileName = s+(Portable::pathSeparator()+file).str();
3519 FileInfo fi(absFileName);
3520 if (fi.exists())
3521 {
3522 result=fi.absFilePath();
3523 found=true;
3524 }
3525 }
3526 }
3527
3528 if (!found)
3529 {
3530 // as a fallback we also look in the exampleNameDict
3532 if (fd && !ambig)
3533 {
3534 result=fd->absFilePath();
3535 }
3536 }
3537 return result;
3538}
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:3416

References FileDef::absFilePath(), FileInfo::absFilePath(), Config_getList, Doxygen::exampleNameLinkedMap, FileInfo::exists(), findFileDef(), 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 7173 of file util.cpp.

7174{
7176 return reg::search(s,match,re) ? static_cast<int>(match.position()) : -1;
7177}
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 7165 of file util.cpp.

7166{
7167 auto it = std::find(sv.begin(),sv.end(),s);
7168 return it!=sv.end() ? static_cast<int>(it-sv.begin()) : -1;
7169}

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

◆ fixSpaces()

QCString fixSpaces ( const QCString & s)
inline

Definition at line 472 of file util.h.

472{ 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 4071 of file util.cpp.

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

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

◆ generateFileRef()

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

Definition at line 3388 of file util.cpp.

3389{
3390 //printf("generateFileRef(%s,%s)\n",name,text);
3391 QCString linkText = text.isEmpty() ? text : name;
3392 //FileInfo *fi;
3393 bool ambig = false;
3395 if (fd && fd->isLinkable())
3396 // link to documented input file
3397 ol.writeObjectLink(fd->getReference(),fd->getOutputFileBase(),QCString(),linkText);
3398 else
3399 ol.docify(linkText);
3400}
static FileNameLinkedMap * inputNameLinkedMap
Definition doxygen.h:105
void writeObjectLink(const QCString &ref, const QCString &file, const QCString &anchor, const QCString &name)
Definition outputlist.h:441
void docify(const QCString &s)
Definition outputlist.h:439

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

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

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

3834{
3835 auto caseSenseNames = Config_getEnum(CASE_SENSE_NAMES);
3836
3837 if (caseSenseNames == CASE_SENSE_NAMES_t::YES) return true;
3838 else if (caseSenseNames == CASE_SENSE_NAMES_t::NO) return false;
3840}
#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 2823 of file util.cpp.

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

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

◆ getDotImageExtension()

QCString getDotImageExtension ( )

Definition at line 6800 of file util.cpp.

6801{
6802 QCString imgExt = Config_getEnumAsString(DOT_IMAGE_FORMAT);
6803 int i= imgExt.find(':'); // strip renderer part when using e.g. 'png:cairo:gd' as format
6804 return i==-1 ? imgExt : imgExt.left(i);
6805}
#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 6208 of file util.cpp.

6209{
6210 InputFileEncoding elem;
6211 auto getter = [](const InputFileEncoding &e) { return e.pattern; };
6212 if (genericPatternMatch(fi,Doxygen::inputFileEncodingList,elem,getter)) // check for file specific encoding
6213 {
6214 return elem.encoding;
6215 }
6216 else // fall back to default encoding
6217 {
6218 return Config_getString(INPUT_ENCODING);
6219 }
6220}
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:6151

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

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

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

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

◆ getFileNameExtension()

◆ getLanguageFromCodeLang()

SrcLangExt getLanguageFromCodeLang ( QCString & fileName)

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

Definition at line 5736 of file util.cpp.

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

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

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

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

6411{
6412 if (lang==SrcLangExt::Java || lang==SrcLangExt::CSharp || lang==SrcLangExt::VHDL || lang==SrcLangExt::Python)
6413 {
6414 return ".";
6415 }
6416 else if (lang==SrcLangExt::PHP && !classScope)
6417 {
6418 return "\\";
6419 }
6420 else
6421 {
6422 return "::";
6423 }
6424}

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

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

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

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

7323{
7324 QCString projectCookie = Config_getString(HTML_PROJECT_COOKIE);
7325 if (projectCookie.isEmpty()) return QCString();
7326 uint8_t md5_sig[16];
7327 char sigStr[34];
7328 MD5Buffer(projectCookie.data(),static_cast<unsigned int>(projectCookie.length()),md5_sig);
7329 MD5SigToString(md5_sig,sigStr);
7330 sigStr[32]='_'; sigStr[33]=0;
7331 return sigStr;
7332}

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

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

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

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

◆ guessSection()

EntryType guessSection ( const QCString & name)

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

Definition at line 350 of file util.cpp.

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

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

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

References updateLanguageMapping().

Referenced by initDoxygen().

◆ inlineArgListToDoc()

QCString inlineArgListToDoc ( const ArgumentList & al)

Definition at line 1157 of file util.cpp.

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

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

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

◆ inlineTemplateArgListToDoc()

QCString inlineTemplateArgListToDoc ( const ArgumentList & al)

Definition at line 1175 of file util.cpp.

1176{
1177 QCString paramDocs;
1178 if (al.hasTemplateDocumentation())
1179 {
1180 for (const Argument &a : al)
1181 {
1182 if (!a.docs.isEmpty())
1183 {
1184 if (!a.name.isEmpty())
1185 {
1186 paramDocs+=" \\ilinebr @tparam "+a.name+" "+a.docs;
1187 }
1188 else if (!a.type.isEmpty())
1189 {
1190 QCString type = a.type;
1191 type.stripPrefix("class ");
1192 type.stripPrefix("typename ");
1193 type = type.stripWhiteSpace();
1194 paramDocs+=" \\ilinebr @tparam "+type+" "+a.docs;
1195 }
1196 }
1197 }
1198 }
1199 return paramDocs;
1200}
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 4259 of file util.cpp.

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

7194{
7195 QCString result;
7196 int residual = n;
7197
7198 char modVal[2];
7199 modVal[1] = 0;
7200 while (residual > 0)
7201 {
7202 modVal[0] = (upper ? 'A': 'a') + (residual-1)%26;
7203 result = modVal + result;
7204 residual = (residual-1) / 26;
7205 }
7206 return result;
7207}

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

◆ integerToRoman()

QCString integerToRoman ( int n,
bool upper = true )

Definition at line 7209 of file util.cpp.

7210{
7211 static const char *str_romans_upper[] = { "M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I" };
7212 static const char *str_romans_lower[] = { "m", "cm", "d", "cd", "c", "xc", "l", "xl", "x", "ix", "v", "iv", "i" };
7213 static const int values[] = { 1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1 };
7214 static const char **str_romans = upper ? str_romans_upper : str_romans_lower;
7215
7216 QCString result;
7217 int residual = n;
7218
7219 for (int i = 0; i < 13; ++i)
7220 {
7221 while (residual - values[i] >= 0)
7222 {
7223 result += str_romans[i];
7224 residual -= values[i];
7225 }
7226 }
7227
7228 return result;
7229}

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

6427{
6428 static const std::unordered_set<std::string> schemes = {
6429 "http", "https", "ftp", "ftps", "sftp", "file", "news", "irc", "ircs"
6430 };
6431 QCString loc_url = url.stripWhiteSpace();
6432 int colonPos = loc_url.find(':');
6433 return colonPos!=-1 && schemes.find(loc_url.left(colonPos).str())!=schemes.end();
6434}

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

7181{
7182 std::string result;
7183 bool first=true;
7184 for (const auto &s : sv)
7185 {
7186 if (!first) result+=delimiter;
7187 first=false;
7188 result+=s;
7189 }
7190 return result;
7191}

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

◆ langToString()

QCString langToString ( SrcLangExt lang)

Returns a string representation of lang.

Definition at line 6404 of file util.cpp.

6405{
6406 return to_string(lang);
6407}
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 893 of file util.cpp.

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

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

6384{
6385 int result = 1;
6386
6387 // find the character positions of the first marker
6388 int m1 = text.find(marker);
6389 if (m1==-1) return result;
6390
6391 // find start line positions for the markers
6392 bool found=false;
6393 int p=0, i=0;
6394 while (!found && (i=text.find('\n',p))!=-1)
6395 {
6396 found = (p<=m1 && m1<i); // found the line with the start marker
6397 p=i+1;
6398 result++;
6399 }
6400 return result;
6401}

References QCString::find().

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

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

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

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

◆ linkToText()

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

Definition at line 3220 of file util.cpp.

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

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

6796{
6797 return Doxygen::mainPage!=nullptr && Doxygen::mainPage->hasTitle();
6798}
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 7424 of file util.cpp.

7425{
7426 int idx = name.find('<');
7427 if (idx!=-1)
7428 {
7429 return name.left(idx)+"-"+QCString().setNum(name.contains(",")+1)+"-g";
7430 }
7431 return name;
7432}
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 1959 of file util.cpp.

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

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

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

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

7373{
7374 if (Config_getBool(CALL_GRAPH) !=md1->hasCallGraph()) md2->overrideCallGraph(md1->hasCallGraph());
7375 if (Config_getBool(CALLER_GRAPH)!=md1->hasCallerGraph()) md2->overrideCallerGraph(md1->hasCallerGraph());
7376 if (Config_getBool(CALL_GRAPH) !=md2->hasCallGraph()) md1->overrideCallGraph( md2->hasCallGraph());
7377 if (Config_getBool(CALLER_GRAPH)!=md2->hasCallerGraph()) md1->overrideCallerGraph(md2->hasCallerGraph());
7378
7379 if (Config_getBool(SHOW_ENUM_VALUES) !=md1->hasEnumValues()) md2->overrideEnumValues(md1->hasEnumValues());
7380 if (Config_getBool(SHOW_ENUM_VALUES) !=md2->hasEnumValues()) md1->overrideEnumValues( md2->hasEnumValues());
7381
7382 if (Config_getBool(REFERENCED_BY_RELATION)!=md1->hasReferencedByRelation()) md2->overrideReferencedByRelation(md1->hasReferencedByRelation());
7383 if (Config_getBool(REFERENCES_RELATION) !=md1->hasReferencesRelation()) md2->overrideReferencesRelation(md1->hasReferencesRelation());
7384 if (Config_getBool(REFERENCED_BY_RELATION)!=md2->hasReferencedByRelation()) md1->overrideReferencedByRelation(md2->hasReferencedByRelation());
7385 if (Config_getBool(REFERENCES_RELATION) !=md2->hasReferencesRelation()) md1->overrideReferencesRelation(md2->hasReferencesRelation());
7386
7387 if (Config_getBool(INLINE_SOURCES)!=md1->hasInlineSource()) md2->overrideInlineSource(md1->hasInlineSource());
7388 if (Config_getBool(INLINE_SOURCES)!=md2->hasInlineSource()) md1->overrideInlineSource(md2->hasInlineSource());
7389}
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 5093 of file util.cpp.

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

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

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

◆ nextUtf8CharPosition()

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

◆ normalizeNonTemplateArgumentsInString()

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

Definition at line 4799 of file util.cpp.

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

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

Referenced by findUsedClassesForClass().

◆ openOutputFile()

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

Definition at line 6807 of file util.cpp.

6808{
6809 assert(!f.is_open());
6810 bool fileOpened=FALSE;
6811 bool writeToStdout=outFile=="-";
6812 if (writeToStdout) // write to stdout
6813 {
6814 f.basic_ios<char>::rdbuf(std::cout.rdbuf());
6815 fileOpened = true;
6816 }
6817 else // write to file
6818 {
6819 FileInfo fi(outFile.str());
6820 if (fi.exists()) // create a backup
6821 {
6822 Dir dir;
6823 FileInfo backup(fi.filePath()+".bak");
6824 if (backup.exists()) // remove existing backup
6825 dir.remove(backup.filePath());
6826 dir.rename(fi.filePath(),fi.filePath()+".bak");
6827 }
6828 f = Portable::openOutputStream(outFile);
6829 fileOpened = f.is_open();
6830 }
6831 return fileOpened;
6832}
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().

◆ parseCommentAsHtml()

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

Definition at line 5927 of file util.cpp.

5928{
5929 std::lock_guard lock(g_docCacheMutex);
5930 auto it = g_docCache.find(doc.str());
5931 if (it != g_docCache.end())
5932 {
5933 //printf("Cache: [%s]->[%s]\n",qPrint(doc),qPrint(it->second));
5934 return it->second;
5935 }
5936 auto parser { createDocParser() };
5937 auto ast { validatingParseTitle(*parser.get(),fileName,lineNr,doc) };
5938 auto astImpl = dynamic_cast<const DocNodeAST*>(ast.get());
5939 QCString result;
5940 if (astImpl)
5941 {
5942 TextStream t;
5943 OutputCodeList codeList;
5944 codeList.add<HtmlCodeGenerator>(&t);
5945 HtmlDocVisitor visitor(t,codeList,scope,fileName);
5946 std::visit(visitor,astImpl->root);
5947 result = t.str();
5948 }
5949 else // fallback, should not happen
5950 {
5951 result = filterTitle(doc);
5952 }
5953 //printf("Conversion: [%s]->[%s]\n",qPrint(doc),qPrint(result));
5954 g_docCache.insert(std::make_pair(doc.str(),result));
5955 return result;
5956}
Class representing the abstract syntax tree of a documentation block.
Definition docnode.h:1466
Generator for HTML code fragments.
Definition htmlgen.h:26
Concrete visitor implementation for HTML output.
Class representing a list of different code generators.
Definition outputlist.h:164
void add(OutputCodeIntfPtr &&p)
Definition outputlist.h:194
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 validatingParseTitle(IDocParser &parserIntf, const QCString &fileName, int lineNr, const QCString &input)
static std::unordered_map< std::string, QCString > g_docCache
Definition util.cpp:5925
QCString filterTitle(const QCString &title)
Definition util.cpp:6127
static std::mutex g_docCacheMutex
Definition util.cpp:5924

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

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

◆ parseCommentAsText()

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

Definition at line 5876 of file util.cpp.

5878{
5879 if (doc.isEmpty()) return "";
5880 //printf("parseCommentAsText(%s)\n",qPrint(doc));
5881 TextStream t;
5882 auto parser { createDocParser() };
5883 auto ast { validatingParseDoc(*parser.get(),
5884 fileName,lineNr,
5885 scope,md,doc,FALSE,FALSE,
5886 QCString(),FALSE,FALSE,Config_getBool(MARKDOWN_SUPPORT),false) };
5887 auto astImpl = dynamic_cast<const DocNodeAST*>(ast.get());
5888 if (astImpl)
5889 {
5890 TextDocVisitor visitor(t);
5891 std::visit(visitor,astImpl->root);
5892 }
5893 QCString result = convertCharEntitiesToUTF8(t.str().c_str()).stripWhiteSpace();
5894 int i=0;
5895 int charCnt=0;
5896 int l=static_cast<int>(result.length());
5897 while ((i=nextUTF8CharPosition(result,l,i))<l)
5898 {
5899 charCnt++;
5900 if (charCnt>=80) break;
5901 }
5902 if (charCnt>=80) // try to truncate the string
5903 {
5904 while ((i=nextUTF8CharPosition(result,l,i))<l && charCnt<100)
5905 {
5906 charCnt++;
5907 if (result.at(i)==',' ||
5908 result.at(i)=='.' ||
5909 result.at(i)=='!' ||
5910 result.at(i)=='?' ||
5911 result.at(i)=='}') // good for UTF-16 characters and } otherwise also a good point to stop the string
5912 {
5913 i++; // we want to be "behind" last inspected character
5914 break;
5915 }
5916 }
5917 }
5918 if ( i < l) result=result.left(i)+"...";
5919 return result.data();
5920}
Concrete visitor implementation for TEXT output.
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, bool autolinkSupport)
static int nextUTF8CharPosition(const QCString &utf8Str, uint32_t len, uint32_t startPos)
Definition util.cpp:5832

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(), DefinitionImpl::computeTooltip(), writeGroupTreeNode(), writeIndex(), and writePages().

◆ patternMatch()

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

Definition at line 6201 of file util.cpp.

6202{
6203 std::string elem;
6204 auto getter = [](std::string s) { return QCString(s); };
6205 return genericPatternMatch(fi,patList,elem,getter);
6206}

References genericPatternMatch().

Referenced by checkAndOpenFile(), and readDir().

◆ processMarkup()

QCString processMarkup ( const QCString & s)

◆ projectLogoFile()

QCString projectLogoFile ( )

Definition at line 3658 of file util.cpp.

3659{
3660 QCString projectLogo = Config_getString(PROJECT_LOGO);
3661 if (!projectLogo.isEmpty())
3662 {
3663 // check for optional width= and height= specifier
3664 int wi = projectLogo.find(" width=");
3665 if (wi!=-1) // and strip them
3666 {
3667 projectLogo = projectLogo.left(wi);
3668 }
3669 int hi = projectLogo.find(" height=");
3670 if (hi!=-1)
3671 {
3672 projectLogo = projectLogo.left(hi);
3673 }
3674 }
3675 //printf("projectlogo='%s'\n",qPrint(projectLogo));
3676 return projectLogo;
3677}

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

Referenced by copyLogo(), and substituteKeywords().

◆ protectionLevelVisible()

bool protectionLevelVisible ( Protection prot)

Definition at line 6450 of file util.cpp.

6451{
6452 bool extractPrivate = Config_getBool(EXTRACT_PRIVATE);
6453 bool extractPackage = Config_getBool(EXTRACT_PACKAGE);
6454
6455 return (prot!=Protection::Private && prot!=Protection::Package) ||
6456 (prot==Protection::Private && extractPrivate) ||
6457 (prot==Protection::Package && extractPackage);
6458}

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

6048{
6049 // try to open file
6050 FileInfo fi(fileName.str());
6051 if (!fi.exists()) return FALSE;
6052 QCString filterName = getFileFilter(fileName,isSourceCode);
6053 if (filterName.isEmpty() || !filter)
6054 {
6055 std::ifstream f = Portable::openInputStream(fileName,true);
6056 if (!f.is_open())
6057 {
6058 err("could not open file {}\n",fileName);
6059 return FALSE;
6060 }
6061 // read the file
6062 auto fileSize = fi.size();
6063 contents.resize(fileSize);
6064 f.read(contents.data(),fileSize);
6065 if (f.fail())
6066 {
6067 err("problems while reading file {}\n",fileName);
6068 return FALSE;
6069 }
6070 }
6071 else
6072 {
6073 QCString cmd=filterName+" \""+fileName+"\"";
6074 Debug::print(Debug::ExtCmd,0,"Executing popen(`{}`)\n",cmd);
6075 FILE *f=Portable::popen(cmd,"r");
6076 if (!f)
6077 {
6078 err("could not execute filter {}\n",filterName);
6079 return FALSE;
6080 }
6081 const int bufSize=4096;
6082 char buf[bufSize];
6083 int numRead = 0;
6084 while ((numRead=static_cast<int>(fread(buf,1,bufSize,f)))>0)
6085 {
6086 //printf(">>>>>>>>Reading %d bytes\n",numRead);
6087 contents.append(buf,numRead);
6088 }
6090 Debug::print(Debug::FilterOutput, 0, "Filter output\n");
6091 Debug::print(Debug::FilterOutput,0,"-------------\n{}\n-------------\n",contents);
6092 }
6093
6094 if (contents.size()>=2 &&
6095 static_cast<uint8_t>(contents[0])==0xFF &&
6096 static_cast<uint8_t>(contents[1])==0xFE // Little endian BOM
6097 ) // UCS-2LE encoded file
6098 {
6099 transcodeCharacterBuffer(fileName,contents,"UCS-2LE","UTF-8");
6100 }
6101 else if (contents.size()>=2 &&
6102 static_cast<uint8_t>(contents[0])==0xFE &&
6103 static_cast<uint8_t>(contents[1])==0xFF // big endian BOM
6104 ) // UCS-2BE encoded file
6105 {
6106 transcodeCharacterBuffer(fileName,contents,"UCS-2BE","UTF-8");
6107 }
6108 else if (contents.size()>=3 &&
6109 static_cast<uint8_t>(contents[0])==0xEF &&
6110 static_cast<uint8_t>(contents[1])==0xBB &&
6111 static_cast<uint8_t>(contents[2])==0xBF
6112 ) // UTF-8 encoded file
6113 {
6114 contents.erase(0,3); // remove UTF-8 BOM: no translation needed
6115 }
6116 else // transcode according to the INPUT_ENCODING setting
6117 {
6118 // do character transcoding if needed.
6119 transcodeCharacterBuffer(fileName,contents,getEncoding(fi),"UTF-8");
6120 }
6121
6122 filterCRLF(contents);
6123 return true;
6124}
@ 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:1303
static void transcodeCharacterBuffer(const QCString &fileName, std::string &contents, const QCString &inputEncoding, const QCString &outputEncoding)
Definition util.cpp:6011
QCString getEncoding(const FileInfo &fi)
Definition util.cpp:6208
QCString getFileFilter(const QCString &name, bool isSourceCode)
Definition util.cpp:1370

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

6855{
6856 int column=0;
6857 bool skipLine=FALSE;
6858
6859 if (format == FortranFormat::Fixed) return TRUE;
6860 if (format == FortranFormat::Free) return FALSE;
6861
6862 int tabSize=Config_getInt(TAB_SIZE);
6863 size_t sizCont = contents.length();
6864 for (size_t i=0;i<sizCont;i++)
6865 {
6866 column++;
6867
6868 switch(contents.at(i))
6869 {
6870 case '\n':
6871 column=0;
6872 skipLine=FALSE;
6873 break;
6874 case '\t':
6875 column += tabSize-1;
6876 break;
6877 case ' ':
6878 break;
6879 case '\000':
6880 return FALSE;
6881 case '#':
6882 skipLine=TRUE;
6883 break;
6884 case 'C':
6885 case 'c':
6886 if (column==1)
6887 {
6888 return !keyWordsFortranC(contents.data()+i);
6889 }
6890 // fallthrough
6891 case '*':
6892 if (column==1) return TRUE;
6893 if (skipLine) break;
6894 return FALSE;
6895 case '!':
6896 if (column!=6) skipLine=TRUE;
6897 break;
6898 default:
6899 if (skipLine) break;
6900 if (column>=7) return TRUE;
6901 return FALSE;
6902 }
6903 }
6904 return FALSE;
6905}
static bool keyWordsFortranC(const char *contents)
Definition util.cpp:6834

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

4093{
4094 QCString result;
4095 if (Config_getBool(CREATE_SUBDIRS))
4096 {
4097 if (name.isEmpty())
4098 {
4099 return REL_PATH_TO_ROOT;
4100 }
4101 else
4102 {
4103 int i = name.findRev('/');
4104 if (i!=-1)
4105 {
4106 result=REL_PATH_TO_ROOT;
4107 }
4108 }
4109 }
4110 return result;
4111}
#define REL_PATH_TO_ROOT
Definition util.cpp:96

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

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

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

7098{
7099 std::string out;
7100 out.reserve(s.length());
7101 const char *p=s.data();
7102 if (p)
7103 {
7104 char c = 0;
7105 while ((c=*p++))
7106 {
7107 if (c=='\n')
7108 {
7109 const char *e = p;
7110 while (*e==' ' || *e=='\t') e++;
7111 if (*e=='\n')
7112 {
7113 p=e;
7114 }
7115 else out+=c;
7116 }
7117 else
7118 {
7119 out+=c;
7120 }
7121 }
7122 }
7123 //printf("removeEmptyLines(%s)=%s\n",qPrint(s),qPrint(out));
7124 return out;
7125}

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

Referenced by substituteHtmlKeywords(), and substituteLatexKeywords().

◆ removeLongPathMarker()

QCString removeLongPathMarker ( QCString path)

Definition at line 299 of file util.cpp.

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

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

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

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

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

6320{
6321 if (str.isEmpty()) return QCString();
6322 std::string result;
6323 std::string s=str.str();
6324 static const reg::Ex re(R"(##[0-9A-Fa-f][0-9A-Fa-f])");
6325 reg::Iterator it(s,re);
6327 int hue = Config_getInt(HTML_COLORSTYLE_HUE);
6328 int sat = Config_getInt(HTML_COLORSTYLE_SAT);
6329 int gamma = Config_getInt(HTML_COLORSTYLE_GAMMA);
6330 size_t sl=s.length();
6331 size_t p=0;
6332 for (; it!=end ; ++it)
6333 {
6334 const auto &match = *it;
6335 size_t i = match.position();
6336 size_t l = match.length();
6337 if (i>p) result+=s.substr(p,i-p);
6338 std::string lumStr = match.str().substr(2);
6339#define HEXTONUM(x) (((x)>='0' && (x)<='9') ? ((x)-'0') : \
6340 ((x)>='a' && (x)<='f') ? ((x)-'a'+10) : \
6341 ((x)>='A' && (x)<='F') ? ((x)-'A'+10) : 0)
6342
6343 double r = 0,g = 0,b = 0;
6344 int level = HEXTONUM(lumStr[0])*16+HEXTONUM(lumStr[1]);
6345 ColoredImage::hsl2rgb(hue/360.0,sat/255.0,
6346 pow(level/255.0,gamma/100.0),&r,&g,&b);
6347 int red = static_cast<int>(r*255.0);
6348 int green = static_cast<int>(g*255.0);
6349 int blue = static_cast<int>(b*255.0);
6350 char colStr[8];
6351 colStr[0]='#';
6352 colStr[1]=hex[red>>4];
6353 colStr[2]=hex[red&0xf];
6354 colStr[3]=hex[green>>4];
6355 colStr[4]=hex[green&0xf];
6356 colStr[5]=hex[blue>>4];
6357 colStr[6]=hex[blue&0xf];
6358 colStr[7]=0;
6359 //printf("replacing %s->%s (level=%d)\n",qPrint(lumStr),colStr,level);
6360 result+=colStr;
6361 p=i+l;
6362 }
6363 if (p<sl) result+=s.substr(p);
6364 return QCString(result);
6365}
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 3246 of file util.cpp.

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

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

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

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

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

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

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

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

6921{
6922 if (s.isEmpty()) return s;
6923
6924 // helper to find the end of a block
6925 auto skipBlock = [&markerInfo](const char *p,const SelectionBlock &blk)
6926 {
6927 char c = 0;
6928 while ((c=*p))
6929 {
6930 if (c==markerInfo.markerChar && qstrncmp(p,markerInfo.endStr,markerInfo.endLen)==0) // end marker
6931 {
6932 size_t len = markerInfo.endLen;
6933 bool negate = *(p+markerInfo.endLen)=='!';
6934 if (negate) len++;
6935 size_t blkNameLen = qstrlen(blk.name);
6936 if (qstrncmp(p+len,blk.name,blkNameLen)==0 && // matching marker name
6937 qstrncmp(p+len+blkNameLen,markerInfo.closeStr,markerInfo.closeLen)==0) // matching marker closing
6938 {
6939 //printf("Found end marker %s enabled=%d negate=%d\n",blk.name,blk.enabled,negate);
6940 return p+len+blkNameLen+markerInfo.closeLen;
6941 }
6942 else // not the right marker id
6943 {
6944 p++;
6945 }
6946 }
6947 else // not and end marker
6948 {
6949 p++;
6950 }
6951 }
6952 return p;
6953 };
6954
6955 QCString result;
6956 result.reserve(s.length());
6957 const char *p = s.data();
6958 char c = 0;
6959 while ((c=*p))
6960 {
6961 if (c==markerInfo.markerChar) // potential start of marker
6962 {
6963 if (qstrncmp(p,markerInfo.beginStr,markerInfo.beginLen)==0) // start of begin marker
6964 {
6965 bool found = false;
6966 size_t len = markerInfo.beginLen;
6967 bool negate = *(p+len)=='!';
6968 if (negate) len++;
6969 for (const auto &blk : blockList)
6970 {
6971 size_t blkNameLen = qstrlen(blk.name);
6972 if (qstrncmp(p+len,blk.name,blkNameLen)==0 && // matching marker name
6973 qstrncmp(p+len+blkNameLen,markerInfo.closeStr,markerInfo.closeLen)==0) // matching marker closing
6974 {
6975 bool blockEnabled = blk.enabled!=negate;
6976 //printf("Found start marker %s enabled=%d negate=%d\n",blk.name,blk.enabled,negate);
6977 p+=len+blkNameLen+markerInfo.closeLen;
6978 if (!blockEnabled) // skip until the end of the block
6979 {
6980 //printf("skipping block\n");
6981 p=skipBlock(p,blk);
6982 }
6983 found=true;
6984 break;
6985 }
6986 }
6987 if (!found) // unknown marker id
6988 {
6989 result+=c;
6990 p++;
6991 }
6992 }
6993 else if (qstrncmp(p,markerInfo.endStr,markerInfo.endLen)==0) // start of end marker
6994 {
6995 bool found = false;
6996 size_t len = markerInfo.endLen;
6997 bool negate = *(p+len)=='!';
6998 if (negate) len++;
6999 for (const auto &blk : blockList)
7000 {
7001 size_t blkNameLen = qstrlen(blk.name);
7002 if (qstrncmp(p+len,blk.name,blkNameLen)==0 && // matching marker name
7003 qstrncmp(p+len+blkNameLen,markerInfo.closeStr,markerInfo.closeLen)==0) // matching marker closing
7004 {
7005 //printf("Found end marker %s enabled=%d negate=%d\n",blk.name,blk.enabled,negate);
7006 p+=len+blkNameLen+markerInfo.closeLen;
7007 found=true;
7008 break;
7009 }
7010 }
7011 if (!found) // unknown marker id
7012 {
7013 result+=c;
7014 p++;
7015 }
7016 }
7017 else // not a start or end marker
7018 {
7019 result+=c;
7020 p++;
7021 }
7022 }
7023 else // not a marker character
7024 {
7025 result+=c;
7026 p++;
7027 }
7028 }
7029 //printf("====\n%s\n-----\n%s\n~~~~\n",qPrint(s),qPrint(result));
7030 return result;
7031}
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, 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 3542 of file util.cpp.

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

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

7147{
7148 StringVector result;
7149 reg::Iterator iter(s, delimiter);
7151 size_t p=0;
7152 for ( ; iter != end; ++iter)
7153 {
7154 const auto &match = *iter;
7155 size_t i=match.position();
7156 size_t l=match.length();
7157 if (i>p) result.push_back(s.substr(p,i-p));
7158 p=i+l;
7159 }
7160 if (p<s.length()) result.push_back(s.substr(p));
7161 return result;
7162}

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

7130{
7131 StringVector result;
7132 size_t prev = 0, pos = 0, len = s.length();
7133 do
7134 {
7135 pos = s.find(delimiter, prev);
7136 if (pos == std::string::npos) pos = len;
7137 if (pos>prev) result.push_back(s.substr(prev,pos-prev));
7138 prev = pos + delimiter.length();
7139 }
7140 while (pos<len && prev<len);
7141 return result;
7142}

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

◆ stackTrace()

void stackTrace ( )

Definition at line 5983 of file util.cpp.

5984{
5985#ifdef TRACINGSUPPORT
5986 void *backtraceFrames[128];
5987 int frameCount = backtrace(backtraceFrames, 128);
5988 const size_t cmdLen = 40960;
5989 static char cmd[cmdLen];
5990 char *p = cmd;
5991 p += qsnprintf(p,cmdLen,"/usr/bin/atos -p %d ", (int)getpid());
5992 for (int x = 0; x < frameCount; x++)
5993 {
5994 p += qsnprintf(p,cmdLen,"%p ", backtraceFrames[x]);
5995 }
5996 fprintf(stderr,"========== STACKTRACE START ==============\n");
5997 if (FILE *fp = Portable::popen(cmd, "r"))
5998 {
5999 char resBuf[512];
6000 while (size_t len = fread(resBuf, 1, sizeof(resBuf), fp))
6001 {
6002 fwrite(resBuf, 1, len, stderr);
6003 }
6004 Portable::pclose(fp);
6005 }
6006 fprintf(stderr,"============ STACKTRACE END ==============\n");
6007 //fprintf(stderr,"%s\n", frameStrings[x]);
6008#endif
6009}

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

◆ stripAnonymousNamespaceScope()

QCString stripAnonymousNamespaceScope ( const QCString & s)

Definition at line 242 of file util.cpp.

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

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

5435{
5437}
QCString stripExtensionGeneral(const QCString &fName, const QCString &ext)
Definition util.cpp:5424

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

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

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

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

References Config_getList, and stripFromPath().

◆ stripIndentation()

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

Definition at line 6462 of file util.cpp.

6463{
6464 if (s.isEmpty()) return s; // empty string -> we're done
6465
6466 //printf("stripIndentation:\n%s\n------\n",qPrint(s));
6467 // compute minimum indentation over all lines
6468 const char *p=s.data();
6469 char c=0;
6470 int indent=0;
6471 int minIndent=1000000; // "infinite"
6472 bool searchIndent=true;
6473 int tabSize=Config_getInt(TAB_SIZE);
6474 bool skipFirst = skipFirstLine;
6475 while ((c=*p++))
6476 {
6477 if (c=='\t') indent+=tabSize - (indent%tabSize);
6478 else if (c=='\n') indent=0,searchIndent=true,skipFirst=false;
6479 else if (c==' ') indent++;
6480 else if (searchIndent && !skipFirst)
6481 {
6482 searchIndent=false;
6483 if (indent<minIndent) minIndent=indent;
6484 }
6485 }
6486
6487 // no indent to remove -> we're done
6488 if (minIndent==0) return substitute(s,"@ilinebr","\\ilinebr");
6489
6490 // remove minimum indentation for each line
6491 TextStream result;
6492 p=s.data();
6493 indent=0;
6494 skipFirst=skipFirstLine;
6495 while ((c=*p++))
6496 {
6497 if (c=='\n') // start of new line
6498 {
6499 indent=0;
6500 result << c;
6501 skipFirst=false;
6502 }
6503 else if (indent<minIndent && !skipFirst) // skip until we reach minIndent
6504 {
6505 if (c=='\t')
6506 {
6507 int newIndent = indent+tabSize-(indent%tabSize);
6508 int i=newIndent;
6509 while (i>minIndent) // if a tab crosses the minIndent boundary fill the rest with spaces
6510 {
6511 result << ' ';
6512 i--;
6513 }
6514 indent=newIndent;
6515 }
6516 else // space
6517 {
6518 indent++;
6519 }
6520 }
6521 else if (c=='\\' && literal_at(p,"ilinebr "))
6522 // we also need to remove the indentation after a \ilinebr command at the end of a line
6523 {
6524 result << "\\ilinebr ";
6525 p+=8;
6526 int skipAmount=0;
6527 for (int j=0;j<minIndent;j++) if (*(p+j)==' ') skipAmount++; // test to see if we have the indent
6528 if (skipAmount==minIndent)
6529 {
6530 p+=skipAmount; // remove the indent
6531 }
6532 }
6533 else if (c=='@' && literal_at(p,"ilinebr"))
6534 {
6535 result << "\\ilinebr";
6536 p+=7;
6537 }
6538 else // copy anything until the end of the line
6539 {
6540 result << c;
6541 }
6542 }
6543
6544 //printf("stripIndentation: result=\n%s\n------\n",qPrint(result.str()));
6545
6546 return result.str();
6547}

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

6551{
6552 //printf("stripIndentationVerbatim(level=%d):\n%s\n------\n",indentationLevel,qPrint(doc));
6553 if (indentationLevel <= 0 || doc.isEmpty()) return; // nothing to strip
6554
6555 // by stripping content the string will only become shorter so we write the results
6556 // back into the input string and then resize it at the end.
6557 char c = 0;
6558 const char *src = doc.data();
6559 char *dst = doc.rawData();
6560 bool insideIndent = false; // skip the initial line from stripping
6561 int cnt = 0;
6562 while ((c=*src++))
6563 {
6564 // invariant: dst<=src
6565 switch(c)
6566 {
6567 case '\n':
6568 *dst++ = c;
6569 insideIndent = true;
6570 cnt = indentationLevel;
6571 break;
6572 case ' ':
6573 if (insideIndent)
6574 {
6575 if (cnt>0) // count down the spacing until the end of the indent
6576 {
6577 cnt--;
6578 }
6579 else // reached the end of the indent, start of the part of the line to keep
6580 {
6581 insideIndent = false;
6582 *dst++ = c;
6583 }
6584 }
6585 else // part after indent, copy to the output
6586 {
6587 *dst++ = c;
6588 }
6589 break;
6590 default:
6591 insideIndent = false;
6592 *dst++ = c;
6593 break;
6594 }
6595 }
6596 doc.resize(static_cast<uint32_t>(dst-doc.data()));
6597 //printf("stripIndentationVerbatim: result=\n%s\n------\n",qPrint(doc));
6598}
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 5537 of file util.cpp.

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

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

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

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

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

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

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

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

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

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

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

◆ substituteKeywords() [2/2]

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

Definition at line 3724 of file util.cpp.

3726{
3727 return substituteKeywords(file,s,
3728 {
3729 // keyword value getter
3730 { "$title", [&]() { return !title.isEmpty() ? title : projName; } },
3731 { "$doxygenversion", [&]() { return getDoxygenVersion(); } },
3732 { "$projectname", [&]() { return projName; } },
3733 { "$projectnumber", [&]() { return projNum; } },
3734 { "$projectbrief", [&]() { return projBrief; } },
3735 { "$projectlogo", [&]() { return stripPath(projectLogoFile()); } },
3736 { "$logosize", [&]() { return projectLogoSize(); } },
3737 { "$projecticon", [&]() { return stripPath(Config_getString(PROJECT_ICON)); } },
3738 { "$langISO", [&]() { return theTranslator->trISOLang(); } },
3739 { "$showdate", [&](const QCString &fmt) { return showDate(fmt); } }
3740 });
3741}
Definition message.h:144
QCString stripPath(const QCString &s)
Definition util.cpp:5461
QCString substituteKeywords(const QCString &file, const QCString &s, const KeywordSubstitutionList &keywords)
Definition util.cpp:3572
QCString projectLogoFile()
Definition util.cpp:3658
static QCString projectLogoSize()
Definition util.cpp:3679
static QCString showDate(const QCString &fmt)
Definition util.cpp:3645

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

◆ substituteTemplateArgumentsInString()

QCString substituteTemplateArgumentsInString ( const QCString & nm,
const ArgumentList & formalArgs,
const ArgumentList * actualArgs )

Substitutes any occurrence of a formal argument from argument list formalArgs in name by the corresponding actual argument in argument list actualArgs. The result after substitution is returned as a string. The argument name is used to prevent recursive substitution.

Definition at line 4864 of file util.cpp.

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

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

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

◆ tempArgListToString()

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

Definition at line 1247 of file util.cpp.

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

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

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

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

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

◆ updateColumnCount()

size_t updateColumnCount ( const char * s,
size_t col )

Definition at line 7391 of file util.cpp.

7392{
7393 if (s)
7394 {
7395 const int tabSize = Config_getInt(TAB_SIZE);
7396 char c;
7397 while ((c=*s++))
7398 {
7399 switch(c)
7400 {
7401 case '\t': col+=tabSize - (col%tabSize);
7402 break;
7403 case '\n': col=0;
7404 break;
7405 default:
7406 col++;
7407 if (c<0) // multi-byte character
7408 {
7409 int numBytes = getUTF8CharNumBytes(c);
7410 for (int i=0;i<numBytes-1 && (c=*s++);i++) {} // skip over extra chars
7411 if (c==0) return col; // end of string half way a multibyte char
7412 }
7413 break;
7414 }
7415 }
7416 }
7417 return col;
7418}

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

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

6296{
6297 int hue = Config_getInt(HTML_COLORSTYLE_HUE);
6298 int sat = Config_getInt(HTML_COLORSTYLE_SAT);
6299 int gamma = Config_getInt(HTML_COLORSTYLE_GAMMA);
6300 while (data->name)
6301 {
6302 QCString fileName = dir+"/"+data->name;
6303 ColoredImage img(data->width,data->height,data->content,data->alpha,
6304 sat,hue,gamma);
6305 if (!img.save(fileName))
6306 {
6307 fprintf(stderr,"Warning: Cannot open file %s for writing\n",data->name);
6308 }
6309 Doxygen::indexList->addImageFile(data->name);
6310 data++;
6311 }
6312}
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:420
unsigned short height
Definition util.h:419
const unsigned char * alpha
Definition util.h:421
unsigned short width
Definition util.h:418
const char * name
Definition util.h:417

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

◆ writeExamples()

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

Definition at line 1128 of file util.cpp.

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

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

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

5962{
5963 if (al.empty()) return;
5964 ol.startConstraintList(theTranslator->trTypeConstraints());
5965 for (const Argument &a : al)
5966 {
5968 ol.parseText(a.name);
5969 ol.endConstraintParam();
5971 linkifyText(TextGeneratorOLImpl(ol),d,nullptr,nullptr,a.type);
5972 ol.endConstraintType();
5974 ol.generateDoc(d->docFile(),d->docLine(),d,nullptr,a.docs,TRUE,FALSE,
5975 QCString(),FALSE,FALSE);
5976 ol.endConstraintDocs();
5977 }
5978 ol.endConstraintList();
5979}
virtual int docLine() const =0
void endConstraintType()
Definition outputlist.h:716
void endConstraintList()
Definition outputlist.h:722
void startConstraintParam()
Definition outputlist.h:710
void startConstraintDocs()
Definition outputlist.h:718
void startConstraintType()
Definition outputlist.h:714
void endConstraintDocs()
Definition outputlist.h:720
void endConstraintParam()
Definition outputlist.h:712
void startConstraintList(const QCString &header)
Definition outputlist.h:708
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=Config_getBool(MARKDOWN_SUPPORT), bool autolinkSupport=Config_getBool(AUTOLINK_SUPPORT))
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:905

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