Skip to main content

The util.cpp File Reference

Included Headers

#include <stdlib.h> #include <errno.h> #include <math.h> #include <limits.h> #include <string.h> #include <assert.h> #include <mutex> #include <unordered_set> #include <codecvt> #include <algorithm> #include <ctime> #include <cctype> #include <cinttypes> #include <sstream> #include "md5.h" #include "regex.h" #include "util.h" #include "message.h" #include "classdef.h" #include "filedef.h" #include "doxygen.h" #include "outputlist.h" #include "defargs.h" #include "language.h" #include "config.h" #include "htmlhelp.h" #include "example.h" #include "version.h" #include "groupdef.h" #include "reflist.h" #include "pagedef.h" #include "debug.h" #include "searchindex.h" #include "textdocvisitor.h" #include "latexdocvisitor.h" #include "htmldocvisitor.h" #include "portable.h" #include "parserintf.h" #include "image.h" #include "growbuf.h" #include "entry.h" #include "arguments.h" #include "memberlist.h" #include "classlist.h" #include "namespacedef.h" #include "membername.h" #include "filename.h" #include "membergroup.h" #include "dirdef.h" #include "htmlentity.h" #include "symbolresolver.h" #include "fileinfo.h" #include "dir.h" #include "utf8.h" #include "textstream.h" #include "indexlist.h" #include "datetime.h" #include "moduledef.h" #include "trace.h" #include "stringutil.h"

Classes Index

structCharAroundSpace
structCharElem
structFindFileCacheElem

Cache element for the file name to FileDef mapping cache. More...

structLang2ExtMap

Functions Index

QCStringremoveAnonymousScopes (const QCString &str)
QCStringreplaceAnonymousScopes (const QCString &s, const QCString &replacement)
QCStringstripAnonymousNamespaceScope (const QCString &s)
voidwritePageRef (OutputList &ol, const QCString &cn, const QCString &mn)
QCStringgenerateMarker (int id)
QCStringremoveLongPathMarker (QCString path)
static QCStringstripFromPath (const QCString &p, const StringVector &l)
QCStringstripFromPath (const QCString &path)
QCStringstripFromIncludePath (const QCString &path)
EntryTypeguessSection (const QCString &name)
QCStringresolveTypeDef (const Definition *context, const QCString &qualifiedName, const Definition **typedefContext)
QCStringremoveRedundantWhiteSpace (const QCString &s)
intfindParameterList (const QCString &name)

Returns the position in the string where a function parameter list begins, or -1 if one is not found. More...

boolrightScopeMatch (const QCString &scope, const QCString &name)
boolleftScopeMatch (const QCString &scope, const QCString &name)
voidlinkifyText (const TextGeneratorIntf &out, const Definition *scope, const FileDef *fileScope, const Definition *self, const QCString &text, bool autoBreak, bool external, bool keepSpaces, int indentLevel)
voidwriteMarkerList (OutputList &ol, const std::string &markerText, size_t numMarkers, std::function< void(size_t)> replaceFunc)
voidwriteExamples (OutputList &ol, const ExampleList &list)
QCStringinlineArgListToDoc (const ArgumentList &al)
QCStringinlineTemplateArgListToDoc (const ArgumentList &al)
QCStringargListToString (const ArgumentList &al, bool useCanonicalType, bool showDefVals)
QCStringtempArgListToString (const ArgumentList &al, SrcLangExt lang, bool includeDefault)
static voidfilterCRLF (std::string &contents)
static QCStringgetFilterFromList (const QCString &name, const StringVector &filterList, bool &found)
QCStringgetFileFilter (const QCString &name, bool isSourceCode)
booltranscodeCharacterStringToUTF8 (std::string &input, const char *inputEncoding)
QCStringfileToString (const QCString &name, bool filter, bool isSourceCode)
voidtrimBaseClassScope (const BaseClassList &bcl, QCString &s, int level=0)
static voidstripIrrelevantString (QCString &target, const QCString &str)
voidstripIrrelevantConstVolatile (QCString &s)
static QCStringstripDeclKeywords (const QCString &s)
static QCStringextractCanonicalType (const Definition *d, const FileDef *fs, QCString type, SrcLangExt lang)
static QCStringgetCanonicalTemplateSpec (const Definition *d, const FileDef *fs, const QCString &spec, SrcLangExt lang)
static QCStringgetCanonicalTypeForIdentifier (const Definition *d, const FileDef *fs, const QCString &word, SrcLangExt lang, QCString *tSpec, int count=0)
static QCStringextractCanonicalArgType (const Definition *d, const FileDef *fs, const Argument &arg, SrcLangExt lang)
static boolmatchCanonicalTypes (const Definition *srcScope, const FileDef *srcFileScope, const QCString &srcType, const Definition *dstScope, const FileDef *dstFileScope, const QCString &dstType, SrcLangExt lang)
static boolmatchArgument2 (const Definition *srcScope, const FileDef *srcFileScope, Argument &srcA, const Definition *dstScope, const FileDef *dstFileScope, Argument &dstA, SrcLangExt lang)
boolmatchArguments2 (const Definition *srcScope, const FileDef *srcFileScope, const ArgumentList *srcAl, const Definition *dstScope, const FileDef *dstFileScope, const ArgumentList *dstAl, bool checkCV, SrcLangExt lang)
voidmergeArguments (ArgumentList &srcAl, ArgumentList &dstAl, bool forceNameOverwrite)
boolmatchTemplateArguments (const ArgumentList &srcAl, const ArgumentList &dstAl)
static voidfindMembersWithSpecificName (const MemberName *mn, const QCString &args, bool checkStatics, const FileDef *currentFile, bool checkCV, std::vector< const MemberDef * > &members)
GetDefResultgetDefsNew (const GetDefInput &input)
GetDefResultgetDefsOld (const GetDefInput &input)
GetDefResultgetDefs (const GetDefInput &input)
static boolgetScopeDefs (const QCString &docScope, const QCString &scope, ClassDef *&cd, ConceptDef *&cnd, NamespaceDef *&nd, ModuleDef *&modd)
static boolisLowerCase (QCString &s)
boolresolveRef (const QCString &scName, const QCString &name, bool inSeeBlock, const Definition **resContext, const MemberDef **resMember, SrcLangExt lang, bool lookForSpecialization, const FileDef *currentFile, bool checkScope)
QCStringlinkToText (SrcLangExt lang, const QCString &link, bool isFileName)
boolresolveLink (const QCString &scName, const QCString &lr, bool, const Definition **resContext, QCString &resAnchor, SrcLangExt lang, const QCString &prefix)
voidgenerateFileRef (OutputList &ol, const QCString &name, const QCString &text)
FileDef *findFileDef (const FileNameLinkedMap *fnMap, const QCString &n, bool &ambig)
QCStringfindFilePath (const QCString &file, bool &ambig)
QCStringshowFileDefMatches (const FileNameLinkedMap *fnMap, const QCString &n)
QCStringsubstituteKeywords (const QCString &file, const QCString &s, const KeywordSubstitutionList &keywords)
static QCStringshowDate (const QCString &fmt)
QCStringprojectLogoFile ()
static QCStringprojectLogoSize ()
QCStringsubstituteKeywords (const QCString &file, const QCString &s, const QCString &title, const QCString &projName, const QCString &projNum, const QCString &projBrief)
intgetPrefixIndex (const QCString &name)
boolgetCaseSenseNames ()
QCStringescapeCharsInString (const QCString &name, bool allowDots, bool allowUnderscore)
QCStringunescapeCharsInString (const QCString &s)
QCStringconvertNameToFile (const QCString &name, bool allowDots, bool allowUnderscore)
QCStringgenerateAnonymousAnchor (const QCString &fileName, int count)
QCStringrelativePathToRoot (const QCString &name)
QCStringdetermineAbsoluteIncludeName (const QCString &curFile, const QCString &incFileName)
voidcreateSubDirs (const Dir &d)
voidclearSubDirs (const Dir &d)
voidextractNamespaceName (const QCString &scopeName, QCString &className, QCString &namespaceName, bool allowEmptyClass)
QCStringinsertTemplateSpecifierInScope (const QCString &scope, const QCString &templ)
QCStringstripScope (const QCString &name)
QCStringconvertToId (const QCString &s)
QCStringcorrectId (const QCString &s)
QCStringconvertToXML (const QCString &s, bool keepEntities)
QCStringconvertToHtml (const QCString &s, bool keepEntities)
QCStringconvertToJSString (const QCString &s, bool keepEntities)
QCStringconvertCharEntitiesToUTF8 (const QCString &str)
QCStringgetOverloadDocs ()
voidaddMembersToMemberGroup (MemberList *ml, MemberGroupList *pMemberGroups, const Definition *context)
intextractClassNameFromType (const QCString &type, int &pos, QCString &name, QCString &templSpec, SrcLangExt lang)
QCStringnormalizeNonTemplateArgumentsInString (const QCString &name, const Definition *context, const ArgumentList &formalArgs)
QCStringsubstituteTemplateArgumentsInString (const QCString &nm, const ArgumentList &formalArgs, const ArgumentList *actualArgs)
QCStringstripTemplateSpecifiersFromScope (const QCString &fullName, bool parentOnly, QCString *pLastScopeStripped, QCString scopeName, bool allowArtificial)
QCStringmergeScopes (const QCString &leftScope, const QCString &rightScope)
intgetScopeFragment (const QCString &s, int p, int *l)
PageDef *addRelatedPage (const QCString &name, const QCString &ptitle, const QCString &doc, const QCString &fileName, int docLine, int startLine, const RefItemVector &sli, GroupDef *gd, const TagInfo *tagInfo, bool xref, SrcLangExt lang)
voidaddRefItem (const RefItemVector &sli, const QCString &key, const QCString &prefix, const QCString &name, const QCString &title, const QCString &args, const Definition *scope)
static ModuleDef *findModuleDef (const Definition *d)
static boolrecursivelyAddGroupListToTitle (OutputList &ol, const Definition *d, bool root)
voidaddGroupListToTitle (OutputList &ol, const Definition *d)
boolcheckExtension (const QCString &fName, const QCString &ext)
voidaddHtmlExtensionIfMissing (QCString &fName)
QCStringstripExtensionGeneral (const QCString &fName, const QCString &ext)
QCStringstripExtension (const QCString &fName)
QCStringstripPath (const QCString &s)
boolcontainsWord (const QCString &str, const char *word)

returns TRUE iff string s contains word w More...

boolfindAndRemoveWord (QCString &sentence, const char *word)

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

QCStringstripLeadingAndTrailingEmptyLines (const QCString &s, int &docLine)

Special version of QCString::stripWhiteSpace() that only strips completely blank lines. More...

boolupdateLanguageMapping (const QCString &extension, const QCString &language)
voidinitDefaultExtensionMapping ()
voidaddCodeOnlyMappings ()
SrcLangExtgetLanguageFromFileName (const QCString &fileName, SrcLangExt defLang)
SrcLangExtgetLanguageFromCodeLang (QCString &fileName)

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

QCStringgetFileNameExtension (const QCString &fn)
static MemberDef *getMemberFromSymbol (const Definition *scope, const FileDef *fileScope, const QCString &n)
boolcheckIfTypedef (const Definition *scope, const FileDef *fileScope, const QCString &n)
static intnextUTF8CharPosition (const QCString &utf8Str, uint32_t len, uint32_t startPos)
QCStringparseCommentAsText (const Definition *scope, const MemberDef *md, const QCString &doc, const QCString &fileName, int lineNr)
QCStringparseCommentAsHtml (const Definition *scope, const MemberDef *member, const QCString &doc, const QCString &fileName, int lineNr)
voidwriteTypeConstraints (OutputList &ol, const Definition *d, const ArgumentList &al)
voidstackTrace ()
static voidtranscodeCharacterBuffer (const QCString &fileName, std::string &contents, const QCString &inputEncoding, const QCString &outputEncoding)
boolreadInputFile (const QCString &fileName, std::string &contents, bool filter, bool isSourceCode)

read a file name fileName and optionally filter and transcode it More...

QCStringfilterTitle (const QCString &title)
template < ... >
boolgenericPatternMatch (const FileInfo &fi, const PatternList &patList, PatternElem &elem, PatternGet getter)
boolpatternMatch (const FileInfo &fi, const StringVector &patList)
QCStringgetEncoding (const FileInfo &fi)
QCStringexternalLinkTarget (const bool parent)
QCStringcreateHtmlUrl (const QCString &relPath, const QCString &ref, bool href, bool isLocalFile, const QCString &targetFileName, const QCString &anchor)
QCStringexternalRef (const QCString &relPath, const QCString &ref, bool href)
voidwriteColoredImgData (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_*. More...

QCStringreplaceColorMarkers (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. More...

boolcopyFile (const QCString &src, const QCString &dest)

Copies the contents of file with name src to the newly created file with name dest. More...

intlineBlock (const QCString &text, const QCString &marker)

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

QCStringlangToString (SrcLangExt lang)

Returns a string representation of lang. More...

QCStringgetLanguageSpecificSeparator (SrcLangExt lang, bool classScope)

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

boolisURL (const QCString &url)

Checks whether the given url starts with a supported protocol. More...

QCStringcorrectURL (const QCString &url, const QCString &relPath)

Corrects URL url according to the relative path relPath. More...

boolprotectionLevelVisible (Protection prot)
QCStringstripIndentation (const QCString &s, bool skipFirstLine)
voidstripIndentationVerbatim (QCString &doc, const int indentationLevel)
boolfileVisibleInIndex (const FileDef *fd, bool &genSourceFile)
QCStringextractDirection (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. More...

voidconvertProtectionLevel (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. More...

boolmainPageHasTitle ()
QCStringgetDotImageExtension ()
boolopenOutputFile (const QCString &outFile, std::ofstream &f)
static boolkeyWordsFortranC (const char *contents)
boolrecognizeFixedForm (const QCString &contents, FortranFormat format)
FortranFormatconvertFileNameFortranParserCode (QCString fn)
QCStringselectBlocks (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 More...

voidcheckBlocks (const QCString &s, const QCString fileName, const SelectionMarkerInfo &markerInfo)
QCStringremoveEmptyLines (const QCString &s)
StringVectorsplit (const std::string &s, const std::string &delimiter)

split input string s by string delimiter delimiter. More...

StringVectorsplit (const std::string &s, const reg::Ex &delimiter)

split input string s by regular expression delimiter delimiter. More...

intfindIndex (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 More...

intfindIndex (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 More...

std::stringjoin (const StringVector &sv, const std::string &delimiter)

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

QCStringintegerToAlpha (int n, bool upper)
QCStringintegerToRoman (int n, bool upper)
QCStringdetab (const QCString &s, size_t &refIndent)
QCStringgetProjectId ()
intcomputeQualifiedIndex (const QCString &name)

Return the index of the last :: in the string name that is still before the first <. More...

voidmergeMemberOverrideOptions (MemberDefMutable *md1, MemberDefMutable *md2)
size_tupdateColumnCount (const char *s, size_t col)
QCStringmangleCSharpGenericName (const QCString &name)
QCStringdemangleCSharpGenericName (const QCString &name, const QCString &templArgs)

Variables Index

static const char *hex = "0123456789ABCDEF"
const intmaxInheritanceDepth = 100000
static const charconstScope[] = { 'c', 'o', 'n', 's', 't', ':' }
static const charvolatileScope[] = { 'v', 'o', 'l', 'a', 't', 'i', 'l', 'e', ':' }
static const charvirtualScope[] = { 'v', 'i', 'r', 't', 'u', 'a', 'l', ':' }
static const charoperatorScope[] = { 'o', 'p', 'e', 'r', 'a', 't', 'o', 'r', '?', '?', '?' }
static CharAroundSpaceg_charAroundSpace
static std::mutexg_matchArgsMutex
static Cache< std::string, FindFileCacheElem >g_findFileDefCache(5000)
static std::mutexg_findFileDefMutex
static std::unordered_map< std::string, int >g_usedNames
static std::mutexg_usedNamesMutex
static intg_usedNamesCount =1
static std::unordered_map< std::string, SrcLangExt >g_extLookup
static std::vector< Lang2ExtMap >g_lang2extMap = ...
static std::mutexg_docCacheMutex
static std::unordered_map< std::string, QCString >g_docCache

Macro Definitions Index

#defineENABLE_TRACINGSUPPORT   0
#defineREL_PATH_TO_ROOT   "../../"
#defineMATCH
#defineNOMATCH
#defineHEXTONUM(x)   ...

Functions

addCodeOnlyMappings()

void addCodeOnlyMappings ()

Definition at line 5716 of file util.cpp.

5717{
5718 updateLanguageMapping(".xml", "xml");
5719 updateLanguageMapping(".sql", "sql");
5720}

Reference updateLanguageMapping.

Referenced by generateOutput.

addGroupListToTitle()

addHtmlExtensionIfMissing()

void addHtmlExtensionIfMissing (QCString & fName)

Definition at line 5416 of file util.cpp.

5417{
5418 if (fName.isEmpty()) return;
5419 int i_fs = fName.findRev('/');
5420 int i_bs = fName.findRev('\\');
5421 int i = fName.find('.',std::max({ i_fs, i_bs ,0})); // search for . after path part
5422 if (i==-1)
5423 {
5425 }
5426}

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

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

addMembersToMemberGroup()

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

Definition at line 4611 of file util.cpp.

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

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

5319void addRefItem(const RefItemVector &sli,
5320 const QCString &key, const QCString &prefix, const QCString &name,
5321 const QCString &title, const QCString &args, const Definition *scope)
5322{
5323 //printf("addRefItem(sli=%d,key=%s,prefix=%s,name=%s,title=%s,args=%s)\n",(int)sli.size(),key,prefix,name,title,args);
5324 if (!key.isEmpty() && key[0]!='@') // check for @ to skip anonymous stuff (see bug427012)
5325 {
5326 for (RefItem *item : sli)
5327 {
5328 item->setPrefix(prefix);
5329 item->setScope(scope);
5330 item->setName(name);
5331 item->setTitle(title);
5332 item->setArgs(args);
5333 item->setGroup(key);
5334 }
5335 }
5336}

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, GroupDef * gd, const TagInfo * tagInfo, bool xref, SrcLangExt lang)

Definition at line 5189 of file util.cpp.

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

References SectionManager::add, GroupDef::addPage, convertNameToFile, createPageDef, Definition::docFile, QCString::endsWith, FALSE, SectionInfo::fileName, TagInfo::fileName, LinkedMap< T, Hash, KeyEqual, Map >::find, Definition::getOutputFileBase, Definition::getReference, Definition::getStartBodyLine, PageDef::hasTitle, Doxygen::htmlFileExtension, SectionManager::instance, QCString::isEmpty, Definition::isReference, QCString::left, QCString::length, SectionInfo::lineNr, Definition::name, SectionType::Page, Doxygen::pageLinkedMap, SectionInfo::ref, SectionManager::replace, QCString::right, DefinitionMutable::setBodySegment, DefinitionMutable::setDocumentation, PageDef::setFileName, DefinitionMutable::setLanguage, PageDef::setNestingLevel, PageDef::setPageScope, DefinitionMutable::setReference, DefinitionMutable::setRefItems, PageDef::setShowLineNo, PageDef::setTitle, SectionInfo::setTitle, QCString::stripWhiteSpace, TagInfo::tagName, PageDef::title, TRUE and warn.

argListToString()

QCString argListToString (const ArgumentList & al, bool useCanonicalType, bool showDefVals)

Definition at line 1202 of file util.cpp.

1202QCString argListToString(const ArgumentList &al,bool useCanonicalType,bool showDefVals)
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}

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

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

checkBlocks()

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

Definition at line 7037 of file util.cpp.

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

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

Referenced by HtmlGenerator::init and LatexGenerator::init.

checkExtension()

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

Definition at line 5411 of file util.cpp.

5411bool checkExtension(const QCString &fName, const QCString &ext)
5412{
5413 return fName.right(ext.length())==ext;
5414}

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

5826bool checkIfTypedef(const Definition *scope,const FileDef *fileScope,const QCString &n)
5827{
5828 MemberDef *bestMatch = getMemberFromSymbol(scope,fileScope,n);
5829
5830 if (bestMatch && bestMatch->isTypedef())
5831 return TRUE; // closest matching symbol is a typedef
5832 else
5833 return FALSE;
5834}

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

Referenced by isVarWithConstructor.

clearSubDirs()

void clearSubDirs (const Dir & d)

Definition at line 4184 of file util.cpp.

4184void clearSubDirs(const Dir &d)
4185{
4186 if (Config_getBool(CREATE_SUBDIRS))
4187 {
4188 // remove empty subdirectories
4189 int createSubdirsLevelPow2 = 1 << Config_getInt(CREATE_SUBDIRS_LEVEL);
4190 for (int l1=0;l1<16;l1++)
4191 {
4192 QCString subdir;
4193 subdir.sprintf("d%x",l1);
4194 for (int l2=0; l2 < createSubdirsLevelPow2; l2++)
4195 {
4196 QCString subsubdir;
4197 subsubdir.sprintf("d%x/d%02x",l1,l2);
4198 if (d.exists(subsubdir.str()) && d.isEmpty(subsubdir.str()))
4199 {
4200 d.rmdir(subsubdir.str());
4201 }
4202 }
4203 if (d.exists(subdir.str()) && d.isEmpty(subdir.str()))
4204 {
4205 d.rmdir(subdir.str());
4206 }
4207 }
4208 }
4209}

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

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

References QCString::data and QCString::length.

Referenced by addToMap, addVariable, buildFunctionList, buildTypedefList, getMemberFromSymbol, SymbolResolver::Private::getResolvedSymbolRec and SymbolResolver::Private::getResolvedTypeRec.

containsWord()

bool containsWord (const QCString & str, const char * word)

returns TRUE iff string s contains word w

Definition at line 5482 of file util.cpp.

5482bool containsWord(const QCString &str,const char *word)
5483{
5484 if (str.isEmpty() || word==nullptr) return false;
5485 static const reg::Ex re(R"(\a+)");
5486 std::string s = str.str();
5487 for (reg::Iterator it(s,re) ; it!=reg::Iterator() ; ++it)
5488 {
5489 if (it->str()==word) return true;
5490 }
5491 return false;
5492}

References QCString::isEmpty and QCString::str.

convertCharEntitiesToUTF8()

QCString convertCharEntitiesToUTF8 (const QCString & str)

Definition at line 4561 of file util.cpp.

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

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

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

convertFileNameFortranParserCode()

FortranFormat convertFileNameFortranParserCode (QCString fn)

Definition at line 6911 of file util.cpp.

6912{
6914 QCString parserName = Doxygen::parserManager->getParserName(ext);
6915
6916 if (parserName == "fortranfixed") return FortranFormat::Fixed;
6917 else if (parserName == "fortranfree") return FortranFormat::Free;
6918
6920}

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

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

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

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

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

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

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

Referenced by HtmlCodeGenerator::_writeCodeLink, HtmlHelp::addContentsItem, convertToHtmlAndTruncate, FTVHelp::Private::generateLink, DefinitionImpl::navigationPathAsString, HtmlDocVisitor::operator(), HtmlDocVisitor::operator(), HtmlDocVisitor::operator(), HtmlGenerator::startFile, HtmlDocVisitor::startLink, substituteHtmlKeywords, HtmlHelpIndex::writeFields, HtmlGenerator::writeInheritedSectionTitle, HtmlGenerator::writeLogoAsString, writeMapArea, HtmlGenerator::writePageFooter, ClassDefImpl::writeQuickMemberLinks, FileDefImpl::writeQuickMemberLinks, GroupDefImpl::writeQuickMemberLinks, NamespaceDefImpl::writeQuickMemberLinks and HtmlGenerator::writeSearchPage.

convertToId()

QCString convertToId (const QCString & s)

Converts a string to a HTML id string

Definition at line 4389 of file util.cpp.

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

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

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

convertToJSString()

QCString convertToJSString (const QCString & s, bool keepEntities)

Definition at line 4540 of file util.cpp.

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

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

Referenced by generateJSLink, generateJSNavTree, renderMemberIndicesAsJs and renderQuickLinksAsJs.

convertToXML()

QCString convertToXML (const QCString & s, bool keepEntities)

Converts a string to an XML-encoded string

Definition at line 4429 of file util.cpp.

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

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

Referenced by DocSets::addContentsItem, EclipseHelp::addContentsItem, Qhp::addFile, Sitemap::addIndexFile, Qhp::addIndexItem, XmlDocVisitor::filter, generateXMLForClass, generateXMLForConcept, generateXMLForDir, generateXMLForFile, generateXMLForGroup, generateXMLForMember, generateXMLForModule, generateXMLForNamespace, generateXMLForPage, generateXMLSection, DotDirDeps::getImgAltText, EclipseHelp::initialize, Qhp::initialize, XmlDocVisitor::operator(), XmlDocVisitor::operator(), HtmlAttribList::toString, QhpSectionTree::traverse, visitPreStart, SearchIndexExternal::write, FileDefImpl::writeClassesToTagFile, NamespaceDefImpl::writeClassesToTagFile, NamespaceDefImpl::writeConceptsToTagFile, DefinitionImpl::writeDocAnchorsToTagFile, DotNode::writeDocbook, DotGraph::writeGraphHeader, writeInnerClasses, writeInnerConcepts, writeInnerDirs, writeInnerFiles, writeInnerGroups, writeInnerModules, writeInnerNamespaces, writeInnerPages, writeJavascriptSearchData, writeJavasScriptSearchDataPage, DotNode::writeLabel, writeListOfAllMembers, writeMapArea, writeMemberReference, ClassDefImpl::writeTagFile, ConceptDefImpl::writeTagFile, DirDefImpl::writeTagFile, FileDefImpl::writeTagFile, GroupDefImpl::writeTagFile, MemberDefImpl::writeTagFile, ModuleDefImpl::writeTagFile, NamespaceDefImpl::writeTagFile, PageDefImpl::writeTagFile, VhdlDocGen::writeTagFile, writeTemplateArgumentList, DocSets::writeToken, DotNode::writeXML, writeXMLLink and writeXMLString.

copyFile()

correctId()

QCString correctId (const QCString & s)

Some strings have been corrected but the requirement regarding the fact that an id cannot have a digit at the first position. To overcome problems with double labels we always place an "a" in front

Definition at line 4422 of file util.cpp.

4423{
4424 if (s.isEmpty()) return s;
4425 return "a" + s;
4426}

Reference QCString::isEmpty.

Referenced by DotGraph::generateCode and DotFilePatcher::run.

correctURL()

QCString correctURL (const QCString & url, const QCString & relPath)

Corrects URL url according to the relative path relPath.

Returns the corrected URL. For absolute URLs no correction will be done.

Definition at line 6442 of file util.cpp.

6442QCString correctURL(const QCString &url,const QCString &relPath)
6443{
6444 QCString result = url;
6445 if (!relPath.isEmpty() && !isURL(url))
6446 {
6447 result.prepend(relPath);
6448 }
6449 return result;
6450}

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

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

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

4157void createSubDirs(const Dir &d)
4158{
4159 if (Config_getBool(CREATE_SUBDIRS))
4160 {
4161 // create up to 4096 subdirectories
4162 int createSubdirsLevelPow2 = 1 << Config_getInt(CREATE_SUBDIRS_LEVEL);
4163 for (int l1=0; l1<16; l1++)
4164 {
4165 QCString subdir;
4166 subdir.sprintf("d%x",l1);
4167 if (!d.exists(subdir.str()) && !d.mkdir(subdir.str()))
4168 {
4169 term("Failed to create output directory '{}'\n",subdir);
4170 }
4171 for (int l2=0; l2<createSubdirsLevelPow2; l2++)
4172 {
4173 QCString subsubdir;
4174 subsubdir.sprintf("d%x/d%02x",l1,l2);
4175 if (!d.exists(subsubdir.str()) && !d.mkdir(subsubdir.str()))
4176 {
4177 term("Failed to create output directory '{}'\n",subsubdir);
4178 }
4179 }
4180 }
4181 }
4182}

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

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

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

Referenced by ClassDefImpl::className.

detab()

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

Definition at line 7235 of file util.cpp.

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

References GrowBuf::addChar, GrowBuf::addStr, Config_getInt, QCString::data, GrowBuf::get, getUTF8CharNumBytes, isUTF8NonBreakableSpace, QCString::length and literal_at.

Referenced by Markdown::process.

determineAbsoluteIncludeName()

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

Definition at line 4117 of file util.cpp.

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

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)

Definition at line 3847 of file util.cpp.

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

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)

Definition at line 6226 of file util.cpp.

6227{
6228 bool extLinksInWindow = Config_getBool(EXT_LINKS_IN_WINDOW);
6229 if (extLinksInWindow)
6230 return "target=\"_blank\" ";
6231 else if (parent)
6232 return "target=\"_parent\" ";
6233 else
6234 return "";
6235}

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

6270QCString externalRef(const QCString &relPath,const QCString &ref,bool href)
6271{
6272 QCString result;
6273 if (!ref.isEmpty())
6274 {
6275 auto it = Doxygen::tagDestinationMap.find(ref.str());
6277 {
6278 result = it->second;
6279 size_t l = result.length();
6280 if (!relPath.isEmpty() && l>0 && result.at(0)=='.')
6281 { // relative path -> prepend relPath.
6282 result.prepend(relPath);
6283 l+=relPath.length();
6284 }
6285 if (l>0 && result.at(l-1)!='/') result+='/';
6286 if (!href) result.append("\" ");
6287 }
6288 }
6289 else
6290 {
6291 result = relPath;
6292 }
6293 return result;
6294}

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.

extractCanonicalArgType()

QCString extractCanonicalArgType (const Definition * d, const FileDef * fs, const Argument & arg, SrcLangExt lang)
static

Definition at line 1828 of file util.cpp.

1828static QCString extractCanonicalArgType(const Definition *d,const FileDef *fs,const Argument &arg,SrcLangExt lang)
1829{
1830 QCString type = arg.type.stripWhiteSpace();
1831 QCString name = arg.name;
1832 //printf("----- extractCanonicalArgType(type=%s,name=%s)\n",qPrint(type),qPrint(name));
1833 if ((type=="const" || type=="volatile") && !name.isEmpty())
1834 { // name is part of type => correct
1835 type+=" ";
1836 type+=name;
1837 }
1838 if (name=="const" || name=="volatile")
1839 { // name is part of type => correct
1840 if (!type.isEmpty()) type+=" ";
1841 type+=name;
1842 }
1843 if (!arg.array.isEmpty())
1844 {
1845 type+=arg.array;
1846 }
1847
1848 return extractCanonicalType(d,fs,type,lang);
1849}

References Argument::array, extractCanonicalType, QCString::isEmpty, Argument::name, QCString::stripWhiteSpace and Argument::type.

Referenced by matchArgument2.

extractCanonicalType()

QCString extractCanonicalType (const Definition * d, const FileDef * fs, QCString type, SrcLangExt lang)
static

Definition at line 1752 of file util.cpp.

1753{
1754 AUTO_TRACE("d={} fs={} type='{}'",d?d->name():"",fs?fs->name():"",type);
1755 type = type.stripWhiteSpace();
1756
1757 // strip const and volatile keywords that are not relevant for the type
1759
1760 // strip leading keywords
1761 type.stripPrefix("class ");
1762 type.stripPrefix("struct ");
1763 type.stripPrefix("union ");
1764 type.stripPrefix("enum ");
1765 type.stripPrefix("typename ");
1766
1767 type = removeRedundantWhiteSpace(type);
1768 //printf("extractCanonicalType(type=%s) start: def=%s file=%s\n",qPrint(type),
1769 // d ? qPrint(d->name()) : "<null>", fs ? qPrint(fs->name()) : "<null>");
1770
1771 QCString canType;
1772 QCString templSpec,word;
1773 int i=0,p=0,pp=0;
1774 while ((i=extractClassNameFromType(type,p,word,templSpec))!=-1)
1775 // foreach identifier in the type
1776 {
1777 //printf(" i=%d p=%d\n",i,p);
1778 if (i>pp) canType += type.mid(pp,i-pp);
1779
1780 QCString ct = getCanonicalTypeForIdentifier(d,fs,word,lang,&templSpec);
1781
1782 // in case the ct is empty it means that "word" represents scope "d"
1783 // and this does not need to be added to the canonical
1784 // type (it is redundant), so/ we skip it. This solves problem 589616
1785 if (ct.isEmpty() && type.mid(p,2)=="::")
1786 {
1787 p+=2;
1788 }
1789 else
1790 {
1791 canType += ct;
1792 }
1793 //printf(" word=%s templSpec=%s canType=%s ct=%s\n",
1794 // qPrint(word), qPrint(templSpec), qPrint(canType), qPrint(ct));
1795 if (!templSpec.isEmpty()) // if we didn't use up the templSpec already
1796 // (i.e. type is not a template specialization)
1797 // then resolve any identifiers inside.
1798 {
1799 std::string ts = templSpec.str();
1800 static const reg::Ex re(R"(\a\w*)");
1801 reg::Iterator it(ts,re);
1803
1804 size_t tp=0;
1805 // for each identifier template specifier
1806 //printf("adding resolved %s to %s\n",qPrint(templSpec),qPrint(canType));
1807 for (; it!=end ; ++it)
1808 {
1809 const auto &match = *it;
1810 size_t ti = match.position();
1811 size_t tl = match.length();
1812 std::string matchStr = match.str();
1813 canType += ts.substr(tp,ti-tp);
1814 canType += getCanonicalTypeForIdentifier(d,fs,matchStr.c_str(),lang,nullptr);
1815 tp=ti+tl;
1816 }
1817 canType+=ts.substr(tp);
1818 }
1819
1820 pp=p;
1821 }
1822 canType += type.right(type.length()-pp);
1823 AUTO_TRACE_EXIT("canType='{}'",canType);
1824
1825 return removeRedundantWhiteSpace(canType);
1826}

References AUTO_TRACE, AUTO_TRACE_EXIT, end, extractClassNameFromType, getCanonicalTypeForIdentifier, QCString::isEmpty, QCString::length, QCString::mid, Definition::name, removeRedundantWhiteSpace, QCString::right, QCString::str, stripIrrelevantConstVolatile, QCString::stripPrefix and QCString::stripWhiteSpace.

Referenced by extractCanonicalArgType and getCanonicalTemplateSpec.

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

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

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

Referenced by extractCanonicalType, findUsedClassesForClass, stripClassName and stripClassName.

extractDirection()

QCString extractDirection (QCString & docs)

Strip the direction part from docs and return it as a string in canonical form The input docs string can start with e.g.

"[in]", "[in, out]", "[inout]", "[out,in]"...

Returns

either "[in,out]", "[in]", or "[out]" or the empty string.

Definition at line 6693 of file util.cpp.

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

References end and QCString::str.

Referenced by inlineArgListToDoc.

extractNamespaceName()

void extractNamespaceName (const QCString & scopeName, QCString & className, QCString & namespaceName, bool allowEmptyClass)

Input is a scopeName, output is the scopename split into a namespace part (as large as possible) and a classname part.

Definition at line 4214 of file util.cpp.

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

References QCString::clear, QCString::endsWith, QCString::findRev, getClass, getResolvedNamespace, QCString::isEmpty, QCString::left, QCString::length, Definition::name and QCString::right.

Referenced by addClassToContext, addConceptToContext, findMember and writeAlphabeticalClassList.

fileToString()

QCString fileToString (const QCString & name, bool filter, bool isSourceCode)

reads a file with name name and returns it as a string. If filter is TRUE the file will be filtered by any user specified input filter. If name is "-" the string will be read from standard input.

Definition at line 1442 of file util.cpp.

1442QCString fileToString(const QCString &name,bool filter,bool isSourceCode)
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}

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

Referenced by createDVIFile, extractBoundingBox, getConvertLatexMacro, HtmlGenerator::init, LatexGenerator::init, LayoutDocManager::parse, parseInput, FileDefImpl::parseSource, parseTagFile, DocParser::readTextFileByName, readTextFileByName, runPlantumlContent, FileDefImpl::writeSourceBody, HtmlGenerator::writeStyleInfo and writeXMLCodeBlock.

fileVisibleInIndex()

bool fileVisibleInIndex (const FileDef * fd, bool & genSourceFile)

Definition at line 6604 of file util.cpp.

6604bool fileVisibleInIndex(const FileDef *fd,bool &genSourceFile)
6605{
6606 bool allExternals = Config_getBool(ALLEXTERNALS);
6607 bool isDocFile = fd->isDocumentationFile();
6608 genSourceFile = !isDocFile && fd->generateSourceFile();
6609 return ( ((allExternals && fd->isLinkable()) ||
6611 ) &&
6612 !isDocFile
6613 );
6614}

References Config_getBool, FileDef::generateSourceFile, FileDef::isDocumentationFile, Definition::isLinkable and Definition::isLinkableInProject.

Referenced by countFiles, dirHasVisibleChildren, generateJSTree, writeDirHierarchy, writeDirTreeNode and DirDefImpl::writeFileList.

filterCRLF()

void filterCRLF (std::string & contents)
static

takes the buf of the given length len and converts CR LF (DOS) or CR (MAC) line ending to LF (Unix). Returns the length of the converted content (i.e. the same as len (Unix, MAC) or smaller (DOS).

Definition at line 1303 of file util.cpp.

1303static void filterCRLF(std::string &contents)
1304{
1305 size_t src = 0; // source index
1306 size_t dest = 0; // destination index
1307 size_t len = contents.length();
1308
1309 while (src<len)
1310 {
1311 char c = contents[src++]; // Remember the processed character.
1312 if (c == '\r') // CR to be solved (MAC, DOS)
1313 {
1314 c = '\n'; // each CR to LF
1315 if (src<len && contents[src] == '\n')
1316 {
1317 ++src; // skip LF just after CR (DOS)
1318 }
1319 }
1320 else if ( c == '\0' && src<len-1) // filter out internal \0 characters, as it will confuse the parser
1321 {
1322 c = ' '; // turn into a space
1323 }
1324 contents[dest++] = c; // copy the (modified) character to dest
1325 }
1326 contents.resize(dest);
1327}

Referenced by readInputFile.

filterTitle()

QCString filterTitle (const QCString & title)

Definition at line 6131 of file util.cpp.

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

References end and QCString::str.

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

findAndRemoveWord()

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

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

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

Definition at line 5498 of file util.cpp.

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

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

Referenced by isVarWithConstructor.

findFileDef()

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

Definition at line 3416 of file util.cpp.

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

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

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

findFilePath()

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

Definition at line 3499 of file util.cpp.

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

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

Referenced by readIncludeFile and DocParser::readTextFileByName.

findIndex()

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

7169int findIndex(const StringVector &sv,const std::string &s)
7170{
7171 auto it = std::find(sv.begin(),sv.end(),s);
7172 return it!=sv.end() ? static_cast<int>(it-sv.begin()) : -1;
7173}

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

findIndex()

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

7177int findIndex(const std::string &s,const reg::Ex &re)
7178{
7179 reg::Match match;
7180 return reg::search(s,match,re) ? static_cast<int>(match.position()) : -1;
7181}

Reference reg::search.

findMembersWithSpecificName()

void findMembersWithSpecificName (const MemberName * mn, const QCString & args, bool checkStatics, const FileDef * currentFile, bool checkCV, std::vector< const MemberDef * > & members)
static

Definition at line 2230 of file util.cpp.

2231 const QCString &args,
2232 bool checkStatics,
2233 const FileDef *currentFile,
2234 bool checkCV,
2235 std::vector<const MemberDef *> &members)
2236{
2237 //printf(" Function with global scope name '%s' args='%s'\n",
2238 // mn->memberName(),args);
2239 for (const auto &md_p : *mn)
2240 {
2241 const MemberDef *md = md_p.get();
2242 const FileDef *fd=md->getFileDef();
2243 const GroupDef *gd=md->getGroupDef();
2244 //printf(" md->name()='%s' md->args='%s' fd=%p gd=%p current=%p ref=%s\n",
2245 // qPrint(md->name()),args,fd,gd,currentFile,qPrint(md->getReference()));
2246 if (
2247 ((gd && gd->isLinkable()) || (fd && fd->isLinkable()) || md->isReference()) &&
2248 md->getNamespaceDef()==nullptr && md->isLinkable() &&
2249 (!checkStatics || (!md->isStatic() && !md->isDefine()) ||
2250 currentFile==nullptr || fd==currentFile) // statics must appear in the same file
2251 )
2252 {
2253 bool match=TRUE;
2254 if (!args.isEmpty() && !md->isDefine() && args!="()")
2255 {
2256 const ArgumentList &mdAl = md->argumentList();
2257 auto argList_p = stringToArgumentList(md->getLanguage(),args);
2258 match=matchArguments2(
2259 md->getOuterScope(),fd,&mdAl,
2260 Doxygen::globalScope,fd,argList_p.get(),
2261 checkCV,md->getLanguage());
2262 }
2263 if (match)
2264 {
2265 //printf("Found match!\n");
2266 members.push_back(md);
2267 }
2268 }
2269 }
2270}

References MemberDef::argumentList, MemberDef::getFileDef, MemberDef::getGroupDef, Definition::getLanguage, MemberDef::getNamespaceDef, Definition::getOuterScope, Doxygen::globalScope, MemberDef::isDefine, QCString::isEmpty, Definition::isLinkable, Definition::isReference, MemberDef::isStatic, matchArguments2, stringToArgumentList and TRUE.

Referenced by getDefsOld.

findModuleDef()

ModuleDef * findModuleDef (const Definition * d)
static

Definition at line 5338 of file util.cpp.

5339{
5340 ModuleDef *mod = nullptr;
5342 {
5343 const FileDef *fd = toFileDef(d);
5344 if (fd) mod = fd->getModuleDef();
5345 }
5347 {
5348 const ClassDef *cd = toClassDef(d);
5349 if (cd)
5350 {
5351 const FileDef *fd = cd->getFileDef();
5352 if (fd) mod = fd->getModuleDef();
5353 }
5354 }
5356 {
5357 const ConceptDef *cd = toConceptDef(d);
5358 if (cd)
5359 {
5360 const FileDef *fd = cd->getFileDef();
5361 if (fd) mod = fd->getModuleDef();
5362 }
5363 }
5364 return mod;
5365}

References Definition::definitionType, ClassDef::getFileDef, ConceptDef::getFileDef, FileDef::getModuleDef, toClassDef, toConceptDef, toFileDef, Definition::TypeClass, Definition::TypeConcept and Definition::TypeFile.

Referenced by recursivelyAddGroupListToTitle.

findParameterList()

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 at line 837 of file util.cpp.

838{
839 int pos=-1;
840 int templateDepth=0;
841 do
842 {
843 if (templateDepth > 0)
844 {
845 int nextOpenPos=name.findRev('>', pos);
846 int nextClosePos=name.findRev('<', pos);
847 if (nextOpenPos!=-1 && nextOpenPos>nextClosePos)
848 {
849 ++templateDepth;
850 pos=nextOpenPos-1;
851 }
852 else if (nextClosePos!=-1)
853 {
854 --templateDepth;
855 pos=nextClosePos-1;
856 }
857 else // more >'s than <'s, see bug701295
858 {
859 return -1;
860 }
861 }
862 else
863 {
864 int lastAnglePos=name.findRev('>', pos);
865 int bracePos=name.findRev('(', pos);
866 if (lastAnglePos!=-1 && lastAnglePos>bracePos)
867 {
868 ++templateDepth;
869 pos=lastAnglePos-1;
870 }
871 else
872 {
873 int bp = bracePos>0 ? name.findRev('(',bracePos-1) : -1;
874 // bp test is to allow foo(int(&)[10]), but we need to make an exception for operator()
875 return bp==-1 || (bp>=8 && name.mid(bp-8,10)=="operator()") ? bracePos : bp;
876 }
877 }
878 } while (pos!=-1);
879 return -1;
880}

References QCString::findRev and QCString::mid.

Referenced by resolveRef.

generateAnonymousAnchor()

QCString generateAnonymousAnchor (const QCString & fileName, int count)

Definition at line 4075 of file util.cpp.

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

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

generateFileRef()

void generateFileRef (OutputList & ol, const QCString & name, const QCString & text)

Definition at line 3388 of file util.cpp.

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

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}

Reference 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.

genericPatternMatch()

template <class PatternList, class PatternElem, typename PatternGet = QCString(*)(const PatternElem &)>
bool genericPatternMatch (const FileInfo & fi, const PatternList & patList, PatternElem & elem, PatternGet getter)

Definition at line 6155 of file util.cpp.

6156 const PatternList &patList,
6157 PatternElem &elem,
6158 PatternGet getter)
6159{
6160 bool caseSenseNames = getCaseSenseNames();
6161 bool found = FALSE;
6162
6163 if (!patList.empty())
6164 {
6165 std::string fn = fi.fileName();
6166 std::string fp = fi.filePath();
6167 std::string afp= fi.absFilePath();
6168
6169 for (const auto &li : patList)
6170 {
6171 std::string pattern = getter(li).str();
6172 if (!pattern.empty())
6173 {
6174 size_t i=pattern.find('=');
6175 if (i!=std::string::npos) pattern=pattern.substr(0,i); // strip of the extension specific filter name
6176
6177 if (!caseSenseNames)
6178 {
6179 pattern = QCString(pattern).lower().str();
6180 fn = QCString(fn).lower().str();
6181 fp = QCString(fp).lower().str();
6182 afp = QCString(afp).lower().str();
6183 }
6185 found = re.isValid() && (reg::match(fn,re) ||
6186 (fn!=fp && reg::match(fp,re)) ||
6187 (fn!=afp && fp!=afp && reg::match(afp,re)));
6188 if (found)
6189 {
6190 elem = li;
6191 break;
6192 }
6193 //printf("Matching '%s' against pattern '%s' found=%d\n",
6194 // qPrint(fi->fileName()),qPrint(pattern),found);
6195 }
6196 }
6197 }
6198 return found;
6199}

References FileInfo::absFilePath, FALSE, FileInfo::fileName, FileInfo::filePath, getCaseSenseNames, reg::Ex::isValid, QCString::lower, reg::match, QCString::str and reg::Ex::Wildcard.

Referenced by getEncoding and patternMatch.

getCanonicalTemplateSpec()

QCString getCanonicalTemplateSpec (const Definition * d, const FileDef * fs, const QCString & spec, SrcLangExt lang)
static

Definition at line 1578 of file util.cpp.

1578static QCString getCanonicalTemplateSpec(const Definition *d,const FileDef *fs,const QCString& spec,SrcLangExt lang)
1579{
1580
1581 QCString templSpec = spec.stripWhiteSpace();
1582 // this part had been commented out before... but it is needed to match for instance
1583 // std::list<std::string> against list<string> so it is now back again!
1584 if (!templSpec.isEmpty() && templSpec.at(0) == '<')
1585 {
1586 templSpec = "< " + extractCanonicalType(d,fs,templSpec.right(templSpec.length()-1).stripWhiteSpace(),lang);
1587 }
1588 QCString resolvedType = lang==SrcLangExt::Java ? templSpec : resolveTypeDef(d,templSpec);
1589 if (!resolvedType.isEmpty()) // not known as a typedef either
1590 {
1591 templSpec = resolvedType;
1592 }
1593 //printf("getCanonicalTemplateSpec(%s)=%s\n",qPrint(spec),qPrint(templSpec));
1594 return templSpec;
1595}

References QCString::at, extractCanonicalType, QCString::isEmpty, QCString::length, resolveTypeDef, QCString::right and QCString::stripWhiteSpace.

Referenced by getCanonicalTypeForIdentifier.

getCanonicalTypeForIdentifier()

QCString getCanonicalTypeForIdentifier (const Definition * d, const FileDef * fs, const QCString & word, SrcLangExt lang, QCString * tSpec, int count=0)
static

Definition at line 1598 of file util.cpp.

1599 const Definition *d,const FileDef *fs,const QCString &word,SrcLangExt lang,
1600 QCString *tSpec,int count=0)
1601{
1602 if (count>10) return word; // oops recursion
1603
1604 QCString symName,result,templSpec,tmpName;
1605 if (tSpec && !tSpec->isEmpty())
1606 templSpec = stripDeclKeywords(getCanonicalTemplateSpec(d,fs,*tSpec,lang));
1607
1608 AUTO_TRACE("d='{}' fs='{}' word='{}' templSpec='{}'",d?d->name():"",fs?fs->name():"",word,templSpec);
1609
1610 if (word.findRev("::")!=-1 && !(tmpName=stripScope(word)).isEmpty())
1611 {
1612 symName=tmpName; // name without scope
1613 }
1614 else
1615 {
1616 symName=word;
1617 }
1618
1619 // lookup class / class template instance
1620 SymbolResolver resolver(fs);
1621 const ClassDef *cd = resolver.resolveClass(d,word+templSpec,true,true);
1622 const MemberDef *mType = resolver.getTypedef();
1623 QCString ts = resolver.getTemplateSpec();
1624 QCString resolvedType = resolver.getResolvedType();
1625
1626 bool isTemplInst = cd && !templSpec.isEmpty();
1627 if (!cd && !templSpec.isEmpty())
1628 {
1629 // class template specialization not known, look up class template
1630 cd = resolver.resolveClass(d,word,true,true);
1631 mType = resolver.getTypedef();
1632 ts = resolver.getTemplateSpec();
1633 resolvedType = resolver.getResolvedType();
1634 }
1635 if (cd && cd->isUsedOnly()) cd=nullptr; // ignore types introduced by usage relations
1636
1637 AUTO_TRACE_ADD("cd='{}' mType='{}' ts='{}' resolvedType='{}'",
1638 cd?cd->name():"",mType?mType->name():"",ts,resolvedType);
1639 //printf("cd=%p mtype=%p\n",cd,mType);
1640 //printf(" getCanonicalTypeForIdentifier: symbol=%s word=%s cd=%s d=%s fs=%s cd->isTemplate=%d\n",
1641 // qPrint(symName),
1642 // qPrint(word),
1643 // cd ? qPrint(cd->name()) : "<none>",
1644 // d ? qPrint( d->name()) : "<none>",
1645 // fs ? qPrint(fs->name()) : "<none>",
1646 // cd ? cd->isTemplate():-1
1647 // );
1648
1649 //printf(" >>>> word '%s' => '%s' templSpec=%s ts=%s tSpec=%s isTemplate=%d resolvedType=%s\n",
1650 // qPrint((word+templSpec)),
1651 // cd ? qPrint(cd->qualifiedName()) : "<none>",
1652 // qPrint(templSpec), qPrint(ts),
1653 // tSpec ? qPrint(tSpec) : "<null>",
1654 // cd ? cd->isTemplate():FALSE,
1655 // qPrint(resolvedType));
1656
1657 //printf(" mtype=%s\n",mType ? qPrint(mType->name()) : "<none>");
1658
1659 if (cd) // resolves to a known class type
1660 {
1661 if (cd==d && tSpec) *tSpec="";
1662
1663 if (mType && mType->isTypedef()) // but via a typedef
1664 {
1665 result = resolvedType+ts; // the +ts was added for bug 685125
1666 }
1667 else
1668 {
1669 if (isTemplInst)
1670 {
1671 // spec is already part of class type
1672 templSpec="";
1673 if (tSpec) *tSpec="";
1674 }
1675 else if (!ts.isEmpty() && templSpec.isEmpty())
1676 {
1677 // use formal template args for spec
1678 templSpec = stripDeclKeywords(getCanonicalTemplateSpec(d,fs,ts,lang));
1679 }
1680
1681 result = removeRedundantWhiteSpace(cd->qualifiedName() + templSpec);
1682
1683 if (cd->isTemplate() && tSpec) //
1684 {
1685 if (!templSpec.isEmpty()) // specific instance
1686 {
1687 result=cd->name()+templSpec;
1688 }
1689 else // use template type
1690 {
1692 }
1693 // template class, so remove the template part (it is part of the class name)
1694 *tSpec="";
1695 }
1696 else if (ts.isEmpty() && !templSpec.isEmpty() && cd && !cd->isTemplate() && tSpec)
1697 {
1698 // obscure case, where a class is used as a template, but doxygen think it is
1699 // not (could happen when loading the class from a tag file).
1700 *tSpec="";
1701 }
1702 }
1703 }
1704 else if (mType && mType->isEnumerate()) // an enum
1705 {
1706 result = mType->qualifiedName();
1707 }
1708 else if (mType && mType->isTypedef()) // a typedef
1709 {
1710 //result = mType->qualifiedName(); // changed after 1.7.2
1711 //result = mType->typeString();
1712 //printf("word=%s typeString=%s\n",qPrint(word),mType->typeString());
1713 if (word!=mType->typeString())
1714 {
1715 QCString type = mType->typeString();
1716 if (type.startsWith("typename "))
1717 {
1718 type.stripPrefix("typename ");
1720 }
1721 if (!type.isEmpty()) // see issue #11065
1722 {
1723 result = getCanonicalTypeForIdentifier(d,fs,type,mType->getLanguage(),tSpec,count+1);
1724 }
1725 else
1726 {
1727 result = word;
1728 }
1729 }
1730 else
1731 {
1732 result = mType->typeString();
1733 }
1734 }
1735 else // fallback
1736 {
1737 resolvedType = lang==SrcLangExt::Java ? word : resolveTypeDef(d,word);
1738 AUTO_TRACE_ADD("fallback resolvedType='{}'",resolvedType);
1739 if (resolvedType.isEmpty()) // not known as a typedef either
1740 {
1741 result = word;
1742 }
1743 else
1744 {
1745 result = resolvedType;
1746 }
1747 }
1748 AUTO_TRACE_EXIT("result='{}'",result);
1749 return result;
1750}

References AUTO_TRACE, AUTO_TRACE_ADD, AUTO_TRACE_EXIT, FALSE, QCString::findRev, getCanonicalTemplateSpec, getCanonicalTypeForIdentifier, Definition::getLanguage, SymbolResolver::getResolvedType, SymbolResolver::getTemplateSpec, SymbolResolver::getTypedef, QCString::isEmpty, MemberDef::isEnumerate, ClassDef::isTemplate, MemberDef::isTypedef, ClassDef::isUsedOnly, Definition::name, Definition::qualifiedName, ClassDef::qualifiedNameWithTemplateParameters, removeRedundantWhiteSpace, SymbolResolver::resolveClass, resolveTypeDef, QCString::startsWith, stripDeclKeywords, QCString::stripPrefix, stripScope, stripTemplateSpecifiersFromScope and MemberDef::typeString.

Referenced by extractCanonicalType and getCanonicalTypeForIdentifier.

getCaseSenseNames()

bool getCaseSenseNames ()

Definition at line 3837 of file util.cpp.

3838{
3839 auto caseSenseNames = Config_getEnum(CASE_SENSE_NAMES);
3840
3841 if (caseSenseNames == CASE_SENSE_NAMES_t::YES) return true;
3842 else if (caseSenseNames == CASE_SENSE_NAMES_t::NO) return false;
3844}

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),
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),
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}

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.

getDefsNew()

GetDefResult getDefsNew (const GetDefInput & input)

Definition at line 2274 of file util.cpp.

2275{
2276 GetDefResult result;
2277 if (input.memberName.isEmpty()) return result;
2278
2279 //printf("@@ --- getDefsNew(%s,%s)-----------\n",qPrint(scName),qPrint(mbName));
2280 const Definition *scope = Doxygen::globalScope;
2281 SymbolResolver resolver;
2282 if (input.currentFile) resolver.setFileScope(input.currentFile);
2283 if (!input.scopeName.isEmpty())
2284 {
2285 scope = resolver.resolveSymbol(scope,input.scopeName);
2286 }
2287 if (scope==Doxygen::globalScope)
2288 {
2289 scope = input.currentFile;
2290 }
2291 //printf("@@ -> found scope scope=%s member=%s out=%s\n",qPrint(input.scopeName),qPrint(input.memberName),qPrint(scope?scope->name():""));
2292 //
2293 const Definition *symbol = resolver.resolveSymbol(scope,input.memberName,input.args,input.checkCV,input.insideCode,true);
2294 //printf("@@ -> found symbol in=%s out=%s\n",qPrint(input.memberName),qPrint(symbol?symbol->qualifiedName():QCString()));
2295 if (symbol && symbol->definitionType()==Definition::TypeMember)
2296 {
2297 result.md = toMemberDef(symbol);
2298 result.cd = result.md->getClassDef();
2299 if (result.cd==nullptr) result.nd = result.md->getNamespaceDef();
2300 if (result.cd==nullptr && result.nd==nullptr) result.fd = result.md->getFileDef();
2301 result.gd = result.md->getGroupDef();
2302 result.found = true;
2303 }
2304 else if (symbol && symbol->definitionType()==Definition::TypeClass)
2305 {
2306 result.cd = toClassDef(symbol);
2307 result.found = true;
2308 }
2309 else if (symbol && symbol->definitionType()==Definition::TypeNamespace)
2310 {
2311 result.nd = toNamespaceDef(symbol);
2312 result.found = true;
2313 }
2314 else if (symbol && symbol->definitionType()==Definition::TypeConcept)
2315 {
2316 result.cnd = toConceptDef(symbol);
2317 result.found = true;
2318 }
2319 else if (symbol && symbol->definitionType()==Definition::TypeModule)
2320 {
2321 result.modd = toModuleDef(symbol);
2322 result.found = true;
2323 }
2324 return result;
2325}

References GetDefInput::args, GetDefResult::cd, GetDefInput::checkCV, GetDefResult::cnd, GetDefInput::currentFile, Definition::definitionType, GetDefResult::fd, GetDefResult::found, GetDefResult::gd, MemberDef::getClassDef, MemberDef::getFileDef, MemberDef::getGroupDef, MemberDef::getNamespaceDef, Doxygen::globalScope, GetDefInput::insideCode, QCString::isEmpty, GetDefResult::md, GetDefInput::memberName, GetDefResult::modd, GetDefResult::nd, SymbolResolver::resolveSymbol, GetDefInput::scopeName, SymbolResolver::setFileScope, toClassDef, toConceptDef, toMemberDef, toModuleDef, toNamespaceDef, Definition::TypeClass, Definition::TypeConcept, Definition::TypeMember, Definition::TypeModule and Definition::TypeNamespace.

Referenced by getDefs.

getDefsOld()

GetDefResult getDefsOld (const GetDefInput & input)

Searches for a member definition given its name 'memberName' as a string. memberName may also include a (partial) scope to indicate the scope in which the member is located.

The parameter 'scName' is a string representing the name of the scope in which the link was found.

In case of a function args contains a string representation of the argument list. Passing 0 means the member has no arguments. Passing "()" means any argument list will do, but "()" is preferred.

The function returns TRUE if the member is known and documented or FALSE if it is not. If TRUE is returned parameter 'md' contains a pointer to the member definition. Furthermore exactly one of the parameter 'cd', 'nd', or 'fd' will be non-zero:

  • if 'cd' is non zero, the member was found in a class pointed to by cd.
  • if 'nd' is non zero, the member was found in a namespace pointed to by nd.
  • if 'fd' is non zero, the member was found in the global namespace of file fd.

Definition at line 2349 of file util.cpp.

2350{
2351 GetDefResult result;
2352 QCString scopeName;
2353 QCString memberName;
2354 QCString mName;
2355 QCString mScope;
2356 MemberName *mn = nullptr;
2357 int is=0,im=0,pm=0;
2358
2359 if (input.memberName.isEmpty()) goto exit; /* empty name => nothing to link */
2360
2361 scopeName = input.scopeName;
2362 scopeName = substitute(scopeName,"\\","::"); // for PHP
2363 memberName = input.memberName;
2364 memberName = substitute(memberName,"\\","::"); // for PHP
2365 //printf("Search for name=%s args=%s in scope=%s forceEmpty=%d\n",
2366 // qPrint(memberName),qPrint(args),qPrint(scopeName),forceEmptyScope);
2367
2368 // strip common part of the scope from the scopeName
2369 while ((is=scopeName.findRev("::"))!=-1 &&
2370 (im=memberName.find("::",pm))!=-1 &&
2371 (scopeName.right(scopeName.length()-is-2)==memberName.mid(pm,im-pm))
2372 )
2373 {
2374 scopeName=scopeName.left(is);
2375 pm=im+2;
2376 }
2377 //printf("result after scope corrections scope=%s name=%s\n",
2378 // qPrint(scopeName), qPrint(memberName));
2379
2380 mName=memberName;
2381 if (!memberName.startsWith("operator ") && // treat operator conversion methods
2382 // as a special case
2383 (im=memberName.findRev("::"))!=-1 &&
2384 im<static_cast<int>(memberName.length())-2 // not A::
2385 )
2386 {
2387 mScope=memberName.left(im);
2388 mName=memberName.right(memberName.length()-im-2);
2389 }
2390
2391 // handle special the case where both scope name and member scope are equal
2392 if (mScope==scopeName) scopeName.clear();
2393
2394 //printf("mScope='%s' mName='%s'\n",qPrint(mScope),qPrint(mName));
2395
2396 mn = Doxygen::memberNameLinkedMap->find(mName);
2397 //printf("mName=%s mn=%p\n",qPrint(mName),mn);
2398
2399 if ((!input.forceEmptyScope || input.scopeName.isEmpty()) && // this was changed for bug638856, forceEmptyScope => empty scopeName
2400 mn && !(input.scopeName.isEmpty() && mScope.isEmpty()))
2401 {
2402 //printf(" >member name '%s' found\n",qPrint(mName));
2403 int scopeOffset = static_cast<int>(scopeName.length());
2404 do
2405 {
2406 QCString className = scopeName.left(scopeOffset);
2407 if (!className.isEmpty() && !mScope.isEmpty())
2408 {
2409 className+="::"+mScope;
2410 }
2411 else if (!mScope.isEmpty())
2412 {
2413 className=mScope;
2414 }
2415
2416 SymbolResolver resolver;
2417 const ClassDef *fcd=resolver.resolveClass(Doxygen::globalScope,className);
2418 const MemberDef *tmd=resolver.getTypedef();
2419
2420 if (fcd==nullptr && className.find('<')!=-1) // try without template specifiers as well
2421 {
2422 QCString nameWithoutTemplates = stripTemplateSpecifiersFromScope(className,FALSE);
2423 fcd=resolver.resolveClass(Doxygen::globalScope,nameWithoutTemplates);
2424 tmd=resolver.getTypedef();
2425 }
2426 //printf("Trying class scope %s: fcd=%p tmd=%p\n",qPrint(className),fcd,tmd);
2427 // todo: fill in correct fileScope!
2428 if (fcd && // is it a documented class
2429 fcd->isLinkable()
2430 )
2431 {
2432 //printf(" Found fcd=%p\n",fcd);
2433 int mdist=maxInheritanceDepth;
2434 std::unique_ptr<ArgumentList> argList;
2435 if (!input.args.isEmpty())
2436 {
2437 argList = stringToArgumentList(fcd->getLanguage(),input.args);
2438 }
2439 for (const auto &mmd_p : *mn)
2440 {
2441 MemberDef *mmd = mmd_p.get();
2442 if (!mmd->isStrongEnumValue())
2443 {
2444 const ArgumentList &mmdAl = mmd->argumentList();
2445 bool match = input.args.isEmpty() ||
2446 matchArguments2(mmd->getOuterScope(),mmd->getFileDef(),&mmdAl,
2447 fcd, fcd->getFileDef(),argList.get(),
2448 input.checkCV,mmd->getLanguage());
2449 //printf("match=%d\n",match);
2450 if (match)
2451 {
2452 const ClassDef *mcd=mmd->getClassDef();
2453 if (mcd)
2454 {
2455 int m=minClassDistance(fcd,mcd);
2456 if (m<mdist && mcd->isLinkable())
2457 {
2458 mdist=m;
2459 result.cd=mcd;
2460 result.md=mmd;
2461 }
2462 }
2463 }
2464 }
2465 }
2466 if (mdist==maxInheritanceDepth && input.args=="()")
2467 // no exact match found, but if args="()" an arbitrary member will do
2468 {
2469 //printf(" >Searching for arbitrary member\n");
2470 for (const auto &mmd_p : *mn)
2471 {
2472 MemberDef *mmd = mmd_p.get();
2473 //if (mmd->isLinkable())
2474 //{
2475 const ClassDef *mcd=mmd->getClassDef();
2476 //printf(" >Class %s found\n",qPrint(mcd->name()));
2477 if (mcd)
2478 {
2479 int m=minClassDistance(fcd,mcd);
2480 if (m<mdist /* && mcd->isLinkable()*/ )
2481 {
2482 //printf("Class distance %d\n",m);
2483 mdist = m;
2484 result.cd = mcd;
2485 result.md = mmd;
2486 }
2487 }
2488 //}
2489 }
2490 }
2491 //printf(" >Success=%d\n",mdist<maxInheritanceDepth);
2492 if (mdist<maxInheritanceDepth)
2493 {
2494 if (!result.md->isLinkable() || result.md->isStrongEnumValue())
2495 {
2496 result.md = nullptr; // avoid returning things we cannot link to
2497 result.cd = nullptr;
2498 result.found = false; // match found, but was not linkable
2499 goto exit;
2500 }
2501 else
2502 {
2503 result.gd = result.md->getGroupDef();
2504 if (result.gd) result.cd=nullptr;
2505 result.found=true; /* found match */
2506 goto exit;
2507 }
2508 }
2509 }
2510 if (tmd && tmd->isEnumerate() && tmd->isStrong()) // scoped enum
2511 {
2512 //printf("Found scoped enum!\n");
2513 for (const auto &emd : tmd->enumFieldList())
2514 {
2515 if (emd->localName()==mName)
2516 {
2517 if (emd->isLinkable())
2518 {
2519 result.cd = tmd->getClassDef();
2520 result.md = emd;
2521 result.found = true;
2522 goto exit;
2523 }
2524 else
2525 {
2526 result.cd = nullptr;
2527 result.md = nullptr;
2528 result.found = false;
2529 goto exit;
2530 }
2531 }
2532 }
2533 }
2534 /* go to the parent scope */
2535 if (scopeOffset==0)
2536 {
2537 scopeOffset=-1;
2538 }
2539 else if ((scopeOffset=scopeName.findRev("::",scopeOffset-1))==-1)
2540 {
2541 scopeOffset=0;
2542 }
2543 } while (scopeOffset>=0);
2544
2545 }
2546 if (mn && input.scopeName.isEmpty() && mScope.isEmpty()) // Maybe a related function?
2547 {
2548 //printf("Global symbol\n");
2549 const MemberDef *fuzzy_mmd = nullptr;
2550 std::unique_ptr<ArgumentList> argList;
2551 bool hasEmptyArgs = input.args=="()";
2552
2553 if (!input.args.isEmpty())
2554 {
2555 argList = stringToArgumentList(SrcLangExt::Cpp, input.args);
2556 }
2557
2558 for (const auto &mmd_p : *mn)
2559 {
2560 const MemberDef *mmd = mmd_p.get();
2561 if (!mmd->isLinkable() || (!mmd->isRelated() && !mmd->isForeign()) ||
2562 !mmd->getClassDef())
2563 {
2564 continue;
2565 }
2566
2567 if (input.args.isEmpty())
2568 {
2569 fuzzy_mmd = mmd;
2570 break;
2571 }
2572
2573 const ArgumentList &mmdAl = mmd->argumentList();
2574 if (matchArguments2(mmd->getOuterScope(),mmd->getFileDef(),&mmdAl,
2575 Doxygen::globalScope,mmd->getFileDef(),argList.get(),
2576 input.checkCV,mmd->getLanguage())
2577 )
2578 {
2579 fuzzy_mmd = mmd;
2580 break;
2581 }
2582
2583 if (!fuzzy_mmd && hasEmptyArgs)
2584 {
2585 fuzzy_mmd = mmd;
2586 }
2587 }
2588
2589 if (fuzzy_mmd && !fuzzy_mmd->isStrongEnumValue())
2590 {
2591 result.md = fuzzy_mmd;
2592 result.cd = fuzzy_mmd->getClassDef();
2593 result.found = true;
2594 goto exit;
2595 }
2596 }
2597
2598
2599 // maybe an namespace, file or group member ?
2600 //printf("Testing for global symbol scopeName='%s' mScope='%s' :: mName='%s'\n",
2601 // qPrint(scopeName), qPrint(mScope), qPrint(mName));
2602 if ((mn=Doxygen::functionNameLinkedMap->find(mName))) // name is known
2603 {
2604 //printf(" >symbol name found\n");
2605 NamespaceDef *fnd=nullptr;
2606 int scopeOffset = static_cast<int>(scopeName.length());
2607 do
2608 {
2609 QCString namespaceName = scopeName.left(scopeOffset);
2610 if (!namespaceName.isEmpty() && !mScope.isEmpty())
2611 {
2612 namespaceName+="::"+mScope;
2613 }
2614 else if (!mScope.isEmpty())
2615 {
2616 namespaceName=mScope;
2617 }
2618 //printf("Trying namespace %s\n",qPrint(namespaceName));
2619 if (!namespaceName.isEmpty() &&
2620 (fnd=Doxygen::namespaceLinkedMap->find(namespaceName)) &&
2621 fnd->isLinkable()
2622 )
2623 {
2624 //printf("Symbol inside existing namespace '%s' count=%d\n",
2625 // qPrint(namespaceName),mn->count());
2626 bool found=FALSE;
2627 for (const auto &mmd_p : *mn)
2628 {
2629 const MemberDef *mmd = mmd_p.get();
2630 //printf("mmd->getNamespaceDef()=%p fnd=%p\n",
2631 // mmd->getNamespaceDef(),fnd);
2632 const MemberDef *emd = mmd->getEnumScope();
2633 if (emd && emd->isStrong())
2634 {
2635 //printf("yes match %s<->%s!\n",qPrint(mScope),qPrint(emd->localName()));
2636 if (emd->getNamespaceDef()==fnd &&
2637 rightScopeMatch(mScope,emd->localName()))
2638 {
2639 //printf("found it!\n");
2640 result.nd=fnd;
2641 result.md=mmd;
2642 found=TRUE;
2643 break;
2644 }
2645 else
2646 {
2647 result.md=nullptr;
2648 result.cd=nullptr;
2649 result.found=false;
2650 goto exit;
2651 }
2652 }
2653 else if (mmd->getOuterScope()==fnd /* && mmd->isLinkable() */ )
2654 { // namespace is found
2655 bool match=TRUE;
2656 if (!input.args.isEmpty() && input.args!="()")
2657 {
2658 const ArgumentList &mmdAl = mmd->argumentList();
2659 auto argList_p = stringToArgumentList(mmd->getLanguage(),input.args);
2660 match=matchArguments2(
2661 mmd->getOuterScope(),mmd->getFileDef(),&mmdAl,
2662 fnd,mmd->getFileDef(),argList_p.get(),
2663 input.checkCV,mmd->getLanguage());
2664 }
2665 if (match)
2666 {
2667 result.nd=fnd;
2668 result.md=mmd;
2669 found=TRUE;
2670 break;
2671 }
2672 }
2673 }
2674 if (!found && input.args=="()")
2675 // no exact match found, but if args="()" an arbitrary
2676 // member will do
2677 {
2678 for (const auto &mmd_p : *mn)
2679 {
2680 const MemberDef *mmd = mmd_p.get();
2681 if (mmd->getNamespaceDef()==fnd /*&& mmd->isLinkable() */ )
2682 {
2683 result.nd=fnd;
2684 result.md=mmd;
2685 found=TRUE;
2686 break;
2687 }
2688 }
2689 }
2690 if (found)
2691 {
2692 if (!result.md->isLinkable())
2693 {
2694 result.md=nullptr; // avoid returning things we cannot link to
2695 result.nd=nullptr;
2696 result.found=false; // match found but not linkable
2697 goto exit;
2698 }
2699 else
2700 {
2701 result.gd=result.md->resolveAlias()->getGroupDef();
2702 if (result.gd && result.gd->isLinkable()) result.nd=nullptr; else result.gd=nullptr;
2703 result.found = true;
2704 goto exit;
2705 }
2706 }
2707 }
2708 else
2709 {
2710 //printf("not a namespace\n");
2711 for (const auto &mmd_p : *mn)
2712 {
2713 const MemberDef *mmd = mmd_p.get();
2714 const MemberDef *tmd = mmd->getEnumScope();
2715 //printf("try member %s tmd=%s\n",qPrint(mmd->name()),tmd ? qPrint(tmd->name()) : "<none>");
2716 int ni=namespaceName.findRev("::");
2717 //printf("namespaceName=%s ni=%d\n",qPrint(namespaceName),ni);
2718 bool notInNS = tmd && ni==-1 && tmd->getNamespaceDef()==nullptr && (mScope.isEmpty() || mScope==tmd->name());
2719 bool sameNS = tmd && ni>=0 && tmd->getNamespaceDef() && namespaceName.left(ni)==tmd->getNamespaceDef()->name() && namespaceName.mid(ni+2)==tmd->name();
2720 //printf("notInNS=%d sameNS=%d\n",notInNS,sameNS);
2721 if (tmd && tmd->isStrong() && // C++11 enum class
2722 (notInNS || sameNS) &&
2723 namespaceName.length()>0 // enum is part of namespace so this should not be empty
2724 )
2725 {
2726 result.md=mmd;
2727 result.fd=mmd->getFileDef();
2728 result.gd=mmd->getGroupDef();
2729 if (result.gd && result.gd->isLinkable()) result.fd=nullptr; else result.gd=nullptr;
2730 //printf("Found scoped enum %s fd=%p gd=%p\n",
2731 // qPrint(mmd->name()),result.fd,result.gd);
2732 result.found = true;
2733 goto exit;
2734 }
2735 }
2736 }
2737 if (scopeOffset==0)
2738 {
2739 scopeOffset=-1;
2740 }
2741 else if ((scopeOffset=scopeName.findRev("::",scopeOffset-1))==-1)
2742 {
2743 scopeOffset=0;
2744 }
2745 } while (scopeOffset>=0);
2746
2747 //else // no scope => global function
2748 {
2749 std::vector<const MemberDef *> members;
2750 // search for matches with strict static checking
2751 findMembersWithSpecificName(mn,input.args,true,input.currentFile,input.checkCV,members);
2752 if (members.empty()) // nothing found
2753 {
2754 // search again without strict static checking
2755 findMembersWithSpecificName(mn,input.args,false,input.currentFile,input.checkCV,members);
2756 }
2757 //printf("found %d members\n",members.count());
2758 if (members.size()!=1 && input.args=="()")
2759 {
2760 // no exact match found, but if args="()" an arbitrary
2761 // member will do
2762 //MemberNameIterator mni(*mn);
2763 //for (mni.toLast();(md=mni.current());--mni)
2764 for (auto it = mn->rbegin(); it!=mn->rend(); ++it)
2765 {
2766 const auto &mmd_p = *it;
2767 const MemberDef *mmd = mmd_p.get();
2768 //printf("Found member '%s'\n",qPrint(mmd->name()));
2769 //printf("member is linkable mmd->name()='%s'\n",qPrint(mmd->name()));
2770 result.fd = mmd->getFileDef();
2771 result.gd = mmd->getGroupDef();
2772 const MemberDef *tmd = mmd->getEnumScope();
2773 if (
2774 (result.gd && result.gd->isLinkable()) || (result.fd && result.fd->isLinkable()) ||
2775 (tmd && tmd->isStrong())
2776 )
2777 {
2778 members.push_back(mmd);
2779 }
2780 }
2781 }
2782 //printf("found %d candidate members\n",members.count());
2783 if (!members.empty()) // at least one match
2784 {
2785 if (input.currentFile)
2786 {
2787 //printf("multiple results; pick one from file:%s\n",qPrint( currentFile->name()));
2788 for (const auto &rmd : members)
2789 {
2790 if (rmd->getFileDef() && rmd->getFileDef()->name() == input.currentFile->name())
2791 {
2792 result.md = rmd;
2793 break; // found match in the current file
2794 }
2795 }
2796 if (!result.md) // member not in the current file
2797 {
2798 result.md = members.back();
2799 }
2800 }
2801 else
2802 {
2803 result.md = members.back();
2804 }
2805 }
2806 if (result.md && (result.md->getEnumScope()==nullptr || !result.md->getEnumScope()->isStrong()))
2807 // found a matching global member, that is not a scoped enum value (or uniquely matches)
2808 {
2809 result.fd = result.md->getFileDef();
2810 result.gd = result.md->getGroupDef();
2811 //printf("fd=%p gd=%p gd->isLinkable()=%d\n",fd,gd,gd->isLinkable());
2812 if (result.gd && result.gd->isLinkable()) result.fd=nullptr; else result.gd=nullptr;
2813 result.found = true;
2814 goto exit;
2815 }
2816 }
2817 }
2818
2819exit:
2820 return result;
2821}

References GetDefInput::args, MemberDef::argumentList, GetDefResult::cd, GetDefInput::checkCV, QCString::clear, GetDefInput::currentFile, MemberDef::enumFieldList, FALSE, GetDefResult::fd, QCString::find, findMembersWithSpecificName, QCString::findRev, GetDefInput::forceEmptyScope, GetDefResult::found, Doxygen::functionNameLinkedMap, GetDefResult::gd, MemberDef::getClassDef, MemberDef::getEnumScope, ClassDef::getFileDef, MemberDef::getFileDef, MemberDef::getGroupDef, Definition::getLanguage, MemberDef::getNamespaceDef, Definition::getOuterScope, SymbolResolver::getTypedef, Doxygen::globalScope, QCString::isEmpty, MemberDef::isEnumerate, MemberDef::isForeign, Definition::isLinkable, MemberDef::isRelated, MemberDef::isStrong, MemberDef::isStrongEnumValue, QCString::left, QCString::length, Definition::localName, matchArguments2, maxInheritanceDepth, GetDefResult::md, GetDefInput::memberName, Doxygen::memberNameLinkedMap, QCString::mid, minClassDistance, Definition::name, Doxygen::namespaceLinkedMap, GetDefResult::nd, MemberName::rbegin, MemberName::rend, MemberDef::resolveAlias, SymbolResolver::resolveClass, QCString::right, rightScopeMatch, GetDefInput::scopeName, QCString::startsWith, stringToArgumentList, stripTemplateSpecifiersFromScope, substitute and TRUE.

Referenced by getDefs.

getDotImageExtension()

QCString getDotImageExtension ()

Definition at line 6804 of file util.cpp.

6805{
6806 QCString imgExt = Config_getEnumAsString(DOT_IMAGE_FORMAT);
6807 int i= imgExt.find(':'); // strip renderer part when using e.g. 'png:cairo:gd' as format
6808 return i==-1 ? imgExt : imgExt.left(i);
6809}

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

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

getEncoding()

QCString getEncoding (const FileInfo & fi)

Definition at line 6212 of file util.cpp.

6213{
6215 auto getter = [](const InputFileEncoding &e) { return e.pattern; };
6216 if (genericPatternMatch(fi,Doxygen::inputFileEncodingList,elem,getter)) // check for file specific encoding
6217 {
6218 return elem.encoding;
6219 }
6220 else // fall back to default encoding
6221 {
6222 return Config_getString(INPUT_ENCODING);
6223 }
6224}

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.

1370QCString getFileFilter(const QCString &name,bool isSourceCode)
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}

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

getFilterFromList()

QCString getFilterFromList (const QCString & name, const StringVector & filterList, bool & found)
static

Definition at line 1329 of file util.cpp.

1329static QCString getFilterFromList(const QCString &name,const StringVector &filterList,bool &found)
1330{
1331 found=FALSE;
1332 // compare the file name to the filter pattern list
1333 for (const auto &filterStr : filterList)
1334 {
1335 QCString fs = filterStr.c_str();
1336 int i_equals=fs.find('=');
1337 if (i_equals!=-1)
1338 {
1339 QCString filterPattern = fs.left(i_equals);
1340 QCString input = name;
1342 {
1343 filterPattern = filterPattern.lower();
1344 input = input.lower();
1345 }
1346 reg::Ex re(filterPattern.str(),reg::Ex::Mode::Wildcard);
1347 if (re.isValid() && reg::match(input.str(),re))
1348 {
1349 // found a match!
1350 QCString filterName = fs.mid(i_equals+1);
1351 if (filterName.find(' ')!=-1)
1352 { // add quotes if the name has spaces
1353 filterName="\""+filterName+"\"";
1354 }
1355 found=TRUE;
1356 return filterName;
1357 }
1358 }
1359 }
1360
1361 // no match
1362 return "";
1363}

References FALSE, Portable::fileSystemIsCaseSensitive, QCString::find, reg::Ex::isValid, QCString::left, QCString::lower, reg::match, QCString::mid, QCString::str, TRUE and reg::Ex::Wildcard.

Referenced by getFileFilter.

getLanguageFromCodeLang()

SrcLangExt getLanguageFromCodeLang (QCString & fileName)

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

Definition at line 5740 of file util.cpp.

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

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)

Definition at line 5722 of file util.cpp.

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

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)

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

Definition at line 6414 of file util.cpp.

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

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.

getMemberFromSymbol()

MemberDef * getMemberFromSymbol (const Definition * scope, const FileDef * fileScope, const QCString & n)
static

Definition at line 5774 of file util.cpp.

5774static MemberDef *getMemberFromSymbol(const Definition *scope,const FileDef *fileScope,
5775 const QCString &n)
5776{
5777 if (scope==nullptr ||
5780 )
5781 )
5782 {
5784 }
5785
5786 QCString name = n;
5787 if (name.isEmpty())
5788 return nullptr; // no name was given
5789
5790 auto &range = Doxygen::symbolMap->find(name);
5791 if (range.empty())
5792 return nullptr; // could not find any matching symbols
5793
5794 // mostly copied from getResolvedClassRec()
5795 QCString explicitScopePart;
5796 int qualifierIndex = computeQualifiedIndex(name);
5797 if (qualifierIndex!=-1)
5798 {
5799 explicitScopePart = name.left(qualifierIndex);
5800 replaceNamespaceAliases(explicitScopePart);
5801 name = name.mid(qualifierIndex+2);
5802 }
5803 //printf("explicitScopePart=%s\n",qPrint(explicitScopePart));
5804
5805 int minDistance = 10000;
5806 MemberDef *bestMatch = nullptr;
5807
5808 for (Definition *d : range)
5809 {
5810 if (d->definitionType()==Definition::TypeMember)
5811 {
5812 SymbolResolver resolver(fileScope);
5813 int distance = resolver.isAccessibleFromWithExpScope(scope,d,explicitScopePart);
5814 if (distance!=-1 && distance<minDistance)
5815 {
5816 minDistance = distance;
5817 bestMatch = toMemberDef(d);
5818 //printf("new best match %s distance=%d\n",qPrint(bestMatch->qualifiedName()),distance);
5819 }
5820 }
5821 }
5822 return bestMatch;
5823}

References computeQualifiedIndex, Definition::definitionType, Doxygen::globalScope, SymbolResolver::isAccessibleFromWithExpScope, QCString::isEmpty, QCString::left, QCString::mid, replaceNamespaceAliases, Doxygen::symbolMap, toMemberDef, Definition::TypeClass, Definition::TypeMember and Definition::TypeNamespace.

Referenced by checkIfTypedef.

getOverloadDocs()

QCString getOverloadDocs ()

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

Definition at line 4603 of file util.cpp.

4604{
4605 return theTranslator->trOverloadText();
4606 //"This is an overloaded member function, "
4607 // "provided for convenience. It differs from the above "
4608 // "function only in what argument(s) it accepts.";
4609}

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

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

References Config_getList, QCString::data and QCString::isEmpty.

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

getProjectId()

QCString getProjectId ()

Definition at line 7326 of file util.cpp.

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

References Config_getString, QCString::data, QCString::isEmpty and QCString::length.

Referenced by generateJSNavTree, HtmlGenerator::init and writeJavaScriptSearchIndex.

getScopeDefs()

bool getScopeDefs (const QCString & docScope, const QCString & scope, ClassDef *& cd, ConceptDef *& cnd, NamespaceDef *& nd, ModuleDef *& modd)
static

Searches for a scope definition given its name as a string via parameter scope.

The parameter docScope is a string representing the name of the scope in which the scope string was found.

The function returns TRUE if the scope is known and documented or FALSE if it is not. If TRUE is returned exactly one of the parameter cd, nd will be non-zero:

  • if cd is non zero, the scope was a class pointed to by cd.
  • if nd is non zero, the scope was a namespace pointed to by nd.

Definition at line 2891 of file util.cpp.

2891static bool getScopeDefs(const QCString &docScope,const QCString &scope,
2892 ClassDef *&cd, ConceptDef *&cnd, NamespaceDef *&nd,ModuleDef *&modd)
2893{
2894 cd=nullptr;
2895 cnd=nullptr;
2896 nd=nullptr;
2897 modd=nullptr;
2898
2899 QCString scopeName=scope;
2900 //printf("getScopeDefs: docScope='%s' scope='%s'\n",qPrint(docScope),qPrint(scope));
2901 if (scopeName.isEmpty()) return FALSE;
2902
2903 bool explicitGlobalScope=FALSE;
2904 if (scopeName.at(0)==':' && scopeName.at(1)==':')
2905 {
2906 scopeName=scopeName.right(scopeName.length()-2);
2907 explicitGlobalScope=TRUE;
2908 }
2909 if (scopeName.isEmpty())
2910 {
2911 return FALSE;
2912 }
2913
2914 QCString docScopeName=docScope;
2915 int scopeOffset=explicitGlobalScope ? 0 : static_cast<int>(docScopeName.length());
2916
2917 do // for each possible docScope (from largest to and including empty)
2918 {
2919 QCString fullName=scopeName;
2920 if (scopeOffset>0) fullName.prepend(docScopeName.left(scopeOffset)+"::");
2921
2922 if (((cd=getClass(fullName)) || // normal class
2923 (cd=getClass(fullName+"-p")) // ObjC protocol
2924 ) && cd->isLinkable())
2925 {
2926 return TRUE; // class link written => quit
2927 }
2928 else if ((nd=Doxygen::namespaceLinkedMap->find(fullName)) && nd->isLinkable())
2929 {
2930 return TRUE; // namespace link written => quit
2931 }
2932 else if ((cnd=Doxygen::conceptLinkedMap->find(fullName)) && cnd->isLinkable())
2933 {
2934 return TRUE; // concept link written => quit
2935 }
2936 else if ((modd=ModuleManager::instance().modules().find(fullName)) && modd->isLinkable())
2937 {
2938 return TRUE; // module link written => quit
2939 }
2940 if (scopeOffset==0)
2941 {
2942 scopeOffset=-1;
2943 }
2944 else if ((scopeOffset=docScopeName.findRev("::",scopeOffset-1))==-1)
2945 {
2946 scopeOffset=0;
2947 }
2948 } while (scopeOffset>=0);
2949
2950 return FALSE;
2951}

References QCString::at, Doxygen::conceptLinkedMap, FALSE, QCString::findRev, getClass, ModuleManager::instance, QCString::isEmpty, Definition::isLinkable, QCString::left, QCString::length, Doxygen::namespaceLinkedMap, QCString::prepend, QCString::right and TRUE.

Referenced by resolveRef.

getScopeFragment()

int getScopeFragment (const QCString & s, int p, int * l)

Returns a fragment from scope s, starting at position p.

Parameters
s

the scope name as a string.

p

the start position (0 is the first).

l

the resulting length of the fragment.

Returns

the location of the fragment, or -1 if non is found.

Definition at line 5142 of file util.cpp.

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

References QCString::at and QCString::length.

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

guessSection()

EntryType guessSection (const QCString & name)

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

Definition at line 350 of file util.cpp.

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

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

Referenced by addIncludeFile, anonymous{tagreader.cpp}::TagFileParser::buildLists, ClassDefImpl::ClassDefImpl, computeClassRelations, FileDefImpl::FileDefImpl, FileDefImpl::generateSourceFile, parseMain, parseMain, Preprocessor::processFile, setFileName and warnUndocumentedNamespaces.

initDefaultExtensionMapping()

void initDefaultExtensionMapping ()

Definition at line 5649 of file util.cpp.

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

Reference 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}

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;
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}

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

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

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)

Definition at line 7197 of file util.cpp.

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

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

integerToRoman()

QCString integerToRoman (int n, bool upper)

Definition at line 7213 of file util.cpp.

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

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

isLowerCase()

bool isLowerCase (QCString & s)
static

Definition at line 2953 of file util.cpp.

2953static bool isLowerCase(QCString &s)
2954{
2955 if (s.isEmpty()) return true;
2956 const char *p=s.data();
2957 int c=0;
2958 while ((c=static_cast<uint8_t>(*p++))) if (!islower(c)) return false;
2959 return true;
2960}

References QCString::data and QCString::isEmpty.

Referenced by resolveRef.

isURL()

bool isURL (const QCString & url)

Checks whether the given url starts with a supported protocol.

Definition at line 6430 of file util.cpp.

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

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

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

join()

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

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

Definition at line 7184 of file util.cpp.

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

Referenced by handleAnchor, handleCite, handleFormatBlock and handleImage.

keyWordsFortranC()

bool keyWordsFortranC (const char * contents)
static

Definition at line 6838 of file util.cpp.

6838static bool keyWordsFortranC(const char *contents)
6839{
6840 static const std::unordered_set<std::string> fortran_C_keywords = {
6841 "character", "call", "close", "common", "continue",
6842 "case", "contains", "cycle", "class", "codimension",
6843 "concurrent", "contiguous", "critical"
6844 };
6845
6846 if (*contents != 'c' && *contents != 'C') return false;
6847
6848 const char *c = contents;
6849 QCString keyword;
6850 while (*c && *c != ' ') {keyword += *c; c++;}
6851 keyword = keyword.lower();
6852
6853 return (fortran_C_keywords.find(keyword.str()) != fortran_C_keywords.end());
6854}

References QCString::lower and QCString::str.

Referenced by recognizeFixedForm.

langToString()

QCString langToString (SrcLangExt lang)

Returns a string representation of lang.

Definition at line 6408 of file util.cpp.

6409{
6410 return to_string(lang);
6411}

Reference 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.

893bool leftScopeMatch(const QCString &scope, const QCString &name)
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 6387 of file util.cpp.

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

Reference QCString::find.

Referenced by readIncludeFile.

linkifyText()

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

905void linkifyText(const TextGeneratorIntf &out, const Definition *scope,
906 const FileDef *fileScope,const Definition *self,
907 const QCString &text, bool autoBreak,bool external,
908 bool keepSpaces,int indentLevel)
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}

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

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

linkToText()

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

Definition at line 3220 of file util.cpp.

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

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

6800{
6801 return Doxygen::mainPage!=nullptr && Doxygen::mainPage->hasTitle();
6802}

Reference Doxygen::mainPage.

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

mangleCSharpGenericName()

QCString mangleCSharpGenericName (const QCString & name)

Definition at line 7428 of file util.cpp.

7429{
7430 int idx = name.find('<');
7431 if (idx!=-1)
7432 {
7433 return name.left(idx)+"-"+QCString().setNum(name.contains(",")+1)+"-g";
7434 }
7435 return name;
7436}

References QCString::contains, QCString::find, QCString::left and QCString::setNum.

Referenced by addClassToContext, addEnumValuesToEnums, addVariable, buildFunctionList, extractClassName, findClassRelation, findEnums, SymbolResolver::resolveClass, resolveLink and resolveRef.

matchArgument2()

bool matchArgument2 (const Definition * srcScope, const FileDef * srcFileScope, Argument & srcA, const Definition * dstScope, const FileDef * dstFileScope, Argument & dstA, SrcLangExt lang)
static

Definition at line 1893 of file util.cpp.

1893static bool matchArgument2(
1894 const Definition *srcScope,const FileDef *srcFileScope,Argument &srcA,
1895 const Definition *dstScope,const FileDef *dstFileScope,Argument &dstA,
1896 SrcLangExt lang
1897 )
1898{
1899 AUTO_TRACE("src: scope={} type={} name={} canType={}, dst: scope={} type={} name={} canType={}",
1900 srcScope?srcScope->name():"",srcA.type,srcA.name,srcA.canType,
1901 dstScope?dstScope->name():"",dstA.type,dstA.name,dstA.canType);
1902 //printf(">> match argument: %s::'%s|%s' (%s) <-> %s::'%s|%s' (%s)\n",
1903 // srcScope ? qPrint(srcScope->name()) : "",
1904 // qPrint(srcA.type), qPrint(srcA.name), qPrint(srcA.canType),
1905 // dstScope ? qPrint(dstScope->name()) : "",
1906 // qPrint(dstA.type), qPrint(dstA.name), qPrint(dstA.canType));
1907
1908 QCString sSrcName = " "+srcA.name;
1909 QCString sDstName = " "+dstA.name;
1910 QCString srcType = srcA.type;
1911 QCString dstType = dstA.type;
1914 //printf("'%s'<->'%s'\n",qPrint(sSrcName),qPrint(dstType.right(sSrcName.length())));
1915 //printf("'%s'<->'%s'\n",qPrint(sDstName),qPrint(srcType.right(sDstName.length())));
1916 if (sSrcName==dstType.right(sSrcName.length()))
1917 { // case "unsigned int" <-> "unsigned int i"
1918 srcA.type+=sSrcName;
1919 srcA.name="";
1920 srcA.canType=""; // invalidate cached type value
1921 }
1922 else if (sDstName==srcType.right(sDstName.length()))
1923 { // case "unsigned int i" <-> "unsigned int"
1924 dstA.type+=sDstName;
1925 dstA.name="";
1926 dstA.canType=""; // invalidate cached type value
1927 }
1928
1929 {
1930 std::lock_guard lock(g_matchArgsMutex);
1931 if (srcA.canType.isEmpty() || dstA.canType.isEmpty())
1932 {
1933 // need to re-evaluate both see issue #8370
1934 srcA.canType = extractCanonicalArgType(srcScope,srcFileScope,srcA,lang);
1935 dstA.canType = extractCanonicalArgType(dstScope,dstFileScope,dstA,lang);
1936 }
1937 }
1938
1939 if (matchCanonicalTypes(srcScope,srcFileScope,srcA.canType,
1940 dstScope,dstFileScope,dstA.canType,
1941 lang))
1942 {
1943 MATCH
1944 AUTO_TRACE_EXIT("true");
1945 return TRUE;
1946 }
1947 else
1948 {
1949 //printf(" Canonical types do not match [%s]<->[%s]\n",
1950 // qPrint(srcA->canType),qPrint(dstA->canType));
1951 NOMATCH
1952 AUTO_TRACE_EXIT("false");
1953 return FALSE;
1954 }
1955}

References AUTO_TRACE, AUTO_TRACE_EXIT, Argument::canType, extractCanonicalArgType, FALSE, g_matchArgsMutex, QCString::isEmpty, QCString::length, MATCH, matchCanonicalTypes, Argument::name, Definition::name, NOMATCH, QCString::right, stripIrrelevantConstVolatile, TRUE and Argument::type.

Referenced by matchArguments2.

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.

1959bool matchArguments2(const Definition *srcScope,const FileDef *srcFileScope,const ArgumentList *srcAl,
1960 const Definition *dstScope,const FileDef *dstFileScope,const ArgumentList *dstAl,
1961 bool checkCV,SrcLangExt lang)
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}

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.

matchCanonicalTypes()

bool matchCanonicalTypes (const Definition * srcScope, const FileDef * srcFileScope, const QCString & srcType, const Definition * dstScope, const FileDef * dstFileScope, const QCString & dstType, SrcLangExt lang)
static

Definition at line 1861 of file util.cpp.

1862 const Definition *srcScope,const FileDef *srcFileScope,const QCString &srcType,
1863 const Definition *dstScope,const FileDef *dstFileScope,const QCString &dstType,
1864 SrcLangExt lang)
1865{
1866 AUTO_TRACE("srcType='{}' dstType='{}'",srcType,dstType);
1867 if (srcType==dstType) return true;
1868
1869 // check if the types are function pointers
1870 int i1=srcType.find(")(");
1871 if (i1==-1) return false;
1872 int i2=dstType.find(")(");
1873 if (i1!=i2) return false;
1874
1875 // check if the result part of the function pointer types matches
1876 int j1=srcType.find("(");
1877 if (j1==-1 || j1>i1) return false;
1878 int j2=dstType.find("(");
1879 if (j2!=j1) return false;
1880 if (srcType.left(j1)!=dstType.left(j2)) return false; // different return types
1881
1882 // if srcType and dstType are both function pointers with the same return type,
1883 // then match against the parameter lists.
1884 // This way srcType='void (*fptr)(int x)' will match against `void (*fptr)(int y)' because
1885 // 'int x' matches 'int y'. A simple literal string match would treat these as different.
1886 auto srcAl = stringToArgumentList(lang,srcType.mid(i1+1));
1887 auto dstAl = stringToArgumentList(lang,dstType.mid(i2+1));
1888 return matchArguments2(srcScope,srcFileScope,srcAl.get(),
1889 dstScope,dstFileScope,dstAl.get(),
1890 true,lang);
1891}

References AUTO_TRACE, QCString::find, QCString::left, matchArguments2, QCString::mid and stringToArgumentList.

Referenced by matchArgument2.

matchTemplateArguments()

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

Definition at line 2197 of file util.cpp.

2197bool matchTemplateArguments(const ArgumentList &srcAl,const ArgumentList &dstAl)
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}

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)

Definition at line 2053 of file util.cpp.

2053void mergeArguments(ArgumentList &srcAl,ArgumentList &dstAl,bool forceNameOverwrite)
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}

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

7377{
7378 if (Config_getBool(CALL_GRAPH) !=md1->hasCallGraph()) md2->overrideCallGraph(md1->hasCallGraph());
7379 if (Config_getBool(CALLER_GRAPH)!=md1->hasCallerGraph()) md2->overrideCallerGraph(md1->hasCallerGraph());
7380 if (Config_getBool(CALL_GRAPH) !=md2->hasCallGraph()) md1->overrideCallGraph( md2->hasCallGraph());
7381 if (Config_getBool(CALLER_GRAPH)!=md2->hasCallerGraph()) md1->overrideCallerGraph(md2->hasCallerGraph());
7382
7383 if (Config_getBool(SHOW_ENUM_VALUES) !=md1->hasEnumValues()) md2->overrideEnumValues(md1->hasEnumValues());
7384 if (Config_getBool(SHOW_ENUM_VALUES) !=md2->hasEnumValues()) md1->overrideEnumValues( md2->hasEnumValues());
7385
7386 if (Config_getBool(REFERENCED_BY_RELATION)!=md1->hasReferencedByRelation()) md2->overrideReferencedByRelation(md1->hasReferencedByRelation());
7387 if (Config_getBool(REFERENCES_RELATION) !=md1->hasReferencesRelation()) md2->overrideReferencesRelation(md1->hasReferencesRelation());
7388 if (Config_getBool(REFERENCED_BY_RELATION)!=md2->hasReferencedByRelation()) md1->overrideReferencedByRelation(md2->hasReferencedByRelation());
7389 if (Config_getBool(REFERENCES_RELATION) !=md2->hasReferencesRelation()) md1->overrideReferencesRelation(md2->hasReferencesRelation());
7390
7391 if (Config_getBool(INLINE_SOURCES)!=md1->hasInlineSource()) md2->overrideInlineSource(md1->hasInlineSource());
7392 if (Config_getBool(INLINE_SOURCES)!=md2->hasInlineSource()) md1->overrideInlineSource(md2->hasInlineSource());
7393}

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
leftScope

the left hand part of the scope.

rightScope

the right hand part of the scope.

Returns

the merged scope.

Definition at line 5097 of file util.cpp.

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

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

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

nextUTF8CharPosition()

int nextUTF8CharPosition (const QCString & utf8Str, uint32_t len, uint32_t startPos)
static

Definition at line 5836 of file util.cpp.

5836static int nextUTF8CharPosition(const QCString &utf8Str,uint32_t len,uint32_t startPos)
5837{
5838 if (startPos>=len) return len;
5839 uint8_t c = static_cast<uint8_t>(utf8Str[startPos]);
5840 int bytes=getUTF8CharNumBytes(c);
5841 if (c=='&') // skip over character entities
5842 {
5843 bytes=1;
5844 int (*matcher)(int) = nullptr;
5845 c = static_cast<uint8_t>(utf8Str[startPos+bytes]);
5846 if (c=='#') // numerical entity?
5847 {
5848 bytes++;
5849 c = static_cast<uint8_t>(utf8Str[startPos+bytes]);
5850 if (c=='x') // hexadecimal entity?
5851 {
5852 bytes++;
5853 matcher = std::isxdigit;
5854 }
5855 else // decimal entity
5856 {
5857 matcher = std::isdigit;
5858 }
5859 }
5860 else if (std::isalnum(c)) // named entity?
5861 {
5862 bytes++;
5863 matcher = std::isalnum;
5864 }
5865 if (matcher)
5866 {
5867 while ((c = static_cast<uint8_t>(utf8Str[startPos+bytes]))!=0 && matcher(c))
5868 {
5869 bytes++;
5870 }
5871 }
5872 if (c!=';')
5873 {
5874 bytes=1; // not a valid entity, reset bytes counter
5875 }
5876 }
5877 return startPos+bytes;
5878}

Reference getUTF8CharNumBytes.

Referenced by parseCommentAsText.

normalizeNonTemplateArgumentsInString()

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

Definition at line 4803 of file util.cpp.

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

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

Referenced by findUsedClassesForClass.

openOutputFile()

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

Definition at line 6811 of file util.cpp.

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

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

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

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 * md, const QCString & doc, const QCString & fileName, int lineNr)

Definition at line 5880 of file util.cpp.

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

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

Referenced by PageDefImpl::addSectionsToIndex, DefinitionImpl::computeTooltip, writeGroupTreeNode, writeIndex and writePages.

patternMatch()

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

Definition at line 6205 of file util.cpp.

6205bool patternMatch(const FileInfo &fi,const StringVector &patList)
6206{
6207 std::string elem;
6208 auto getter = [](std::string s) { return QCString(s); };
6209 return genericPatternMatch(fi,patList,elem,getter);
6210}

Reference genericPatternMatch.

Referenced by checkAndOpenFile and readDir.

projectLogoFile()

QCString projectLogoFile ()

Definition at line 3658 of file util.cpp.

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

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

Referenced by copyLogo and substituteKeywords.

projectLogoSize()

QCString projectLogoSize ()
static

Definition at line 3679 of file util.cpp.

3680{
3681 QCString sizeVal;
3682 QCString projectLogo = Config_getString(PROJECT_LOGO);
3683 if (!projectLogo.isEmpty())
3684 {
3685 auto extractDimension = [&projectLogo](const char *startMarker,size_t startPos,size_t endPos) -> QCString
3686 {
3687 QCString result = projectLogo.mid(startPos,endPos-startPos).stripWhiteSpace().quoted();
3688 if (result.length()>=2 && result.at(0)!='"' && result.at(result.length()-1)!='"')
3689 {
3690 result="\""+result+"\"";
3691 }
3692 result.prepend(startMarker);
3693 return result;
3694 };
3695 // check for optional width= and height= specifier
3696 int wi = projectLogo.find(" width=");
3697 int hi = projectLogo.find(" height=");
3698 if (wi!=-1 && hi!=-1)
3699 {
3700 if (wi<hi) // "... width=x height=y..."
3701 {
3702 sizeVal = extractDimension(" width=", wi+7, hi) + " "
3703 + extractDimension(" height=", hi+8, projectLogo.length());
3704 }
3705 else // "... height=y width=x..."
3706 {
3707 sizeVal = extractDimension(" height=", hi+8, wi) + " "
3708 + extractDimension(" width=", wi+7, projectLogo.length());
3709 }
3710 }
3711 else if (wi!=-1) // ... width=x..."
3712 {
3713 sizeVal = extractDimension(" width=", wi+7, projectLogo.length());
3714 }
3715 else if (hi!=-1) // ... height=x..."
3716 {
3717 sizeVal = extractDimension(" height=", hi+8, projectLogo.length());
3718 }
3719 }
3720 //printf("projectsize='%s'\n",qPrint(sizeVal));
3721 return sizeVal;
3722}

References QCString::at, Config_getString, QCString::find, QCString::isEmpty, QCString::length, QCString::mid, QCString::prepend, QCString::quoted and QCString::stripWhiteSpace.

Referenced by substituteKeywords.

protectionLevelVisible()

bool protectionLevelVisible (Protection prot)

Definition at line 6454 of file util.cpp.

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

Reference 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, bool isSourceCode)

read a file name fileName and optionally filter and transcode it

Definition at line 6051 of file util.cpp.

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

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.

recognizeFixedForm()

bool recognizeFixedForm (const QCString & contents, FortranFormat format)

Definition at line 6858 of file util.cpp.

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

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

Referenced by convertCppComments, FortranCodeParser::parseCode and parseMain.

recursivelyAddGroupListToTitle()

bool recursivelyAddGroupListToTitle (OutputList & ol, const Definition * d, bool root)
static

Definition at line 5367 of file util.cpp.

5367static bool recursivelyAddGroupListToTitle(OutputList &ol,const Definition *d,bool root)
5368{
5369 ModuleDef *mod = root ? findModuleDef(d) : nullptr;
5370 if (!d->partOfGroups().empty() || mod!=nullptr) // write list of group to which this definition belongs
5371 {
5372 if (root)
5373 {
5376 ol.writeString("<div class=\"ingroups\">");
5377 }
5378 bool first=true;
5379 for (const auto &gd : d->partOfGroups())
5380 {
5381 if (!first) { ol.writeString(" &#124; "); } else first=false;
5383 {
5384 ol.writeString(" &raquo; ");
5385 }
5386 ol.writeObjectLink(gd->getReference(),gd->getOutputFileBase(),QCString(),gd->groupTitle());
5387 }
5388 if (root)
5389 {
5390 // add module as a group to the file as well
5391 if (mod)
5392 {
5393 if (!first) { ol.writeString(" &#124; "); } else first=false;
5394 ol.writeString(theTranslator->trModule(false,true)+" ");
5396 mod->displayName());
5397 }
5398 ol.writeString("</div>");
5400 }
5401 return true;
5402 }
5403 return false;
5404}

References OutputList::disableAllBut, Definition::displayName, FALSE, findModuleDef, Definition::getOutputFileBase, Definition::getReference, Html, Definition::partOfGroups, OutputList::popGeneratorState, OutputList::pushGeneratorState, recursivelyAddGroupListToTitle, theTranslator, OutputList::writeObjectLink and OutputList::writeString.

Referenced by addGroupListToTitle and recursivelyAddGroupListToTitle.

relativePathToRoot()

QCString relativePathToRoot (const QCString & name)

Definition at line 4096 of file util.cpp.

4097{
4098 QCString result;
4099 if (Config_getBool(CREATE_SUBDIRS))
4100 {
4101 if (name.isEmpty())
4102 {
4103 return REL_PATH_TO_ROOT;
4104 }
4105 else
4106 {
4107 int i = name.findRev('/');
4108 if (i!=-1)
4109 {
4110 result=REL_PATH_TO_ROOT;
4111 }
4112 }
4113 }
4114 return result;
4115}

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

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

removeAnonymousScopes()

QCString removeAnonymousScopes (const QCString & str)

Removes all anonymous scopes from string s Possible examples:

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

Definition at line 173 of file util.cpp.

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

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

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

removeEmptyLines()

QCString removeEmptyLines (const QCString & s)

Definition at line 7101 of file util.cpp.

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

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

Referenced by substituteHtmlKeywords and substituteLatexKeywords.

removeLongPathMarker()

QCString removeLongPathMarker (QCString path)

Definition at line 299 of file util.cpp.

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

References QCString::mid and QCString::startsWith.

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

removeRedundantWhiteSpace()

QCString removeRedundantWhiteSpace (const QCString & s)

Definition at line 579 of file util.cpp.

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

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

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

replaceAnonymousScopes()

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

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}

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

Referenced by addMemberFunction, findGlobalMember and generateDEFForMember.

replaceColorMarkers()

QCString replaceColorMarkers (const QCString & str)

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

Definition at line 6323 of file util.cpp.

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

References Config_getInt, end, hex, HEXTONUM, ColoredImage::hsl2rgb, QCString::isEmpty and QCString::str.

Referenced by ResourceMgr::copyResourceAs, fillColorStyleMaps, HtmlGenerator::init and writeDefaultStyleSheet.

resolveLink()

bool resolveLink (const QCString & scName, const QCString & lr, bool inSeeBlock, const Definition ** resContext, QCString & resAnchor, SrcLangExt lang, const QCString & prefix)

Definition at line 3246 of file util.cpp.

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

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.

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

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

Referenced by DocParser::handleLinkedWord, resolveLink and resolveRef.

resolveTypeDef()

QCString resolveTypeDef (const Definition * context, const QCString & qualifiedName, const Definition ** typedefContext)

Definition at line 385 of file util.cpp.

385QCString resolveTypeDef(const Definition *context,const QCString &qualifiedName,
386 const Definition **typedefContext)
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;
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}

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.

882bool rightScopeMatch(const QCString &scope, const QCString &name)
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 6924 of file util.cpp.

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

References SelectionMarkerInfo::beginLen, SelectionMarkerInfo::beginStr, SelectionMarkerInfo::closeLen, SelectionMarkerInfo::closeStr, QCString::data, SelectionMarkerInfo::endLen, SelectionMarkerInfo::endStr, QCString::isEmpty, QCString::length, SelectionMarkerInfo::markerChar, qstrlen, qstrncmp and QCString::reserve.

Referenced by substituteHtmlKeywords and substituteLatexKeywords.

showDate()

QCString showDate (const QCString & fmt)
static

Definition at line 3645 of file util.cpp.

3646{
3647 // get the current date and time
3648 std::tm dat{};
3649 int specFormat=0;
3650 QCString specDate = "";
3651 QCString err = dateTimeFromString(specDate,dat,specFormat);
3652
3653 // do the conversion
3654 int usedFormat=0;
3655 return formatDateTime(fmt,dat,usedFormat);
3656}

References dateTimeFromString, err and formatDateTime.

Referenced by substituteKeywords.

showFileDefMatches()

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

Definition at line 3542 of file util.cpp.

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

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

Referenced by addIncludeFile, buildFileList, DocParser::findAndCopyImage, DocDiaFile::parse, DocDotFile::parse, DocMscFile::parse, DocPlantUmlFile::parse, readIncludeFile, DocParser::readTextFileByName and readTextFileByName.

split()

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

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

Referenced by VHDLOutlineParser::addProto, VHDLOutlineParser::addVhdlType, FlowChart::alignCommentNode, anonymous{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.

split()

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

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

Reference end.

stackTrace()

void stackTrace ()

Definition at line 5987 of file util.cpp.

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

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

stripAnonymousNamespaceScope()

QCString stripAnonymousNamespaceScope (const QCString & s)

Definition at line 242 of file util.cpp.

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

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

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

stripDeclKeywords()

QCString stripDeclKeywords (const QCString & s)
static

Definition at line 1562 of file util.cpp.

1563{
1564 int i=s.find(" class ");
1565 if (i!=-1) return s.left(i)+s.mid(i+6);
1566 i=s.find(" typename ");
1567 if (i!=-1) return s.left(i)+s.mid(i+9);
1568 i=s.find(" union ");
1569 if (i!=-1) return s.left(i)+s.mid(i+6);
1570 i=s.find(" struct ");
1571 if (i!=-1) return s.left(i)+s.mid(i+7);
1572 return s;
1573}

References QCString::find, QCString::left and QCString::mid.

Referenced by getCanonicalTypeForIdentifier.

stripExtension()

QCString stripExtension (const QCString & fName)

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 & p, const StringVector & l)
static

Definition at line 310 of file util.cpp.

311{
312 // look at all the strings in the list and strip the longest match
313 QCString potential;
315 size_t length = 0;
316 for (const auto &s : l)
317 {
318 QCString prefix = s.c_str();
319 if (prefix.length() > length &&
320 qstricmp(path.left(prefix.length()),prefix)==0) // case insensitive compare
321 {
322 length = prefix.length();
323 potential = path.right(path.length()-prefix.length());
324 }
325 }
326 if (length>0) return potential;
327 return path;
328}

References QCString::left, QCString::length, prefix, qstricmp, removeLongPathMarker and QCString::right.

Referenced by Config::checkAndCorrect, DirDefImpl::DirDefImpl, FileDefImpl::FileDefImpl, generateAnonymousAnchor, generateXMLForClass, generateXMLForConcept, generateXMLForDir, generateXMLForFile, generateXMLForMember, generateXMLForModule, generateXMLForNamespace, generateXMLForPage, handleFileInfoResult, insertPath, markdownFileNameToId, MarkdownOutlineParser::parseInput, ModuleManager::resolveImports, ClassDefImpl::showUsedFiles, stripFromIncludePath, stripFromPath, ModuleDefImpl::writeFiles, writeSingleFileIndex, DirDefImpl::writeTagFile and FileDefImpl::writeTagFile.

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)

Definition at line 6466 of file util.cpp.

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

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

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

stripIndentationVerbatim()

void stripIndentationVerbatim (QCString & doc, const int indentationLevel)

Definition at line 6554 of file util.cpp.

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

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

stripIrrelevantConstVolatile()

void stripIrrelevantConstVolatile (QCString & s)

According to the C++ spec and Ivan Vecerina:

Parameter declarations that differ only in the presence or absence of const and/or volatile are equivalent.

So the following example, show what is stripped by this routine for const. The same is done for volatile.

For Java code we also strip the "final" keyword, see bug 765070.

 const T param -> T param // not relevant
 const T& param -> const T& param // const needed
 T* const param -> T* param // not relevant
 const T* param -> const T* param // const needed

Definition at line 1552 of file util.cpp.

1553{
1554 //printf("stripIrrelevantConstVolatile(%s)=",qPrint(s));
1555 stripIrrelevantString(s,"const");
1556 stripIrrelevantString(s,"volatile");
1557 stripIrrelevantString(s,"final");
1558 //printf("%s\n",qPrint(s));
1559}

Reference stripIrrelevantString.

Referenced by extractCanonicalType and matchArgument2.

stripIrrelevantString()

void stripIrrelevantString (QCString & target, const QCString & str)
static

Definition at line 1501 of file util.cpp.

1501static void stripIrrelevantString(QCString &target,const QCString &str)
1502{
1503 if (target==str) { target.clear(); return; }
1504 int i=0,p=0;
1505 int l=static_cast<int>(str.length());
1506 bool changed=FALSE;
1507 while ((i=target.find(str,p))!=-1)
1508 {
1509 bool isMatch = (i==0 || !isId(target.at(i-1))) && // not a character before str
1510 (i+l==static_cast<int>(target.length()) || !isId(target.at(i+l))); // not a character after str
1511 if (isMatch)
1512 {
1513 int i1=target.find('*',i+l);
1514 int i2=target.find('&',i+l);
1515 if (i1==-1 && i2==-1)
1516 {
1517 // strip str from target at index i
1518 target=target.left(i)+target.right(target.length()-i-l);
1519 changed=TRUE;
1520 i-=l;
1521 }
1522 else if ((i1!=-1 && i<i1) || (i2!=-1 && i<i2)) // str before * or &
1523 {
1524 // move str to front
1525 target=str+" "+target.left(i)+target.right(target.length()-i-l);
1526 changed=TRUE;
1527 i++;
1528 }
1529 }
1530 p = i+l;
1531 }
1532 if (changed) target=target.stripWhiteSpace();
1533}

References QCString::at, QCString::clear, FALSE, QCString::find, isId, QCString::left, QCString::length, QCString::right, QCString::stripWhiteSpace and TRUE.

Referenced by stripIrrelevantConstVolatile.

stripLeadingAndTrailingEmptyLines()

QCString stripLeadingAndTrailingEmptyLines (const QCString & s, int & docLine)

Special version of QCString::stripWhiteSpace() that only strips completely blank lines.

Parameters
s

the string to be stripped

docLine

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

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

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

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

stripPath()

QCString stripPath (const QCString & s)

Definition at line 5465 of file util.cpp.

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

References QCString::findRev and QCString::mid.

Referenced by LatexGenerator::addLabel, anonymous{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 4296 of file util.cpp.

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

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

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

References QCString::at, QCString::find, getClass, Definition::isArtificial, QCString::length, mergeScopes, QCString::mid and QCString::right.

Referenced by addClassToContext, addMemberFunction, addVariable, buildFunctionList, computeTemplateClassRelations, extractClassName, findMember, findScopeFromQualifiedName, findUsingDeclImports, getCanonicalTypeForIdentifier, getDefsOld, SymbolResolver::Private::getResolvedSymbolRec, SymbolResolver::Private::getResolvedTypeRec, SymbolResolver::Private::newResolveTypedef and resolveLink.

substituteKeywords()

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

Definition at line 3572 of file util.cpp.

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

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

Referenced by substituteHtmlKeywords, substituteKeywords and substituteLatexKeywords.

substituteKeywords()

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

Definition at line 3724 of file util.cpp.

3724QCString substituteKeywords(const QCString &file,const QCString &s,const QCString &title,
3725 const QCString &projName,const QCString &projNum,const QCString &projBrief)
3726{
3727 return substituteKeywords(file,s,
3728 {
3729 // keyword value getter
3730 { "$title", [&]() { return !title.isEmpty() ? title : projName; } },
3731 { "$datetime", [&]() { return dateToString(DateTimeType::DateTime); } },
3732 { "$date", [&]() { return dateToString(DateTimeType::Date); } },
3733 { "$time", [&]() { return dateToString(DateTimeType::Time); } },
3734 { "$year", [&]() { return yearToString(); } },
3735 { "$doxygenversion", [&]() { return getDoxygenVersion(); } },
3736 { "$projectname", [&]() { return projName; } },
3737 { "$projectnumber", [&]() { return projNum; } },
3738 { "$projectbrief", [&]() { return projBrief; } },
3739 { "$projectlogo", [&]() { return stripPath(projectLogoFile()); } },
3740 { "$logosize", [&]() { return projectLogoSize(); } },
3741 { "$projecticon", [&]() { return stripPath(Config_getString(PROJECT_ICON)); } },
3742 { "$langISO", [&]() { return theTranslator->trISOLang(); } },
3743 { "$showdate", [&](const QCString &fmt) { return showDate(fmt); } }
3744 });
3745}

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

substituteTemplateArgumentsInString()

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

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

Definition at line 4868 of file util.cpp.

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

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

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

tempArgListToString()

QCString tempArgListToString (const ArgumentList & al, SrcLangExt lang, bool includeDefault)

Definition at line 1247 of file util.cpp.

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

References ArgumentList::empty, isId, removeRedundantWhiteSpace and QCString::right.

Referenced by addMemberFunction, ClassDefImpl::className, findTemplateInstanceRelation, makeQualifiedNameWithTemplateParameters, searchTemplateSpecs and writeDefArgumentList.

transcodeCharacterBuffer()

void transcodeCharacterBuffer (const QCString & fileName, std::string & contents, const QCString & inputEncoding, const QCString & outputEncoding)
static

Definition at line 6015 of file util.cpp.

6015static void transcodeCharacterBuffer(const QCString &fileName,std::string &contents,
6016 const QCString &inputEncoding,const QCString &outputEncoding)
6017{
6018 if (inputEncoding.isEmpty() || outputEncoding.isEmpty()) return; // no encoding specified
6019 if (qstricmp(inputEncoding,outputEncoding)==0) return; // input encoding same as output encoding
6020 void *cd = portable_iconv_open(outputEncoding.data(),inputEncoding.data());
6021 if (cd==reinterpret_cast<void *>(-1))
6022 {
6023 term("unsupported character conversion: '{}'->'{}': {}\n"
6024 "Check the INPUT_ENCODING setting in the config file!\n",
6025 inputEncoding,outputEncoding,strerror(errno));
6026 }
6027 size_t iLeft = contents.size();
6028 const char *srcPtr = contents.data();
6029 size_t tmpBufSize = contents.size()*4+1;
6030 size_t oLeft = tmpBufSize;
6031 std::string tmpBuf;
6032 tmpBuf.resize(tmpBufSize);
6033 char *dstPtr = tmpBuf.data();
6034 size_t newSize=0;
6035 if (!portable_iconv(cd, &srcPtr, &iLeft, &dstPtr, &oLeft))
6036 {
6037 newSize = tmpBufSize-oLeft;
6038 tmpBuf.resize(newSize);
6039 std::swap(contents,tmpBuf);
6040 //printf("iconv: input size=%d output size=%d\n[%s]\n",size,newSize,qPrint(srcBuf));
6041 }
6042 else
6043 {
6044 term("{}: failed to translate characters from {} to {}: check INPUT_ENCODING\n",
6045 fileName,inputEncoding,outputEncoding);
6046 }
6048}

References QCString::data, QCString::isEmpty, portable_iconv, portable_iconv_close, portable_iconv_open, qstricmp and term.

Referenced by readInputFile.

transcodeCharacterStringToUTF8()

bool transcodeCharacterStringToUTF8 (std::string & input, const char * inputEncoding)

Definition at line 1404 of file util.cpp.

1404bool transcodeCharacterStringToUTF8(std::string &input, const char *inputEncoding)
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}

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.

trimBaseClassScope()

void trimBaseClassScope (const BaseClassList & bcl, QCString & s, int level=0)

Definition at line 1479 of file util.cpp.

1479void trimBaseClassScope(const BaseClassList &bcl,QCString &s,int level=0)
1480{
1481 //printf("trimBaseClassScope level=%d '%s'\n",level,qPrint(s));
1482 for (const auto &bcd : bcl)
1483 {
1484 ClassDef *cd=bcd.classDef;
1485 //printf("Trying class %s\n",qPrint(cd->name()));
1486 int spos=s.find(cd->name()+"::");
1487 if (spos!=-1)
1488 {
1489 s = s.left(spos)+s.right(
1490 s.length()-spos-cd->name().length()-2
1491 );
1492 }
1493 //printf("base class '%s'\n",qPrint(cd->name()));
1494 if (!cd->baseClasses().empty())
1495 {
1496 trimBaseClassScope(cd->baseClasses(),s,level+1);
1497 }
1498 }
1499}

References ClassDef::baseClasses, QCString::find, QCString::left, QCString::length, Definition::name, QCString::right and trimBaseClassScope.

Referenced by trimBaseClassScope.

unescapeCharsInString()

QCString unescapeCharsInString (const QCString & s)

Definition at line 3934 of file util.cpp.

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

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

updateColumnCount()

size_t updateColumnCount (const char * s, size_t col)

Definition at line 7395 of file util.cpp.

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

References Config_getInt and getUTF8CharNumBytes.

Referenced by HtmlCodeGenerator::codify, LatexCodeGenerator::codify, ManCodeGenerator::codify, RTFCodeGenerator::codify, writeDocbookCodeString and writeXMLCodeString.

updateLanguageMapping()

bool updateLanguageMapping (const QCString & extension, const QCString & language)

Definition at line 5617 of file util.cpp.

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

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

6300{
6301 int hue = Config_getInt(HTML_COLORSTYLE_HUE);
6302 int sat = Config_getInt(HTML_COLORSTYLE_SAT);
6303 int gamma = Config_getInt(HTML_COLORSTYLE_GAMMA);
6304 while (data->name)
6305 {
6306 QCString fileName = dir+"/"+data->name;
6307 ColoredImage img(data->width,data->height,data->content,data->alpha,
6308 sat,hue,gamma);
6309 if (!img.save(fileName))
6310 {
6311 fprintf(stderr,"Warning: Cannot open file %s for writing\n",data->name);
6312 }
6313 Doxygen::indexList->addImageFile(data->name);
6314 data++;
6315 }
6316}

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

writeExamples()

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

Definition at line 1128 of file util.cpp.

1129{
1130 auto replaceFunc = [&list,&ol](size_t entryIndex)
1131 {
1132 const auto &e = list[entryIndex];
1137 // link for Html / man
1138 //printf("writeObjectLink(file=%s)\n",qPrint(e->file));
1139 ol.writeObjectLink(QCString(),e.file,e.anchor,e.name);
1141
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);
1149 };
1150
1151 writeMarkerList(ol, theTranslator->trWriteList(static_cast<int>(list.size())).str(), list.size(), replaceFunc);
1152
1153 ol.writeString(".");
1154}

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.

1104void writeMarkerList(OutputList &ol,const std::string &markerText,size_t numMarkers,
1105 std::function<void(size_t)> replaceFunc)
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}

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

Variables

constScope

const char constScope[] = { 'c', 'o', 'n', 's', 't', ':' }
static

Definition at line 532 of file util.cpp.

532static const char constScope[] = { 'c', 'o', 'n', 's', 't', ':' };

Referenced by removeRedundantWhiteSpace.

g_charAroundSpace

CharAroundSpace g_charAroundSpace
static

Definition at line 576 of file util.cpp.

Referenced by removeRedundantWhiteSpace.

g_docCache

std::unordered_map<std::string,QCString> g_docCache
static

Definition at line 5929 of file util.cpp.

5929static std::unordered_map<std::string,QCString> g_docCache;

Referenced by parseCommentAsHtml.

g_docCacheMutex

std::mutex g_docCacheMutex
static

Definition at line 5928 of file util.cpp.

5928static std::mutex g_docCacheMutex;

Referenced by parseCommentAsHtml.

g_extLookup

std::unordered_map<std::string,SrcLangExt> g_extLookup
static

Definition at line 5583 of file util.cpp.

5583static std::unordered_map<std::string,SrcLangExt> g_extLookup;

Referenced by getLanguageFromFileName and updateLanguageMapping.

g_findFileDefCache

Cache< std::string, FindFileCacheElem > g_findFileDefCache(5000)
static

Definition at line 3412 of file util.cpp.

Referenced by findFileDef.

g_findFileDefMutex

std::mutex g_findFileDefMutex
static

Definition at line 3414 of file util.cpp.

3414static std::mutex g_findFileDefMutex;

Referenced by findFileDef.

g_lang2extMap

std::vector<Lang2ExtMap> g_lang2extMap
static
Initialiser
= { { "idl", "c", SrcLangExt::IDL, ".idl" }, { "java", "c", SrcLangExt::Java, ".java"}, { "javascript", "c", SrcLangExt::JS, ".js" }, { "csharp", "c", SrcLangExt::CSharp, ".cs" }, { "d", "c", SrcLangExt::D, ".d" }, { "php", "c", SrcLangExt::PHP, ".php" }, { "objective-c", "c", SrcLangExt::ObjC, ".m" }, { "c", "c", SrcLangExt::Cpp, ".c" }, { "c++", "c", SrcLangExt::Cpp, ".cpp" }, { "slice", "c", SrcLangExt::Slice, ".ice" }, { "python", "python", SrcLangExt::Python, ".py" }, { "fortran", "fortran", SrcLangExt::Fortran, ".f" }, { "fortranfree", "fortranfree", SrcLangExt::Fortran, ".f90" }, { "fortranfixed", "fortranfixed", SrcLangExt::Fortran, ".f" }, { "vhdl", "vhdl", SrcLangExt::VHDL, ".vhdl"}, { "xml", "xml", SrcLangExt::XML, ".xml" }, { "sql", "sql", SrcLangExt::SQL, ".sql" }, { "md", "md", SrcLangExt::Markdown, ".md" }, { "lex", "lex", SrcLangExt::Lex, ".l" }, }

Definition at line 5593 of file util.cpp.

5593static std::vector<Lang2ExtMap> g_lang2extMap =
5594{
5595// language parser parser option
5596 { "idl", "c", SrcLangExt::IDL, ".idl" },
5597 { "java", "c", SrcLangExt::Java, ".java"},
5598 { "javascript", "c", SrcLangExt::JS, ".js" },
5599 { "csharp", "c", SrcLangExt::CSharp, ".cs" },
5600 { "d", "c", SrcLangExt::D, ".d" },
5601 { "php", "c", SrcLangExt::PHP, ".php" },
5602 { "objective-c", "c", SrcLangExt::ObjC, ".m" },
5603 { "c", "c", SrcLangExt::Cpp, ".c" },
5604 { "c++", "c", SrcLangExt::Cpp, ".cpp" },
5605 { "slice", "c", SrcLangExt::Slice, ".ice" },
5606 { "python", "python", SrcLangExt::Python, ".py" },
5607 { "fortran", "fortran", SrcLangExt::Fortran, ".f" },
5608 { "fortranfree", "fortranfree", SrcLangExt::Fortran, ".f90" },
5609 { "fortranfixed", "fortranfixed", SrcLangExt::Fortran, ".f" },
5610 { "vhdl", "vhdl", SrcLangExt::VHDL, ".vhdl"},
5611 { "xml", "xml", SrcLangExt::XML, ".xml" },
5612 { "sql", "sql", SrcLangExt::SQL, ".sql" },
5613 { "md", "md", SrcLangExt::Markdown, ".md" },
5614 { "lex", "lex", SrcLangExt::Lex, ".l" },
5615};

Referenced by getLanguageFromCodeLang and updateLanguageMapping.

g_matchArgsMutex

std::mutex g_matchArgsMutex
static

Definition at line 1851 of file util.cpp.

1851static std::mutex g_matchArgsMutex;

Referenced by matchArgument2.

g_usedNames

std::unordered_map<std::string,int> g_usedNames
static

Definition at line 4011 of file util.cpp.

4011static std::unordered_map<std::string,int> g_usedNames;

Referenced by convertNameToFile.

g_usedNamesCount

int g_usedNamesCount =1
static

Definition at line 4013 of file util.cpp.

4013static int g_usedNamesCount=1;

Referenced by convertNameToFile.

g_usedNamesMutex

std::mutex g_usedNamesMutex
static

Definition at line 4012 of file util.cpp.

4012static std::mutex g_usedNamesMutex;

Referenced by convertNameToFile.

hex

const char* hex = "0123456789ABCDEF"
static

Definition at line 98 of file util.cpp.

98static const char *hex = "0123456789ABCDEF";

maxInheritanceDepth

const int maxInheritanceDepth = 100000

Definition at line 157 of file util.cpp.

157const int maxInheritanceDepth = 100000;

Referenced by getDefsOld, ClassDefImpl::getMemberByName and minClassDistance.

operatorScope

const char operatorScope[] = { 'o', 'p', 'e', 'r', 'a', 't', 'o', 'r', '?', '?', '?' }
static

Definition at line 535 of file util.cpp.

535static const char operatorScope[] = { 'o', 'p', 'e', 'r', 'a', 't', 'o', 'r', '?', '?', '?' };

Referenced by removeRedundantWhiteSpace.

virtualScope

const char virtualScope[] = { 'v', 'i', 'r', 't', 'u', 'a', 'l', ':' }
static

Definition at line 534 of file util.cpp.

534static const char virtualScope[] = { 'v', 'i', 'r', 't', 'u', 'a', 'l', ':' };

Referenced by removeRedundantWhiteSpace.

volatileScope

const char volatileScope[] = { 'v', 'o', 'l', 'a', 't', 'i', 'l', 'e', ':' }
static

Definition at line 533 of file util.cpp.

533static const char volatileScope[] = { 'v', 'o', 'l', 'a', 't', 'i', 'l', 'e', ':' };

Referenced by removeRedundantWhiteSpace.

Macro Definitions

ENABLE_TRACINGSUPPORT

#define ENABLE_TRACINGSUPPORT   0

Definition at line 82 of file util.cpp.

82#define ENABLE_TRACINGSUPPORT 0

HEXTONUM

#define HEXTONUM(x)   ...
Value
(((x)>='0' && (x)<='9') ? ((x)-'0') : \ ((x)>='a' && (x)<='f') ? ((x)-'a'+10) : \ ((x)>='A' && (x)<='F') ? ((x)-'A'+10) : 0)

Definition at line 6343 of file util.cpp.

Referenced by replaceColorMarkers.

MATCH

#define MATCH

Definition at line 1854 of file util.cpp.

1854#define MATCH

Referenced by matchArgument2 and matchArguments2.

NOMATCH

#define NOMATCH

Definition at line 1855 of file util.cpp.

1855#define NOMATCH

Referenced by matchArgument2 and matchArguments2.

REL_PATH_TO_ROOT

#define REL_PATH_TO_ROOT   "../../"

Definition at line 96 of file util.cpp.

96#define REL_PATH_TO_ROOT "../../"

Referenced by relativePathToRoot.


Generated via doxygen2docusaurus by Doxygen 1.14.0.