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

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

References updateLanguageMapping().

Referenced by generateOutput().

◆ addDirPrefix()

void addDirPrefix ( QCString & fileName)

References s.

◆ addGroupListToTitle()

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

◆ addHtmlExtensionIfMissing()

void addHtmlExtensionIfMissing ( QCString & fName)

Definition at line 5413 of file util.cpp.

5414{
5415 if (fName.isEmpty()) return;
5416 int i_fs = fName.findRev('/');
5417 int i_bs = fName.findRev('\\');
5418 int i = fName.find('.',std::max({ i_fs, i_bs ,0})); // search for . after path part
5419 if (i==-1)
5420 {
5422 }
5423}
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
size_t i
Definition htmlgen.cpp:161

References QCString::find(), QCString::findRev(), Doxygen::htmlFileExtension, i, 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 4608 of file util.cpp.

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

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

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

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(), line, 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(), i, 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 7034 of file util.cpp.

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

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

◆ checkExtension()

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

Definition at line 5408 of file util.cpp.

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

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

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

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

Referenced by isVarWithConstructor().

◆ clearSubDirs()

void clearSubDirs ( const Dir & d)

Definition at line 4181 of file util.cpp.

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

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

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

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

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

◆ convertCharEntitiesToUTF8()

QCString convertCharEntitiesToUTF8 ( const QCString & s)

Definition at line 4558 of file util.cpp.

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

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

◆ convertFileNameFortranParserCode()

FortranFormat convertFileNameFortranParserCode ( QCString fn)

Definition at line 6908 of file util.cpp.

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

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

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

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

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

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

References GrowBuf::addChar(), GrowBuf::addStr(), GrowBuf::get(), hex, isId(), and s.

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

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

References GrowBuf::addChar(), GrowBuf::addStr(), FALSE, GrowBuf::get(), hex, and s.

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

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

References GrowBuf::addChar(), GrowBuf::addStr(), convertCharEntitiesToUTF8(), GrowBuf::get(), and s.

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

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

References GrowBuf::addChar(), GrowBuf::addStr(), GrowBuf::get(), isId(), and s.

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

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

References s.

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

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

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

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

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

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

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

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

Referenced by ClassDefImpl::className().

◆ detab()

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

Definition at line 7232 of file util.cpp.

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

References Config_getInt, data, getUTF8CharNumBytes(), i, isUTF8NonBreakableSpace(), literal_at(), out, s, and size.

Referenced by Markdown::process().

◆ determineAbsoluteIncludeName()

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

Definition at line 4114 of file util.cpp.

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

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

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

6224{
6225 bool extLinksInWindow = Config_getBool(EXT_LINKS_IN_WINDOW);
6226 if (extLinksInWindow)
6227 return "target=\"_blank\" ";
6228 else if (parent)
6229 return "target=\"_parent\" ";
6230 else
6231 return "";
6232}
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 6267 of file util.cpp.

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

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

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

References end(), s, 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 4211 of file util.cpp.

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

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

Referenced by createDVIFile(), extractBoundingBox(), 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 6601 of file util.cpp.

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

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

References end(), i, 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 5495 of file util.cpp.

5496{
5497 static reg::Ex re(R"(\s*(<\a+>)\s*)");
5498 std::string s = sentence.str();
5499 reg::Iterator it(s,re);
5501 std::string result;
5502 bool found=false;
5503 size_t p=0;
5504 for ( ; it!=end ; ++it)
5505 {
5506 const auto match = *it;
5507 std::string part = match[1].str();
5508 if (part!=word)
5509 {
5510 size_t i = match.position();
5511 size_t l = match.length();
5512 result+=s.substr(p,i-p);
5513 result+=match.str();
5514 p=i+l;
5515 }
5516 else
5517 {
5518 found=true;
5519 size_t i = match[1].position();
5520 size_t l = match[1].length();
5521 result+=s.substr(p,i-p);
5522 p=i+l;
5523 }
5524 }
5525 result+=s.substr(p);
5526 sentence = QCString(result).simplifyWhiteSpace();
5527 return found;
5528}
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(), i, s, QCString::simplifyWhiteSpace(), and QCString::str().

Referenced by isVarWithConstructor().

◆ findFileDef()

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

Definition at line 3417 of file util.cpp.

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

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

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

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

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

References s.

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

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

◆ generateAnonymousAnchor()

QCString generateAnonymousAnchor ( const QCString & fileName,
int count )

Definition at line 4072 of file util.cpp.

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

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

◆ generateFileRef()

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

Definition at line 3389 of file util.cpp.

3390{
3391 //printf("generateFileRef(%s,%s)\n",name,text);
3392 QCString linkText = text.isEmpty() ? text : name;
3393 //FileInfo *fi;
3394 bool ambig = false;
3396 if (fd && fd->isLinkable())
3397 // link to documented input file
3398 ol.writeObjectLink(fd->getReference(),fd->getOutputFileBase(),QCString(),linkText);
3399 else
3400 ol.docify(linkText);
3401}
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 3834 of file util.cpp.

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

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

References Config_getEnumAsString, QCString::find(), i, 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 6209 of file util.cpp.

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

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

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

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

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

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

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

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

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

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

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

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

◆ getProjectId()

QCString getProjectId ( )

Definition at line 7323 of file util.cpp.

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

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

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

References s.

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

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

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

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

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

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

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

◆ integerToRoman()

QCString integerToRoman ( int n,
bool upper = true )

Definition at line 7210 of file util.cpp.

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

References i.

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

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

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

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

References s.

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

◆ langToString()

QCString langToString ( SrcLangExt lang)

Returns a string representation of lang.

Definition at line 6405 of file util.cpp.

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

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

References QCString::find(), and i.

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(), i, QCString::isEmpty(), Definition::isLinkable(), Definition::isLinkableInProject(), MemberDef::isVariable(), QCString::left(), GetDefResult::md, QCString::mid(), Definition::name(), out, Definition::qualifiedName(), SymbolResolver::resolveClass(), substitute(), TRUE, Definition::TypeClass, Definition::TypeNamespace, and QCString::view().

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

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

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

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

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

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

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

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

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

Referenced by findUsedClassesForClass().

◆ openOutputFile()

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

Definition at line 6808 of file util.cpp.

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

5929{
5930 std::lock_guard lock(g_docCacheMutex);
5931 auto it = g_docCache.find(doc.str());
5932 if (it != g_docCache.end())
5933 {
5934 //printf("Cache: [%s]->[%s]\n",qPrint(doc),qPrint(it->second));
5935 return it->second;
5936 }
5937 auto parser { createDocParser() };
5938 auto ast { validatingParseTitle(*parser.get(),fileName,lineNr,doc) };
5939 auto astImpl = dynamic_cast<const DocNodeAST*>(ast.get());
5940 QCString result;
5941 if (astImpl)
5942 {
5943 TextStream t;
5944 OutputCodeList codeList;
5945 codeList.add<HtmlCodeGenerator>(&t);
5946 HtmlDocVisitor visitor(t,codeList,scope,fileName);
5947 std::visit(visitor,astImpl->root);
5948 result = t.str();
5949 }
5950 else // fallback, should not happen
5951 {
5952 result = filterTitle(doc);
5953 }
5954 //printf("Conversion: [%s]->[%s]\n",qPrint(doc),qPrint(result));
5955 g_docCache.insert(std::make_pair(doc.str(),result));
5956 return result;
5957}
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:5926
QCString filterTitle(const QCString &title)
Definition util.cpp:6128
static std::mutex g_docCacheMutex
Definition util.cpp:5925

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

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

References QCString::at(), Config_getBool, convertCharEntitiesToUTF8(), createDocParser(), QCString::data(), FALSE, i, 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 6202 of file util.cpp.

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

References genericPatternMatch(), and s.

Referenced by checkAndOpenFile(), and readDir().

◆ processMarkup()

QCString processMarkup ( const QCString & s)

References s.

◆ projectLogoFile()

QCString projectLogoFile ( )

Definition at line 3659 of file util.cpp.

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

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

Referenced by copyLogo(), and substituteKeywords().

◆ protectionLevelVisible()

bool protectionLevelVisible ( Protection prot)

Definition at line 6451 of file util.cpp.

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

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

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

◆ recognizeFixedForm()

bool recognizeFixedForm ( const QCString & contents,
FortranFormat format )

Definition at line 6855 of file util.cpp.

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

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

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

◆ relativePathToRoot()

QCString relativePathToRoot ( const QCString & name)

Definition at line 4093 of file util.cpp.

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

References Config_getBool, QCString::findRev(), i, 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(), i, QCString::isEmpty(), s, 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 7098 of file util.cpp.

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

References out, and s.

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, g_charAroundSpace, i, isId(), operatorScope, qisspace(), s, 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 s.

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

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

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

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

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

◆ resolveTypeDef()

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

Definition at line 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:5139

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

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

Referenced by substituteHtmlKeywords(), and substituteLatexKeywords().

◆ showFileDefMatches()

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

Definition at line 3543 of file util.cpp.

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

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

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

References end(), i, and s.

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

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

References s.

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

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

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 getScopeFragment(), i, QCString::isEmpty(), Doxygen::namespaceLinkedMap, and s.

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

◆ stripExtension()

QCString stripExtension ( const QCString & fName)

Definition at line 5435 of file util.cpp.

5436{
5438}
QCString stripExtensionGeneral(const QCString &fName, const QCString &ext)
Definition util.cpp:5425

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

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

References Config_getInt, i, literal_at(), s, 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 6551 of file util.cpp.

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

References cnt, 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 5538 of file util.cpp.

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

References i, literal_at(), and s.

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

◆ stripPath()

QCString stripPath ( const QCString & s)

Definition at line 5462 of file util.cpp.

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

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

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

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

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

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

References QCString::at(), QCString::find(), getClass(), i, 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)

References s.

◆ substituteKeywords() [1/2]

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

Definition at line 3573 of file util.cpp.

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

References QCString::left(), line, qstrlen(), qstrncmp(), s, 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 3725 of file util.cpp.

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

References Config_getString, QCString::isEmpty(), projectLogoFile(), projectLogoSize(), s, 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 4865 of file util.cpp.

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

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

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

References getCaseSenseNames(), and s.

◆ updateColumnCount()

size_t updateColumnCount ( const char * s,
size_t col )

Definition at line 7392 of file util.cpp.

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

References Config_getInt, getUTF8CharNumBytes(), i, and s.

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

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

6297{
6298 int hue = Config_getInt(HTML_COLORSTYLE_HUE);
6299 int sat = Config_getInt(HTML_COLORSTYLE_SAT);
6300 int gamma = Config_getInt(HTML_COLORSTYLE_GAMMA);
6301 while (data->name)
6302 {
6303 QCString fileName = dir+"/"+data->name;
6304 ColoredImage img(data->width,data->height,data->content,data->alpha,
6305 sat,hue,gamma);
6306 if (!img.save(fileName))
6307 {
6308 fprintf(stderr,"Warning: Cannot open file %s for writing\n",data->name);
6309 }
6310 Doxygen::indexList->addImageFile(data->name);
6311 data++;
6312 }
6313}
Class representing a bitmap image colored based on hue/sat/gamma settings.
Definition image.h:56
static IndexList * indexList
Definition doxygen.h:134

References Config_getInt, data, Doxygen::indexList, and ColoredImage::save().

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

5963{
5964 if (al.empty()) return;
5965 ol.startConstraintList(theTranslator->trTypeConstraints());
5966 for (const Argument &a : al)
5967 {
5969 ol.parseText(a.name);
5970 ol.endConstraintParam();
5972 linkifyText(TextGeneratorOLImpl(ol),d,nullptr,nullptr,a.type);
5973 ol.endConstraintType();
5975 ol.generateDoc(d->docFile(),d->docLine(),d,nullptr,a.docs,TRUE,FALSE,
5976 QCString(),FALSE,FALSE);
5977 ol.endConstraintDocs();
5978 }
5979 ol.endConstraintList();
5980}
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().