Doxygen
Loading...
Searching...
No Matches
util.cpp File Reference
#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 "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"
+ Include dependency graph for util.cpp:

Go to the source code of this file.

Classes

struct  CharAroundSpace
 
struct  CharAroundSpace::CharElem
 
struct  FindFileCacheElem
 Cache element for the file name to FileDef mapping cache. More...
 
struct  Lang2ExtMap
 

Macros

#define ENABLE_TRACINGSUPPORT   0
 
#define REL_PATH_TO_ROOT   "../../"
 
#define MATCH
 
#define NOMATCH
 
#define HEXTONUM(x)
 

Functions

QCString removeAnonymousScopes (const QCString &str)
 
QCString replaceAnonymousScopes (const QCString &s, const QCString &replacement)
 
QCString stripAnonymousNamespaceScope (const QCString &s)
 
void writePageRef (OutputList &ol, const QCString &cn, const QCString &mn)
 
QCString generateMarker (int id)
 
QCString removeLongPathMarker (QCString path)
 
static QCString stripFromPath (const QCString &p, const StringVector &l)
 
QCString stripFromPath (const QCString &path)
 
QCString stripFromIncludePath (const QCString &path)
 
EntryType guessSection (const QCString &name)
 
QCString resolveTypeDef (const Definition *context, const QCString &qualifiedName, const Definition **typedefContext)
 
QCString removeRedundantWhiteSpace (const QCString &s)
 
int findParameterList (const QCString &name)
 Returns the position in the string where a function parameter list begins, or -1 if one is not found.
 
bool rightScopeMatch (const QCString &scope, const QCString &name)
 
bool leftScopeMatch (const QCString &scope, const QCString &name)
 
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)
 
 if (strLen >35 &&floatingIndex >30 &&autoBreak)
 
out writeString (part, keepSpaces)
 
 if (!insideString)
 
out writeString (lastPart, keepSpaces)
 
void writeMarkerList (OutputList &ol, const std::string &markerText, size_t numMarkers, std::function< void(size_t)> replaceFunc)
 
void writeExamples (OutputList &ol, const ExampleList &list)
 
QCString inlineArgListToDoc (const ArgumentList &al)
 
QCString inlineTemplateArgListToDoc (const ArgumentList &al)
 
QCString argListToString (const ArgumentList &al, bool useCanonicalType, bool showDefVals)
 
QCString tempArgListToString (const ArgumentList &al, SrcLangExt lang, bool includeDefault)
 
static void filterCRLF (std::string &contents)
 
static QCString getFilterFromList (const QCString &name, const StringVector &filterList, bool &found)
 
QCString getFileFilter (const QCString &name, bool isSourceCode)
 
bool transcodeCharacterStringToUTF8 (std::string &input, const char *inputEncoding)
 
QCString fileToString (const QCString &name, bool filter, bool isSourceCode)
 
void trimBaseClassScope (const BaseClassList &bcl, QCString &s, int level=0)
 
static void stripIrrelevantString (QCString &target, const QCString &str)
 
void stripIrrelevantConstVolatile (QCString &s)
 
static QCString stripDeclKeywords (const QCString &s)
 
static QCString extractCanonicalType (const Definition *d, const FileDef *fs, QCString type, SrcLangExt lang)
 
static QCString getCanonicalTemplateSpec (const Definition *d, const FileDef *fs, const QCString &spec, SrcLangExt lang)
 
static QCString getCanonicalTypeForIdentifier (const Definition *d, const FileDef *fs, const QCString &word, SrcLangExt lang, QCString *tSpec, int count=0)
 
static QCString extractCanonicalArgType (const Definition *d, const FileDef *fs, const Argument &arg, SrcLangExt lang)
 
static bool matchCanonicalTypes (const Definition *srcScope, const FileDef *srcFileScope, const QCString &srcType, const Definition *dstScope, const FileDef *dstFileScope, const QCString &dstType, SrcLangExt lang)
 
static bool matchArgument2 (const Definition *srcScope, const FileDef *srcFileScope, Argument &srcA, const Definition *dstScope, const FileDef *dstFileScope, Argument &dstA, SrcLangExt lang)
 
bool matchArguments2 (const Definition *srcScope, const FileDef *srcFileScope, const ArgumentList *srcAl, const Definition *dstScope, const FileDef *dstFileScope, const ArgumentList *dstAl, bool checkCV, SrcLangExt lang)
 
void mergeArguments (ArgumentList &srcAl, ArgumentList &dstAl, bool forceNameOverwrite)
 
bool matchTemplateArguments (const ArgumentList &srcAl, const ArgumentList &dstAl)
 
static void findMembersWithSpecificName (const MemberName *mn, const QCString &args, bool checkStatics, const FileDef *currentFile, bool checkCV, std::vector< const MemberDef * > &members)
 
GetDefResult getDefsNew (const GetDefInput &input)
 
GetDefResult getDefsOld (const GetDefInput &input)
 
GetDefResult getDefs (const GetDefInput &input)
 
static bool getScopeDefs (const QCString &docScope, const QCString &scope, ClassDef *&cd, ConceptDef *&cnd, NamespaceDef *&nd, ModuleDef *&modd)
 
static bool isLowerCase (QCString &s)
 
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)
 
QCString linkToText (SrcLangExt lang, const QCString &link, bool isFileName)
 
bool resolveLink (const QCString &scName, const QCString &lr, bool, const Definition **resContext, QCString &resAnchor, SrcLangExt lang, const QCString &prefix)
 
void generateFileRef (OutputList &ol, const QCString &name, const QCString &text)
 
FileDeffindFileDef (const FileNameLinkedMap *fnMap, const QCString &n, bool &ambig)
 
QCString findFilePath (const QCString &file, bool &ambig)
 
QCString showFileDefMatches (const FileNameLinkedMap *fnMap, const QCString &n)
 
QCString substituteKeywords (const QCString &s, const KeywordSubstitutionList &keywords)
 
static QCString showDate (const QCString &fmt)
 
QCString projectLogoFile ()
 
static QCString projectLogoSize ()
 
QCString substituteKeywords (const QCString &s, const QCString &title, const QCString &projName, const QCString &projNum, const QCString &projBrief)
 
int getPrefixIndex (const QCString &name)
 
bool getCaseSenseNames ()
 
QCString escapeCharsInString (const QCString &name, bool allowDots, bool allowUnderscore)
 
QCString unescapeCharsInString (const QCString &s)
 
QCString convertNameToFile (const QCString &name, bool allowDots, bool allowUnderscore)
 
QCString generateAnonymousAnchor (const QCString &fileName, int count)
 
QCString relativePathToRoot (const QCString &name)
 
QCString determineAbsoluteIncludeName (const QCString &curFile, const QCString &incFileName)
 
void createSubDirs (const Dir &d)
 
void clearSubDirs (const Dir &d)
 
void extractNamespaceName (const QCString &scopeName, QCString &className, QCString &namespaceName, bool allowEmptyClass)
 
QCString insertTemplateSpecifierInScope (const QCString &scope, const QCString &templ)
 
QCString stripScope (const QCString &name)
 
QCString convertToId (const QCString &s)
 
QCString correctId (const QCString &s)
 
QCString convertToXML (const QCString &s, bool keepEntities)
 
QCString convertToHtml (const QCString &s, bool keepEntities)
 
QCString convertToJSString (const QCString &s)
 
QCString convertCharEntitiesToUTF8 (const QCString &str)
 
QCString getOverloadDocs ()
 
void addMembersToMemberGroup (MemberList *ml, MemberGroupList *pMemberGroups, const Definition *context)
 
int extractClassNameFromType (const QCString &type, int &pos, QCString &name, QCString &templSpec, SrcLangExt lang)
 
QCString normalizeNonTemplateArgumentsInString (const QCString &name, const Definition *context, const ArgumentList &formalArgs)
 
QCString substituteTemplateArgumentsInString (const QCString &nm, const ArgumentList &formalArgs, const ArgumentList *actualArgs)
 
QCString stripTemplateSpecifiersFromScope (const QCString &fullName, bool parentOnly, QCString *pLastScopeStripped, QCString scopeName, bool allowArtificial)
 
QCString mergeScopes (const QCString &leftScope, const QCString &rightScope)
 
int getScopeFragment (const QCString &s, int p, int *l)
 
PageDefaddRelatedPage (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)
 
void addRefItem (const RefItemVector &sli, const QCString &key, const QCString &prefix, const QCString &name, const QCString &title, const QCString &args, const Definition *scope)
 
static ModuleDeffindModuleDef (const Definition *d)
 
static bool recursivelyAddGroupListToTitle (OutputList &ol, const Definition *d, bool root)
 
void addGroupListToTitle (OutputList &ol, const Definition *d)
 
bool checkExtension (const QCString &fName, const QCString &ext)
 
void addHtmlExtensionIfMissing (QCString &fName)
 
QCString stripExtensionGeneral (const QCString &fName, const QCString &ext)
 
QCString stripExtension (const QCString &fName)
 
QCString stripPath (const QCString &s)
 
bool containsWord (const QCString &str, const char *word)
 returns TRUE iff string s contains word w
 
bool findAndRemoveWord (QCString &sentence, const char *word)
 removes occurrences of whole word from sentence, while keeps internal spaces and reducing multiple sequences of spaces.
 
QCString stripLeadingAndTrailingEmptyLines (const QCString &s, int &docLine)
 Special version of QCString::stripWhiteSpace() that only strips completely blank lines.
 
bool updateLanguageMapping (const QCString &extension, const QCString &language)
 
void initDefaultExtensionMapping ()
 
void addCodeOnlyMappings ()
 
SrcLangExt getLanguageFromFileName (const QCString &fileName, SrcLangExt defLang)
 
SrcLangExt getLanguageFromCodeLang (QCString &fileName)
 Routine to handle the language attribute of the \code command.
 
QCString getFileNameExtension (const QCString &fn)
 
static MemberDefgetMemberFromSymbol (const Definition *scope, const FileDef *fileScope, const QCString &n)
 
bool checkIfTypedef (const Definition *scope, const FileDef *fileScope, const QCString &n)
 
static int nextUTF8CharPosition (const QCString &utf8Str, uint32_t len, uint32_t startPos)
 
QCString parseCommentAsText (const Definition *scope, const MemberDef *md, const QCString &doc, const QCString &fileName, int lineNr)
 
void writeTypeConstraints (OutputList &ol, const Definition *d, const ArgumentList &al)
 
void stackTrace ()
 
static void transcodeCharacterBuffer (const QCString &fileName, std::string &contents, const QCString &inputEncoding, const QCString &outputEncoding)
 
bool readInputFile (const QCString &fileName, std::string &contents, bool filter, bool isSourceCode)
 read a file name fileName and optionally filter and transcode it
 
QCString filterTitle (const QCString &title)
 
template<class PatternList, class PatternElem, typename PatternGet = QCString(*)(const PatternElem &)>
bool genericPatternMatch (const FileInfo &fi, const PatternList &patList, PatternElem &elem, PatternGet getter)
 
bool patternMatch (const FileInfo &fi, const StringVector &patList)
 
QCString getEncoding (const FileInfo &fi)
 
QCString externalLinkTarget (const bool parent)
 
QCString createHtmlUrl (const QCString &relPath, const QCString &ref, bool href, bool isLocalFile, const QCString &targetFileName, const QCString &anchor)
 
QCString externalRef (const QCString &relPath, const QCString &ref, bool href)
 
void writeColoredImgData (const QCString &dir, ColoredImgDataItem data[])
 Writes the intensity only bitmap represented by data as an image to directory dir using the colors defined by HTML_COLORSTYLE_*.
 
QCString replaceColorMarkers (const QCString &str)
 Replaces any markers of the form ##AA in input string str by new markers of the form #AABBCC, where #AABBCC represents a valid color, based on the intensity represented by hex number AA and the current HTML_COLORSTYLE_* settings.
 
bool copyFile (const QCString &src, const QCString &dest)
 Copies the contents of file with name src to the newly created file with name dest.
 
int lineBlock (const QCString &text, const QCString &marker)
 Returns the line number of the line following the line with the marker.
 
QCString langToString (SrcLangExt lang)
 Returns a string representation of lang.
 
QCString getLanguageSpecificSeparator (SrcLangExt lang, bool classScope)
 Returns the scope separator to use given the programming language lang.
 
bool isURL (const QCString &url)
 Checks whether the given url starts with a supported protocol.
 
QCString correctURL (const QCString &url, const QCString &relPath)
 Corrects URL url according to the relative path relPath.
 
bool protectionLevelVisible (Protection prot)
 
QCString stripIndentation (const QCString &s, bool skipFirstLine)
 
void stripIndentationVerbatim (QCString &doc, const int indentationLevel)
 
bool fileVisibleInIndex (const FileDef *fd, bool &genSourceFile)
 
QCString extractDirection (QCString &docs)
 Strip the direction part from docs and return it as a string in canonical form The input docs string can start with e.g.
 
void convertProtectionLevel (MemberListType inListType, Protection inProt, MemberListType *outListType1, MemberListType *outListType2)
 Computes for a given list type inListType, which are the the corresponding list type(s) in the base class that are to be added to this list.
 
bool mainPageHasTitle ()
 
QCString getDotImageExtension ()
 
bool openOutputFile (const QCString &outFile, std::ofstream &f)
 
static bool keyWordsFortranC (const char *contents)
 
bool recognizeFixedForm (const QCString &contents, FortranFormat format)
 
FortranFormat convertFileNameFortranParserCode (QCString fn)
 
QCString selectBlocks (const QCString &s, const SelectionBlockList &blockList, const SelectionMarkerInfo &markerInfo)
 remove disabled blocks and all block markers from s and return the result as a string
 
void checkBlocks (const QCString &s, const QCString fileName, const SelectionMarkerInfo &markerInfo)
 
QCString removeEmptyLines (const QCString &s)
 
StringVector split (const std::string &s, const std::string &delimiter)
 split input string s by string delimiter delimiter.
 
StringVector split (const std::string &s, const reg::Ex &delimiter)
 split input string s by regular expression delimiter delimiter.
 
int findIndex (const StringVector &sv, const std::string &s)
 find the index of a string in a vector of strings, returns -1 if the string could not be found
 
int findIndex (const std::string &s, const reg::Ex &re)
 find the index of the first occurrence of pattern re in a string s returns -1 if the pattern could not be found
 
std::string join (const StringVector &sv, const std::string &delimiter)
 create a string where the string in the vector are joined by the given delimiter
 
QCString integerToAlpha (int n, bool upper)
 
QCString integerToRoman (int n, bool upper)
 
QCString detab (const QCString &s, size_t &refIndent)
 
QCString getProjectId ()
 
int computeQualifiedIndex (const QCString &name)
 Return the index of the last :: in the string name that is still before the first <.
 
void mergeMemberOverrideOptions (MemberDefMutable *md1, MemberDefMutable *md2)
 
size_t updateColumnCount (const char *s, size_t col)
 
QCString mangleCSharpGenericName (const QCString &name)
 
QCString demangleCSharpGenericName (const QCString &name, const QCString &templArgs)
 

Variables

static const char * hex = "0123456789ABCDEF"
 
const int maxInheritanceDepth = 100000
 
static const char constScope [] = { 'c', 'o', 'n', 's', 't', ':' }
 
static const char volatileScope [] = { 'v', 'o', 'l', 'a', 't', 'i', 'l', 'e', ':' }
 
static const char virtualScope [] = { 'v', 'i', 'r', 't', 'u', 'a', 'l', ':' }
 
static const char operatorScope [] = { 'o', 'p', 'e', 'r', 'a', 't', 'o', 'r', '?', '?', '?' }
 
static CharAroundSpace g_charAroundSpace
 
 else
 
std::string_view word =txtStr.substr(newIndex,matchLen)
 
QCString matchWord = substitute(substitute(QCString(word),"\\","::"),".","::")
 
bool found =FALSE
 
 skipIndex =index=newIndex+matchLen
 
std::string_view lastPart = txtStr.substr(skipIndex)
 
static std::mutex g_matchArgsMutex
 
static Cache< std::string, FindFileCacheElemg_findFileDefCache (5000)
 
static std::mutex g_findFileDefMutex
 
static std::unordered_map< std::string, int > g_usedNames
 
static std::mutex g_usedNamesMutex
 
static int g_usedNamesCount =1
 
static std::unordered_map< std::string, SrcLangExtg_extLookup
 
static std::vector< Lang2ExtMapg_lang2extMap
 

Macro Definition Documentation

◆ ENABLE_TRACINGSUPPORT

#define ENABLE_TRACINGSUPPORT   0

Definition at line 81 of file util.cpp.

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

Referenced by replaceColorMarkers().

◆ MATCH

#define MATCH

Definition at line 1853 of file util.cpp.

Referenced by matchArgument2(), and matchArguments2().

◆ NOMATCH

#define NOMATCH

Definition at line 1854 of file util.cpp.

Referenced by matchArgument2(), and matchArguments2().

◆ REL_PATH_TO_ROOT

#define REL_PATH_TO_ROOT   "../../"

Definition at line 95 of file util.cpp.

Referenced by relativePathToRoot().

Function Documentation

◆ addCodeOnlyMappings()

void addCodeOnlyMappings ( )

Definition at line 5699 of file util.cpp.

5700{
5701 updateLanguageMapping(".xml", "xml");
5702 updateLanguageMapping(".sql", "sql");
5703}
bool updateLanguageMapping(const QCString &extension, const QCString &language)
Definition util.cpp:5600

References updateLanguageMapping().

Referenced by generateOutput().

◆ addGroupListToTitle()

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

◆ addHtmlExtensionIfMissing()

void addHtmlExtensionIfMissing ( QCString & fName)

Definition at line 5399 of file util.cpp.

5400{
5401 if (fName.isEmpty()) return;
5402 int i_fs = fName.findRev('/');
5403 int i_bs = fName.findRev('\\');
5404 int i = fName.find('.',std::max({ i_fs, i_bs ,0})); // search for . after path part
5405 if (i==-1)
5406 {
5408 }
5409}
static QCString htmlFileExtension
Definition doxygen.h:122
int find(char c, int index=0, bool cs=TRUE) const
Definition qcstring.cpp:43
bool isEmpty() const
Returns TRUE iff the string is empty.
Definition qcstring.h:150
int findRev(char c, int index=-1, bool cs=TRUE) const
Definition qcstring.cpp:91

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

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

◆ addMembersToMemberGroup()

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

Definition at line 4594 of file util.cpp.

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

References ASSERT, MemberList::container(), Definition::docFile(), end(), MemberGroup::insertMember(), Doxygen::memberGroupInfoMap, MemberVector::remove(), MemberDef::setMemberGroup(), and toMemberDefMutable().

◆ addRefItem()

void addRefItem ( const RefItemVector & sli,
const QCString & key,
const QCString & prefix,
const QCString & name,
const QCString & title,
const QCString & args,
const Definition * scope )

Definition at line 5302 of file util.cpp.

5305{
5306 //printf("addRefItem(sli=%d,key=%s,prefix=%s,name=%s,title=%s,args=%s)\n",(int)sli.size(),key,prefix,name,title,args);
5307 if (!key.isEmpty() && key[0]!='@') // check for @ to skip anonymous stuff (see bug427012)
5308 {
5309 for (RefItem *item : sli)
5310 {
5311 item->setPrefix(prefix);
5312 item->setScope(scope);
5313 item->setName(name);
5314 item->setTitle(title);
5315 item->setArgs(args);
5316 item->setGroup(key);
5317 }
5318 }
5319}
constexpr auto prefix
Definition anchor.cpp:44
This struct represents an item in the list of references.
Definition reflist.h:32

References QCString::isEmpty(), and prefix.

Referenced by MemberDefImpl::addListReference(), addListReferences(), ClassDefImpl::addListReferences(), FileDefImpl::addListReferences(), GroupDefImpl::addListReferences(), ModuleDefImpl::addListReferences(), NamespaceDefImpl::addListReferences(), and buildPageList().

◆ addRelatedPage()

PageDef * addRelatedPage ( const QCString & name,
const QCString & ptitle,
const QCString & doc,
const QCString & fileName,
int docLine,
int startLine,
const RefItemVector & sli,
GroupDef * gd,
const TagInfo * tagInfo,
bool xref,
SrcLangExt lang )

Definition at line 5172 of file util.cpp.

5183{
5184 PageDef *pd=nullptr;
5185 //printf("addRelatedPage(name=%s gd=%p)\n",qPrint(name),gd);
5186 QCString title=ptitle.stripWhiteSpace();
5187 bool newPage = true;
5188 if ((pd=Doxygen::pageLinkedMap->find(name)) && !pd->isReference())
5189 {
5190 if (!xref && !title.isEmpty() && pd->title()!=pd->name() && pd->title()!=title)
5191 {
5192 warn(fileName,startLine,"multiple use of page label '{}' with different titles, (other occurrence: {}, line: {})",
5193 name,pd->docFile(),pd->getStartBodyLine());
5194 }
5195 if (!title.isEmpty() && pd->title()==pd->name()) // pd has no real title yet
5196 {
5197 pd->setTitle(title);
5199 if (si)
5200 {
5201 si->setTitle(title);
5202 }
5203 }
5204 // append documentation block to the page.
5205 pd->setDocumentation(doc,fileName,docLine);
5206 //printf("Adding page docs '%s' pi=%p name=%s\n",qPrint(doc),pd,name);
5207 // append (x)refitems to the page.
5208 pd->setRefItems(sli);
5209 newPage = false;
5210 }
5211
5212 if (newPage) // new page
5213 {
5214 QCString baseName=name;
5215 if (baseName.endsWith(".tex"))
5216 baseName=baseName.left(baseName.length()-4);
5217 else if (baseName.right(Doxygen::htmlFileExtension.length())==Doxygen::htmlFileExtension)
5218 baseName=baseName.left(baseName.length()-Doxygen::htmlFileExtension.length());
5219
5220 //printf("Appending page '%s'\n",qPrint(baseName));
5221 if (pd) // replace existing page
5222 {
5223 pd->setDocumentation(doc,fileName,docLine);
5225 pd->setShowLineNo(FALSE);
5226 pd->setNestingLevel(0);
5227 pd->setPageScope(nullptr);
5228 pd->setTitle(title);
5229 pd->setReference(QCString());
5230 }
5231 else // newPage
5232 {
5233 pd = Doxygen::pageLinkedMap->add(baseName,
5234 createPageDef(fileName,docLine,baseName,doc,title));
5235 }
5236 pd->setBodySegment(startLine,startLine,-1);
5237
5238 pd->setRefItems(sli);
5239 pd->setLanguage(lang);
5240
5241 if (tagInfo)
5242 {
5243 pd->setReference(tagInfo->tagName);
5244 pd->setFileName(tagInfo->fileName);
5245 }
5246
5247 if (gd) gd->addPage(pd);
5248
5249 if (pd->hasTitle())
5250 {
5251 //outputList->writeTitle(pi->name,pi->title);
5252
5253 // a page name is a label as well!
5254 QCString file;
5255 QCString orgFile;
5256 int line = -1;
5257 if (gd)
5258 {
5259 file=gd->getOutputFileBase();
5260 orgFile=gd->getOutputFileBase();
5261 }
5262 else
5263 {
5264 file=pd->getOutputFileBase();
5265 orgFile=pd->docFile();
5266 line = pd->getStartBodyLine();
5267 }
5268 const SectionInfo *si = SectionManager::instance().find(pd->name());
5269 if (si)
5270 {
5271 if (!si->ref().isEmpty()) // we are from a tag file
5272 {
5274 file,-1,pd->title(),SectionType::Page,0,pd->getReference());
5275 }
5276 else if (si->lineNr() != -1)
5277 {
5278 warn(orgFile,line,"multiple use of section label '{}', (first occurrence: {}, line {})",pd->name(),si->fileName(),si->lineNr());
5279 }
5280 else
5281 {
5282 warn(orgFile,line,"multiple use of section label '{}', (first occurrence: {})",pd->name(),si->fileName());
5283 }
5284 }
5285 else
5286 {
5288 file,-1,pd->title(),SectionType::Page,0,pd->getReference());
5289 //printf("si->label='%s' si->definition=%s si->fileName='%s'\n",
5290 // qPrint(si->label),si->definition?si->definition->name().data():"<none>",
5291 // qPrint(si->fileName));
5292 //printf(" SectionInfo: sec=%p sec->fileName=%s\n",si,qPrint(si->fileName));
5293 //printf("Adding section key=%s si->fileName=%s\n",qPrint(pageName),qPrint(si->fileName));
5294 }
5295 }
5296 }
5297 return pd;
5298}
virtual QCString docFile() const =0
virtual QCString getReference() const =0
virtual QCString getOutputFileBase() const =0
virtual int getStartBodyLine() const =0
virtual bool isReference() const =0
virtual const QCString & name() const =0
virtual void setBodySegment(int defLine, int bls, int ble)=0
virtual void setDocumentation(const QCString &d, const QCString &docFile, int docLine, bool stripWhiteSpace=TRUE)=0
virtual void setLanguage(SrcLangExt lang)=0
virtual void setReference(const QCString &r)=0
virtual void setRefItems(const RefItemVector &sli)=0
static PageLinkedMap * pageLinkedMap
Definition doxygen.h:100
virtual void addPage(PageDef *def)=0
const T * find(const std::string &key) const
Definition linkedmap.h:47
A model of a page symbol.
Definition pagedef.h:26
virtual void setTitle(const QCString &title)=0
virtual void setNestingLevel(int)=0
virtual bool hasTitle() const =0
virtual void setFileName(const QCString &name)=0
virtual void setShowLineNo(bool)=0
virtual QCString title() const =0
virtual void setPageScope(Definition *)=0
This is an alternative implementation of QCString.
Definition qcstring.h:101
size_t length() const
Returns the length of the string, not counting the 0-terminator.
Definition qcstring.h:153
bool endsWith(const char *s) const
Definition qcstring.h:509
QCString stripWhiteSpace() const
returns a copy of this string with leading and trailing whitespace removed
Definition qcstring.h:245
QCString right(size_t len) const
Definition qcstring.h:219
QCString left(size_t len) const
Definition qcstring.h:214
class that provide information about a section.
Definition section.h:57
QCString ref() const
Definition section.h:71
QCString fileName() const
Definition section.h:73
int lineNr() const
Definition section.h:72
void setTitle(const QCString &t)
Definition section.h:83
SectionInfo * replace(const QCString &label, const QCString &fileName, int lineNr, const QCString &title, SectionType type, int level, const QCString &ref=QCString())
Definition section.h:154
SectionInfo * add(const SectionInfo &si)
Definition section.h:138
static SectionManager & instance()
returns a reference to the singleton
Definition section.h:175
static constexpr int Page
Definition section.h:31
#define warn(file, line, fmt,...)
Definition message.h:97
std::unique_ptr< PageDef > createPageDef(const QCString &f, int l, const QCString &n, const QCString &d, const QCString &t)
Definition pagedef.cpp:79
#define FALSE
Definition qcstring.h:34
QCString fileName
Definition entry.h:105
QCString tagName
Definition entry.h:104
QCString convertNameToFile(const QCString &name, bool allowDots, bool allowUnderscore)
Definition util.cpp:4004

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

1202{
1203 QCString result;
1204 if (!al.hasParameters()) return result;
1205 result+="(";
1206 for (auto it = al.begin() ; it!=al.end() ;)
1207 {
1208 Argument a = *it;
1209 QCString type1 = useCanonicalType && !a.canType.isEmpty() ? a.canType : a.type;
1210 QCString type2;
1211 int i=type1.find(")("); // hack to deal with function pointers
1212 if (i!=-1)
1213 {
1214 type2=type1.mid(i);
1215 type1=type1.left(i);
1216 }
1217 if (!a.attrib.isEmpty())
1218 {
1219 result+=a.attrib+" ";
1220 }
1221 if (!a.name.isEmpty() || !a.array.isEmpty())
1222 {
1223 result+= type1+" "+a.name+type2+a.array;
1224 }
1225 else
1226 {
1227 result+= type1+type2;
1228 }
1229 if (!a.defval.isEmpty() && showDefVals)
1230 {
1231 result+="="+a.defval;
1232 }
1233 ++it;
1234 if (it!=al.end()) result+=", ";
1235 }
1236 result+=")";
1237 if (al.constSpecifier()) result+=" const";
1238 if (al.volatileSpecifier()) result+=" volatile";
1239 if (al.refQualifier()==RefQualifierType::LValue) result+=" &";
1240 else if (al.refQualifier()==RefQualifierType::RValue) result+=" &&";
1241 if (!al.trailingReturnType().isEmpty()) result+=al.trailingReturnType();
1242 if (al.pureSpecifier()) result+=" =0";
1243 return removeRedundantWhiteSpace(result);
1244}
RefQualifierType refQualifier() const
Definition arguments.h:116
bool pureSpecifier() const
Definition arguments.h:113
iterator end()
Definition arguments.h:94
bool hasParameters() const
Definition arguments.h:76
QCString trailingReturnType() const
Definition arguments.h:114
bool constSpecifier() const
Definition arguments.h:111
iterator begin()
Definition arguments.h:93
bool volatileSpecifier() const
Definition arguments.h:112
QCString mid(size_t index, size_t len=static_cast< size_t >(-1)) const
Definition qcstring.h:226
This class contains the information about the argument of a function or template.
Definition arguments.h:27
QCString type
Definition arguments.h:42
QCString name
Definition arguments.h:44
QCString defval
Definition arguments.h:46
QCString array
Definition arguments.h:45
QCString canType
Definition arguments.h:43
QCString attrib
Definition arguments.h:41
QCString removeRedundantWhiteSpace(const QCString &s)
Definition util.cpp:578

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

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

◆ checkBlocks()

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

Definition at line 7009 of file util.cpp.

7010{
7011 if (s.isEmpty()) return;
7012
7013 const char *p = s.data();
7014 char c = 0;
7015 while ((c=*p))
7016 {
7017 if (c==markerInfo.markerChar) // potential start of marker
7018 {
7019 if (qstrncmp(p,markerInfo.beginStr,markerInfo.beginLen)==0) // start of begin marker
7020 {
7021 size_t len = markerInfo.beginLen;
7022 bool negate = *(p+len)=='!';
7023 if (negate) len++;
7024 p += len;
7025 QCString marker;
7026 while (*p)
7027 {
7028 if (markerInfo.closeLen==0 && *p=='\n') // matching end of line
7029 {
7030 warn(fileName,-1,"Remaining begin replacement with marker '{}'",marker);
7031 break;
7032 }
7033 else if (markerInfo.closeLen!= 0 && qstrncmp(p,markerInfo.closeStr,markerInfo.closeLen)==0) // matching marker closing
7034 {
7035 p += markerInfo.closeLen;
7036 warn(fileName,-1,"Remaining begin replacement with marker '{}'",marker);
7037 break;
7038 }
7039 marker += *p;
7040 p++;
7041 }
7042 }
7043 else if (qstrncmp(p,markerInfo.endStr,markerInfo.endLen)==0) // start of end marker
7044 {
7045 size_t len = markerInfo.endLen;
7046 bool negate = *(p+len)=='!';
7047 if (negate) len++;
7048 p += len;
7049 QCString marker;
7050 while (*p)
7051 {
7052 if (markerInfo.closeLen==0 && *p=='\n') // matching end of line
7053 {
7054 warn(fileName,-1,"Remaining end replacement with marker '{}'",marker);
7055 break;
7056 }
7057 else if (markerInfo.closeLen!= 0 && qstrncmp(p,markerInfo.closeStr,markerInfo.closeLen)==0) // matching marker closing
7058 {
7059 p += markerInfo.closeLen;
7060 warn(fileName,-1,"Remaining end replacement with marker '{}'",marker);
7061 break;
7062 }
7063 marker += *p;
7064 p++;
7065 }
7066 }
7067 }
7068 p++;
7069 }
7070}
const char * data() const
Returns a pointer to the contents of the string in the form of a 0-terminated C string.
Definition qcstring.h:159
int qstrncmp(const char *str1, const char *str2, size_t len)
Definition qcstring.h:75
size_t beginLen
Definition util.h:188
const char * closeStr
Definition util.h:191
const char * beginStr
Definition util.h:187
size_t closeLen
Definition util.h:192
const char * endStr
Definition util.h:189

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

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

◆ checkExtension()

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

Definition at line 5394 of file util.cpp.

5395{
5396 return fName.right(ext.length())==ext;
5397}

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

5810{
5811 MemberDef *bestMatch = getMemberFromSymbol(scope,fileScope,n);
5812
5813 if (bestMatch && bestMatch->isTypedef())
5814 return TRUE; // closest matching symbol is a typedef
5815 else
5816 return FALSE;
5817}
A model of a class/file/namespace member symbol.
Definition memberdef.h:48
virtual bool isTypedef() const =0
static MemberDef * getMemberFromSymbol(const Definition *scope, const FileDef *fileScope, const QCString &n)
Definition util.cpp:5757

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

Referenced by isVarWithConstructor().

◆ clearSubDirs()

void clearSubDirs ( const Dir & d)

Definition at line 4167 of file util.cpp.

4168{
4169 if (Config_getBool(CREATE_SUBDIRS))
4170 {
4171 // remove empty subdirectories
4172 int createSubdirsLevelPow2 = 1 << Config_getInt(CREATE_SUBDIRS_LEVEL);
4173 for (int l1=0;l1<16;l1++)
4174 {
4175 QCString subdir;
4176 subdir.sprintf("d%x",l1);
4177 for (int l2=0; l2 < createSubdirsLevelPow2; l2++)
4178 {
4179 QCString subsubdir;
4180 subsubdir.sprintf("d%x/d%02x",l1,l2);
4181 if (d.exists(subsubdir.str()) && d.isEmpty(subsubdir.str()))
4182 {
4183 d.rmdir(subsubdir.str());
4184 }
4185 }
4186 if (d.exists(subdir.str()) && d.isEmpty(subdir.str()))
4187 {
4188 d.rmdir(subdir.str());
4189 }
4190 }
4191 }
4192}
bool isEmpty(const std::string subdir) const
Definition dir.cpp:263
bool rmdir(const std::string &path, bool acceptsAbsPath=true) const
Definition dir.cpp:309
bool exists() const
Definition dir.cpp:257
const std::string & str() const
Definition qcstring.h:537
QCString & sprintf(const char *format,...)
Definition qcstring.cpp:29
#define Config_getInt(name)
Definition config.h:34
#define Config_getBool(name)
Definition config.h:33

References Config_getBool, Config_getInt, Dir::exists(), Dir::isEmpty(), Dir::rmdir(), QCString::sprintf(), and QCString::str().

Referenced by DocbookGenerator::cleanup(), HtmlGenerator::cleanup(), LatexGenerator::cleanup(), ManGenerator::cleanup(), RTFGenerator::cleanup(), and generateXML().

◆ computeQualifiedIndex()

int computeQualifiedIndex ( const QCString & name)

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

Definition at line 7311 of file util.cpp.

7312{
7313 int l = static_cast<int>(name.length());
7314 int lastSepPos = -1;
7315 const char *p = name.data();
7316 int i=l-2;
7317 int sharpCount=0;
7318 // --- begin optimized version of ts=name.findRev(">::");
7319 int ts = -1;
7320 while (i>=0)
7321 {
7322 if (p[i]=='>')
7323 {
7324 if (sharpCount==0 && p[i+1]==':' && p[i+2]==':')
7325 {
7326 ts=i;
7327 break;
7328 }
7329 sharpCount++;
7330 }
7331 else if (p[i]=='<')
7332 {
7333 sharpCount--;
7334 }
7335 i--;
7336 }
7337 // --- end optimized version
7338 if (ts==-1) ts=0; else p+=++ts;
7339 for (i=ts;i<l-1;i++)
7340 {
7341 char c=*p++;
7342 if (c==':' && *p==':') lastSepPos=i;
7343 if (c=='<') break;
7344 }
7345 return lastSepPos;
7346}

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

5466{
5467 if (str.isEmpty() || word==nullptr) return false;
5468 static const reg::Ex re(R"(\a+)");
5469 std::string s = str.str();
5470 for (reg::Iterator it(s,re) ; it!=reg::Iterator() ; ++it)
5471 {
5472 if (it->str()==word) return true;
5473 }
5474 return false;
5475}
Class representing a regular expression.
Definition regex.h:39
Iterator class to iterator through matches.
Definition regex.h:232
std::string_view word
Definition util.cpp:980

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

◆ convertCharEntitiesToUTF8()

QCString convertCharEntitiesToUTF8 ( const QCString & str)

Definition at line 4544 of file util.cpp.

4545{
4546 if (str.isEmpty()) return QCString();
4547
4548 std::string s = str.data();
4549 static const reg::Ex re(R"(&\a\w*;)");
4550 reg::Iterator it(s,re);
4552
4553 GrowBuf growBuf;
4554 size_t p=0, i=0, l=0;
4555 for (; it!=end ; ++it)
4556 {
4557 const auto &match = *it;
4558 p = match.position();
4559 l = match.length();
4560 if (p>i)
4561 {
4562 growBuf.addStr(s.substr(i,p-i));
4563 }
4564 QCString entity(match.str());
4566 const char *code=nullptr;
4567 if (symType!=HtmlEntityMapper::Sym_Unknown && (code=HtmlEntityMapper::instance().utf8(symType)))
4568 {
4569 growBuf.addStr(code);
4570 }
4571 else
4572 {
4573 growBuf.addStr(entity);
4574 }
4575 i=p+l;
4576 }
4577 growBuf.addStr(s.substr(i));
4578 growBuf.addChar(0);
4579 //printf("convertCharEntitiesToUTF8(%s)->%s\n",qPrint(s),growBuf.get());
4580 return growBuf.get();
4581}
Class representing a string buffer optimized for growing.
Definition growbuf.h:28
void addChar(char c)
Definition growbuf.h:69
void addStr(const QCString &s)
Definition growbuf.h:72
char * get()
Definition growbuf.h:114
static HtmlEntityMapper & instance()
Returns the one and only instance of the HTML entity mapper.
SymType name2sym(const QCString &symName) const
Give code of the requested HTML entity name.
bool match(std::string_view str, Match &match, const Ex &re)
Matches a given string str for a match against regular expression re.
Definition regex.cpp:759

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

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

◆ convertFileNameFortranParserCode()

FortranFormat convertFileNameFortranParserCode ( QCString fn)

Definition at line 6883 of file util.cpp.

6884{
6886 QCString parserName = Doxygen::parserManager->getParserName(ext);
6887
6888 if (parserName == "fortranfixed") return FortranFormat::Fixed;
6889 else if (parserName == "fortranfree") return FortranFormat::Free;
6890
6892}
static ParserManager * parserManager
Definition doxygen.h:131
QCString getFileNameExtension(const QCString &fn)
Definition util.cpp:5747

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

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

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

6722{
6723 bool extractPrivate = Config_getBool(EXTRACT_PRIVATE);
6724
6725 // default representing 1-1 mapping
6726 *outListType1=inListType;
6727 *outListType2=MemberListType::Invalid();
6728
6729 if (inProt==Protection::Public)
6730 {
6731 if (inListType.isPrivate())
6732 {
6733 *outListType1=MemberListType::Invalid();
6734 }
6735 }
6736 else if (inProt==Protection::Protected)
6737 {
6738 if (inListType.isPrivate() || inListType.isPublic())
6739 {
6740 *outListType1=MemberListType::Invalid();
6741 }
6742 else if (inListType.isProtected())
6743 {
6744 *outListType2=inListType.toPublic();
6745 }
6746 }
6747 else if (inProt==Protection::Private)
6748 {
6749 if (inListType.isPublic() || inListType.isProtected())
6750 {
6751 *outListType1=MemberListType::Invalid();
6752 }
6753 else if (inListType.isPrivate())
6754 {
6755 if (extractPrivate)
6756 {
6757 *outListType1=inListType.toPublic();
6758 *outListType2=inListType.toProtected();
6759 }
6760 else
6761 {
6762 *outListType1=MemberListType::Invalid();
6763 }
6764 }
6765 }
6766
6767 //printf("convertProtectionLevel(type=%s prot=%d): %s,%s\n",
6768 // qPrint(inListType.to_string()),inProt,qPrint(outListType1->to_string()),qPrint(outListType2->to_string()));
6769}
constexpr bool isProtected() const
Definition types.h:218
MemberListType toProtected() const
Definition types.h:276
MemberListType toPublic() const
Definition types.h:264
static MemberListType Invalid()
Definition types.h:209
constexpr bool isPrivate() const
Definition types.h:220
ML_TYPES constexpr bool isPublic() const
Definition types.h:216
@ Public
Definition types.h:26
@ Private
Definition types.h:26
@ Protected
Definition types.h:26

References Config_getBool, MemberListType::Invalid(), MemberListType::isPrivate(), MemberListType::isProtected(), MemberListType::isPublic(), Private, Protected, Public, 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 4463 of file util.cpp.

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

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

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

◆ convertToId()

QCString convertToId ( const QCString & s)

Converts a string to a HTML id string

Definition at line 4372 of file util.cpp.

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

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

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

◆ convertToJSString()

QCString convertToJSString ( const QCString & s)

Definition at line 4523 of file util.cpp.

4524{
4525 if (s.isEmpty()) return s;
4526 GrowBuf growBuf;
4527 const char *p=s.data();
4528 char c = 0;
4529 while ((c=*p++))
4530 {
4531 switch (c)
4532 {
4533 case '"': growBuf.addStr("\\\""); break;
4534 case '\\': if (*p=='u' && *(p+1)=='{') growBuf.addStr("\\");
4535 else growBuf.addStr("\\\\");
4536 break;
4537 default: growBuf.addChar(c); break;
4538 }
4539 }
4540 growBuf.addChar(0);
4541 return convertCharEntitiesToUTF8(growBuf.get());
4542}
QCString convertCharEntitiesToUTF8(const QCString &str)
Definition util.cpp:4544

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

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

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

4406{
4407 if (s.isEmpty()) return s;
4408 return "a" + s;
4409}

References QCString::isEmpty().

Referenced by DotGraph::generateCode(), and DotFilePatcher::run().

◆ correctURL()

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

Corrects URL url according to the relative path relPath.

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

Definition at line 6414 of file util.cpp.

6415{
6416 QCString result = url;
6417 if (!relPath.isEmpty() && !isURL(url))
6418 {
6419 result.prepend(relPath);
6420 }
6421 return result;
6422}
bool isURL(const QCString &url)
Checks whether the given url starts with a supported protocol.
Definition util.cpp:6402

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

6195{
6196 QCString url;
6197 if (!ref.isEmpty())
6198 {
6199 url = externalRef(relPath,ref,href);
6200 }
6201 if (!targetFileName.isEmpty())
6202 {
6203 QCString fn = targetFileName;
6204 if (ref.isEmpty())
6205 {
6206 if (!anchor.isEmpty() && isLocalFile)
6207 {
6208 fn=""; // omit file name for local links
6209 }
6210 else
6211 {
6212 url = relPath;
6213 }
6214 }
6215 url+=fn;
6216 }
6217 if (!anchor.isEmpty()) url+="#"+anchor;
6218 //printf("createHtmlUrl(relPath=%s,local=%d,target=%s,anchor=%s)=%s\n",qPrint(relPath),isLocalFile,qPrint(targetFileName),qPrint(anchor),qPrint(url));
6219 return url;
6220}
QCString externalRef(const QCString &relPath, const QCString &ref, bool href)
Definition util.cpp:6222

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

4141{
4142 if (Config_getBool(CREATE_SUBDIRS))
4143 {
4144 // create up to 4096 subdirectories
4145 int createSubdirsLevelPow2 = 1 << Config_getInt(CREATE_SUBDIRS_LEVEL);
4146 for (int l1=0; l1<16; l1++)
4147 {
4148 QCString subdir;
4149 subdir.sprintf("d%x",l1);
4150 if (!d.exists(subdir.str()) && !d.mkdir(subdir.str()))
4151 {
4152 term("Failed to create output directory '{}'\n",subdir);
4153 }
4154 for (int l2=0; l2<createSubdirsLevelPow2; l2++)
4155 {
4156 QCString subsubdir;
4157 subsubdir.sprintf("d%x/d%02x",l1,l2);
4158 if (!d.exists(subsubdir.str()) && !d.mkdir(subsubdir.str()))
4159 {
4160 term("Failed to create output directory '{}'\n",subsubdir);
4161 }
4162 }
4163 }
4164 }
4165}
bool mkdir(const std::string &path, bool acceptsAbsPath=true) const
Definition dir.cpp:295
#define term(fmt,...)
Definition message.h:137

References Config_getBool, Config_getInt, Dir::exists(), Dir::mkdir(), QCString::sprintf(), QCString::str(), and term.

Referenced by generateXML(), DocbookGenerator::init(), HtmlGenerator::init(), LatexGenerator::init(), ManGenerator::init(), RTFGenerator::init(), ClassDefImpl::writeQuickMemberLinks(), FileDefImpl::writeQuickMemberLinks(), GroupDefImpl::writeQuickMemberLinks(), and NamespaceDefImpl::writeQuickMemberLinks().

◆ demangleCSharpGenericName()

QCString demangleCSharpGenericName ( const QCString & name,
const QCString & templArgs )

Definition at line 7410 of file util.cpp.

7411{
7412 QCString result=name;
7413 if (result.endsWith("-g"))
7414 {
7415 int idx = result.find('-');
7416 result = result.left(idx)+templArgs;
7417 }
7418 return result;
7419}

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

Referenced by ClassDefImpl::className().

◆ detab()

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

Definition at line 7207 of file util.cpp.

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

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

Referenced by Markdown::process().

◆ determineAbsoluteIncludeName()

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

Definition at line 4100 of file util.cpp.

4101{
4102 bool searchIncludes = Config_getBool(SEARCH_INCLUDES);
4103 QCString absIncFileName = incFileName;
4104 FileInfo fi(curFile.str());
4105 if (fi.exists())
4106 {
4107 QCString absName = QCString(fi.dirPath(TRUE))+"/"+incFileName;
4108 FileInfo fi2(absName.str());
4109 if (fi2.exists())
4110 {
4111 absIncFileName=fi2.absFilePath();
4112 }
4113 else if (searchIncludes) // search in INCLUDE_PATH as well
4114 {
4115 const StringVector &includePath = Config_getList(INCLUDE_PATH);
4116 for (const auto &incPath : includePath)
4117 {
4118 FileInfo fi3(incPath);
4119 if (fi3.exists() && fi3.isDir())
4120 {
4121 absName = QCString(fi3.absFilePath())+"/"+incFileName;
4122 //printf("trying absName=%s\n",qPrint(absName));
4123 FileInfo fi4(absName.str());
4124 if (fi4.exists())
4125 {
4126 absIncFileName=fi4.absFilePath();
4127 break;
4128 }
4129 //printf( "absIncFileName = %s\n", qPrint(absIncFileName) );
4130 }
4131 }
4132 }
4133 //printf( "absIncFileName = %s\n", qPrint(absIncFileName) );
4134 }
4135 return absIncFileName;
4136}
Minimal replacement for QFileInfo.
Definition fileinfo.h:23
#define Config_getList(name)
Definition config.h:38
std::vector< std::string > StringVector
Definition containers.h:33

References FileInfo::absFilePath(), Config_getBool, Config_getList, FileInfo::dirPath(), FileInfo::exists(), FileInfo::isDir(), QCString::str(), and TRUE.

Referenced by readIncludeFile(), and ModuleManager::resolveImports().

◆ escapeCharsInString()

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

Definition at line 3830 of file util.cpp.

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

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

6179{
6180 bool extLinksInWindow = Config_getBool(EXT_LINKS_IN_WINDOW);
6181 if (extLinksInWindow)
6182 return "target=\"_blank\" ";
6183 else if (parent)
6184 return "target=\"_parent\" ";
6185 else
6186 return "";
6187}
constexpr DocNodeVariant * parent(DocNodeVariant *n)
returns the parent node of a given node n or nullptr if the node has no parent.
Definition docnode.h:1324

References Config_getBool, and parent().

Referenced by HtmlCodeGenerator::_writeCodeLink(), FTVHelp::Private::generateLink(), Markdown::Private::processLink(), replaceRef(), HtmlGenerator::startIndexItem(), HtmlDocVisitor::startLink(), HtmlGenerator::writeInheritedSectionTitle(), writeMapArea(), and HtmlGenerator::writeObjectLink().

◆ externalRef()

QCString externalRef ( const QCString & relPath,
const QCString & ref,
bool href )

Definition at line 6222 of file util.cpp.

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

References QCString::append(), QCString::at(), end(), QCString::isEmpty(), QCString::length(), QCString::prepend(), QCString::str(), and Doxygen::tagDestinationMap.

Referenced by HtmlHelp::addContentsItem(), convertMapFile(), createHtmlUrl(), generateJSLink(), FTVHelp::Private::generateLink(), replaceRef(), HtmlGenerator::startIndexItem(), LayoutNavEntry::url(), HtmlGenerator::writeInheritedSectionTitle(), writeJavasScriptSearchDataPage(), and writeMapArea().

◆ extractCanonicalArgType()

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

Definition at line 1827 of file util.cpp.

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

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

Referenced by matchArgument2().

◆ extractCanonicalType()

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

Definition at line 1751 of file util.cpp.

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

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(), QCString::stripWhiteSpace(), and word.

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

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

References QCString::clear(), end(), Fortran, 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 6665 of file util.cpp.

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

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

4200{
4201 int i=0, p=0;
4202 QCString clName=scopeName;
4203 NamespaceDef *nd = nullptr;
4204 if (!clName.isEmpty() && (nd=getResolvedNamespace(clName)) && getClass(clName)==nullptr)
4205 { // the whole name is a namespace (and not a class)
4206 namespaceName=nd->name();
4207 className.clear();
4208 goto done;
4209 }
4210 p=static_cast<int>(clName.length())-2;
4211 while (p>=0 && (i=clName.findRev("::",p))!=-1)
4212 // see if the first part is a namespace (and not a class)
4213 {
4214 //printf("Trying %s\n",qPrint(clName.left(i)));
4215 if (i>0 && (nd=getResolvedNamespace(clName.left(i))) && getClass(clName.left(i))==nullptr)
4216 {
4217 //printf("found!\n");
4218 namespaceName=nd->name();
4219 className=clName.right(clName.length()-i-2);
4220 goto done;
4221 }
4222 p=i-2; // try a smaller piece of the scope
4223 }
4224 //printf("not found!\n");
4225
4226 // not found, so we just have to guess.
4227 className=scopeName;
4228 namespaceName.clear();
4229
4230done:
4231 if (className.isEmpty() && !namespaceName.isEmpty() && !allowEmptyClass)
4232 {
4233 // class and namespace with the same name, correct to return the class.
4234 className=namespaceName;
4235 namespaceName.clear();
4236 }
4237 //printf("extractNamespace '%s' => '%s|%s'\n",qPrint(scopeName),
4238 // qPrint(className),qPrint(namespaceName));
4239 if (className.endsWith("-p"))
4240 {
4241 className = className.left(className.length()-2);
4242 }
4243 return;
4244}
An abstract interface of a namespace symbol.
ClassDef * getClass(const QCString &n)
NamespaceDef * getResolvedNamespace(const QCString &name)

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

Referenced by addClassToContext(), addConceptToContext(), findMember(), and writeAlphabeticalClassList().

◆ fileToString()

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

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

Definition at line 1441 of file util.cpp.

1442{
1443 if (name.isEmpty()) return QCString();
1444 bool fileOpened=false;
1445 if (name[0]=='-' && name[1]==0) // read from stdin
1446 {
1447 std::string contents;
1448 std::string line;
1449 while (getline(std::cin,line))
1450 {
1451 contents+=line+'\n';
1452 }
1453 return QCString(contents);
1454 }
1455 else // read from file
1456 {
1457 FileInfo fi(name.str());
1458 if (!fi.exists() || !fi.isFile())
1459 {
1460 err("file '{}' not found\n",name);
1461 return "";
1462 }
1463 std::string buf;
1464 fileOpened=readInputFile(name,buf,filter,isSourceCode);
1465 if (fileOpened)
1466 {
1467 addTerminalCharIfMissing(buf,'\n');
1468 return buf;
1469 }
1470 }
1471 if (!fileOpened)
1472 {
1473 err("cannot open file '{}' for reading\n",name);
1474 }
1475 return "";
1476}
void addTerminalCharIfMissing(std::string &s, char c)
Definition stringutil.h:84
bool readInputFile(const QCString &fileName, std::string &contents, bool filter, bool isSourceCode)
read a file name fileName and optionally filter and transcode it
Definition util.cpp:5997

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

6577{
6578 bool allExternals = Config_getBool(ALLEXTERNALS);
6579 bool isDocFile = fd->isDocumentationFile();
6580 genSourceFile = !isDocFile && fd->generateSourceFile();
6581 return ( ((allExternals && fd->isLinkable()) ||
6583 ) &&
6584 !isDocFile
6585 );
6586}
virtual bool isLinkable() const =0
virtual bool isLinkableInProject() const =0
virtual bool generateSourceFile() const =0
virtual bool isDocumentationFile() const =0

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

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

◆ filterCRLF()

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

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

Referenced by readInputFile().

◆ filterTitle()

QCString filterTitle ( const QCString & title)

Definition at line 6077 of file util.cpp.

6078{
6079 std::string tf;
6080 std::string t = title.str();
6081 static const reg::Ex re(R"(%[a-z_A-Z]+)");
6082 reg::Iterator it(t,re);
6084 size_t p = 0;
6085 for (; it!=end ; ++it)
6086 {
6087 const auto &match = *it;
6088 size_t i = match.position();
6089 size_t l = match.length();
6090 if (i>p) tf+=t.substr(p,i-p);
6091 tf+=match.str().substr(1); // skip %
6092 p=i+l;
6093 }
6094 tf+=t.substr(p);
6095 return QCString(tf);
6096}

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

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

◆ findAndRemoveWord()

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

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

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

Definition at line 5481 of file util.cpp.

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

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

Referenced by isVarWithConstructor().

◆ findFileDef()

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

Definition at line 3408 of file util.cpp.

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

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

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

◆ findFilePath()

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

Definition at line 3491 of file util.cpp.

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

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

Referenced by readIncludeFile(), and DocParser::readTextFileByName().

◆ findIndex() [1/2]

int findIndex ( const std::string & s,
const reg::Ex & re )

find the index of the first occurrence of pattern re in a string s returns -1 if the pattern could not be found

Definition at line 7149 of file util.cpp.

7150{
7152 return reg::search(s,match,re) ? static_cast<int>(match.position()) : -1;
7153}
Object representing the matching results.
Definition regex.h:153
bool search(std::string_view str, Match &match, const Ex &re, size_t pos)
Search in a given string str starting at position pos for a match against regular expression re.
Definition regex.cpp:748

References reg::search().

◆ findIndex() [2/2]

int findIndex ( const StringVector & sv,
const std::string & s )

find the index of a string in a vector of strings, returns -1 if the string could not be found

Definition at line 7141 of file util.cpp.

7142{
7143 auto it = std::find(sv.begin(),sv.end(),s);
7144 return it!=sv.end() ? static_cast<int>(it-sv.begin()) : -1;
7145}

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

◆ findMembersWithSpecificName()

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

Definition at line 2229 of file util.cpp.

2235{
2236 //printf(" Function with global scope name '%s' args='%s'\n",
2237 // mn->memberName(),args);
2238 for (const auto &md_p : *mn)
2239 {
2240 const MemberDef *md = md_p.get();
2241 const FileDef *fd=md->getFileDef();
2242 const GroupDef *gd=md->getGroupDef();
2243 //printf(" md->name()='%s' md->args='%s' fd=%p gd=%p current=%p ref=%s\n",
2244 // qPrint(md->name()),args,fd,gd,currentFile,qPrint(md->getReference()));
2245 if (
2246 ((gd && gd->isLinkable()) || (fd && fd->isLinkable()) || md->isReference()) &&
2247 md->getNamespaceDef()==nullptr && md->isLinkable() &&
2248 (!checkStatics || (!md->isStatic() && !md->isDefine()) ||
2249 currentFile==nullptr || fd==currentFile) // statics must appear in the same file
2250 )
2251 {
2252 bool match=TRUE;
2253 if (!args.isEmpty() && !md->isDefine() && args!="()")
2254 {
2255 const ArgumentList &mdAl = md->argumentList();
2256 auto argList_p = stringToArgumentList(md->getLanguage(),args);
2258 md->getOuterScope(),fd,&mdAl,
2259 Doxygen::globalScope,fd,argList_p.get(),
2260 checkCV,md->getLanguage());
2261 }
2262 if (match)
2263 {
2264 //printf("Found match!\n");
2265 members.push_back(md);
2266 }
2267 }
2268 }
2269}
This class represents an function or template argument list.
Definition arguments.h:65
virtual SrcLangExt getLanguage() const =0
Returns the programming language this definition was written in.
virtual Definition * getOuterScope() const =0
static NamespaceDefMutable * globalScope
Definition doxygen.h:121
A model of a group of symbols.
Definition groupdef.h:52
virtual GroupDef * getGroupDef()=0
virtual const FileDef * getFileDef() const =0
virtual const ArgumentList & argumentList() const =0
virtual bool isStatic() const =0
virtual bool isDefine() const =0
virtual const NamespaceDef * getNamespaceDef() const =0
std::unique_ptr< ArgumentList > stringToArgumentList(SrcLangExt lang, const QCString &argsString, QCString *extraTypeChars=nullptr)
Definition defargs.l:814
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 util.cpp:1958

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

static ModuleDef * findModuleDef ( const Definition * d)
static

Definition at line 5321 of file util.cpp.

5322{
5323 ModuleDef *mod = nullptr;
5325 {
5326 const FileDef *fd = toFileDef(d);
5327 if (fd) mod = fd->getModuleDef();
5328 }
5330 {
5331 const ClassDef *cd = toClassDef(d);
5332 if (cd)
5333 {
5334 const FileDef *fd = cd->getFileDef();
5335 if (fd) mod = fd->getModuleDef();
5336 }
5337 }
5339 {
5340 const ConceptDef *cd = toConceptDef(d);
5341 if (cd)
5342 {
5343 const FileDef *fd = cd->getFileDef();
5344 if (fd) mod = fd->getModuleDef();
5345 }
5346 }
5347 return mod;
5348}
A abstract class representing of a compound symbol.
Definition classdef.h:104
virtual FileDef * getFileDef() const =0
Returns the namespace this compound is in, or 0 if it has a global scope.
virtual const FileDef * getFileDef() const =0
virtual DefType definitionType() const =0
virtual ModuleDef * getModuleDef() const =0
ClassDef * toClassDef(Definition *d)
ConceptDef * toConceptDef(Definition *d)
FileDef * toFileDef(Definition *d)
Definition filedef.cpp:1894

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

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

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

Referenced by resolveRef().

◆ generateAnonymousAnchor()

QCString generateAnonymousAnchor ( const QCString & fileName,
int count )

Definition at line 4058 of file util.cpp.

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

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

◆ generateFileRef()

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

Definition at line 3380 of file util.cpp.

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

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

◆ generateMarker()

QCString generateMarker ( int id)

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

Definition at line 290 of file util.cpp.

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

References qsnprintf.

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

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

6105{
6106 bool caseSenseNames = getCaseSenseNames();
6107 bool found = FALSE;
6108
6109 // For platforms where the file system is non case sensitive overrule the setting
6111 {
6112 caseSenseNames = FALSE;
6113 }
6114
6115 if (!patList.empty())
6116 {
6117 std::string fn = fi.fileName();
6118 std::string fp = fi.filePath();
6119 std::string afp= fi.absFilePath();
6120
6121 for (const auto &li : patList)
6122 {
6123 std::string pattern = getter(li).str();
6124 if (!pattern.empty())
6125 {
6126 size_t i=pattern.find('=');
6127 if (i!=std::string::npos) pattern=pattern.substr(0,i); // strip of the extension specific filter name
6128
6129 if (!caseSenseNames)
6130 {
6131 pattern = QCString(pattern).lower().str();
6132 fn = QCString(fn).lower().str();
6133 fp = QCString(fp).lower().str();
6134 afp = QCString(afp).lower().str();
6135 }
6136 reg::Ex re(pattern,reg::Ex::Mode::Wildcard);
6137 found = re.isValid() && (reg::match(fn,re) ||
6138 (fn!=fp && reg::match(fp,re)) ||
6139 (fn!=afp && fp!=afp && reg::match(afp,re)));
6140 if (found)
6141 {
6142 elem = li;
6143 break;
6144 }
6145 //printf("Matching '%s' against pattern '%s' found=%d\n",
6146 // qPrint(fi->fileName()),qPrint(pattern),found);
6147 }
6148 }
6149 }
6150 return found;
6151}
std::string fileName() const
Definition fileinfo.cpp:118
std::string filePath() const
Definition fileinfo.cpp:91
std::string absFilePath() const
Definition fileinfo.cpp:101
@ Wildcard
simple globbing pattern.
Definition regex.h:45

References FileInfo::absFilePath(), FALSE, FileInfo::fileName(), FileInfo::filePath(), Portable::fileSystemIsCaseSensitive(), found, getCaseSenseNames(), reg::Ex::isValid(), QCString::lower(), reg::match(), QCString::str(), and reg::Ex::Wildcard.

Referenced by getEncoding(), and patternMatch().

◆ getCanonicalTemplateSpec()

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

Definition at line 1577 of file util.cpp.

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

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

Referenced by getCanonicalTypeForIdentifier().

◆ getCanonicalTypeForIdentifier()

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

Definition at line 1597 of file util.cpp.

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

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

Referenced by extractCanonicalType(), and getCanonicalTypeForIdentifier().

◆ getCaseSenseNames()

bool getCaseSenseNames ( )

Definition at line 3820 of file util.cpp.

3821{
3822 auto caseSenseNames = Config_getEnum(CASE_SENSE_NAMES);
3823
3824 if (caseSenseNames == CASE_SENSE_NAMES_t::YES) return true;
3825 else if (caseSenseNames == CASE_SENSE_NAMES_t::NO) return false;
3827}
#define Config_getEnum(name)
Definition config.h:35

References Config_getEnum, and Portable::fileSystemIsCaseSensitive().

Referenced by escapeCharsInString(), genericPatternMatch(), FileNameFn::searchKey(), and unescapeCharsInString().

◆ getDefs()

GetDefResult getDefs ( const GetDefInput & input)

Definition at line 2822 of file util.cpp.

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

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

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

◆ getDefsNew()

GetDefResult getDefsNew ( const GetDefInput & input)

Definition at line 2273 of file util.cpp.

2274{
2275 GetDefResult result;
2276 if (input.memberName.isEmpty()) return result;
2277
2278 //printf("@@ --- getDefsNew(%s,%s)-----------\n",qPrint(scName),qPrint(mbName));
2279 const Definition *scope = Doxygen::globalScope;
2280 SymbolResolver resolver;
2281 if (input.currentFile) resolver.setFileScope(input.currentFile);
2282 if (!input.scopeName.isEmpty())
2283 {
2284 scope = resolver.resolveSymbol(scope,input.scopeName);
2285 }
2286 if (scope==Doxygen::globalScope)
2287 {
2288 scope = input.currentFile;
2289 }
2290 //printf("@@ -> found scope scope=%s member=%s out=%s\n",qPrint(input.scopeName),qPrint(input.memberName),qPrint(scope?scope->name():""));
2291 //
2292 const Definition *symbol = resolver.resolveSymbol(scope,input.memberName,input.args,input.checkCV,input.insideCode);
2293 //printf("@@ -> found symbol in=%s out=%s\n",qPrint(input.memberName),qPrint(symbol?symbol->qualifiedName():QCString()));
2294 if (symbol && symbol->definitionType()==Definition::TypeMember)
2295 {
2296 result.md = toMemberDef(symbol);
2297 result.cd = result.md->getClassDef();
2298 if (result.cd==nullptr) result.nd = result.md->getNamespaceDef();
2299 if (result.cd==nullptr && result.nd==nullptr) result.fd = result.md->getFileDef();
2300 result.gd = result.md->getGroupDef();
2301 result.found = true;
2302 }
2303 else if (symbol && symbol->definitionType()==Definition::TypeClass)
2304 {
2305 result.cd = toClassDef(symbol);
2306 result.found = true;
2307 }
2308 else if (symbol && symbol->definitionType()==Definition::TypeNamespace)
2309 {
2310 result.nd = toNamespaceDef(symbol);
2311 result.found = true;
2312 }
2313 else if (symbol && symbol->definitionType()==Definition::TypeConcept)
2314 {
2315 result.cnd = toConceptDef(symbol);
2316 result.found = true;
2317 }
2318 else if (symbol && symbol->definitionType()==Definition::TypeModule)
2319 {
2320 result.modd = toModuleDef(symbol);
2321 result.found = true;
2322 }
2323 return result;
2324}
The common base class of all entity definitions found in the sources.
Definition definition.h:76
virtual const ClassDef * getClassDef() const =0
const Definition * resolveSymbol(const Definition *scope, const QCString &name, const QCString &args=QCString(), bool checkCV=false, bool insideCode=false)
Find the symbool definition matching name within the scope set.
void setFileScope(const FileDef *fd)
Sets or updates the file scope using when resolving symbols.
MemberDef * toMemberDef(Definition *d)
ModuleDef * toModuleDef(Definition *d)
NamespaceDef * toNamespaceDef(Definition *d)
bool insideCode
Definition util.h:119
const ConceptDef * cnd
Definition util.h:130
const ModuleDef * modd
Definition util.h:131

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

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

References GetDefInput::args, MemberDef::argumentList(), GetDefResult::cd, GetDefInput::checkCV, QCString::clear(), Cpp, GetDefInput::currentFile, MemberDef::enumFieldList(), FALSE, GetDefResult::fd, QCString::find(), findMembersWithSpecificName(), QCString::findRev(), GetDefInput::forceEmptyScope, found, 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 6776 of file util.cpp.

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

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

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

◆ getEncoding()

QCString getEncoding ( const FileInfo & fi)

Definition at line 6164 of file util.cpp.

6165{
6166 InputFileEncoding elem;
6167 auto getter = [](const InputFileEncoding &e) { return e.pattern; };
6168 if (genericPatternMatch(fi,Doxygen::inputFileEncodingList,elem,getter)) // check for file specific encoding
6169 {
6170 return elem.encoding;
6171 }
6172 else // fall back to default encoding
6173 {
6174 return Config_getString(INPUT_ENCODING);
6175 }
6176}
static InputFileEncodingList inputFileEncodingList
Definition doxygen.h:140
#define Config_getString(name)
Definition config.h:32
QCString encoding
Definition doxygen.h:71
bool genericPatternMatch(const FileInfo &fi, const PatternList &patList, PatternElem &elem, PatternGet getter)
Definition util.cpp:6101

References Config_getString, InputFileEncoding::encoding, genericPatternMatch(), and Doxygen::inputFileEncodingList.

Referenced by readCodeFragment(), and readInputFile().

◆ getFileFilter()

QCString getFileFilter ( const QCString & name,
bool isSourceCode )

looks for a filter for the file name. Returns the name of the filter if there is a match for the file name, otherwise an empty string. In case inSourceCode is TRUE then first the source filter list is considered.

Definition at line 1369 of file util.cpp.

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

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

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

◆ getFileNameExtension()

◆ getFilterFromList()

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

Definition at line 1328 of file util.cpp.

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

References FALSE, Portable::fileSystemIsCaseSensitive(), QCString::find(), found, 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 5723 of file util.cpp.

5724{
5725 // try the extension
5726 auto lang = getLanguageFromFileName(fileName, SrcLangExt::Unknown);
5727 if (lang == SrcLangExt::Unknown)
5728 {
5729 // try the language names
5730 QCString langName = fileName.lower();
5731 if (langName.at(0)=='.') langName = langName.mid(1);
5732 auto it = std::find_if(g_lang2extMap.begin(),g_lang2extMap.end(),
5733 [&langName](const auto &info) { return info.langName==langName; });
5734 if (it != g_lang2extMap.end())
5735 {
5736 lang = it->parserId;
5737 fileName = it->defExt;
5738 }
5739 else // default to C++
5740 {
5741 return SrcLangExt::Cpp;
5742 }
5743 }
5744 return lang;
5745}
@ Unknown
Definition types.h:43
SrcLangExt getLanguageFromFileName(const QCString &fileName, SrcLangExt defLang)
Definition util.cpp:5705
static std::vector< Lang2ExtMap > g_lang2extMap
Definition util.cpp:5576

References QCString::at(), Cpp, g_lang2extMap, getLanguageFromFileName(), QCString::lower(), QCString::mid(), and Unknown.

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

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

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

◆ getMemberFromSymbol()

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

Definition at line 5757 of file util.cpp.

5759{
5760 if (scope==nullptr ||
5763 )
5764 )
5765 {
5767 }
5768
5769 QCString name = n;
5770 if (name.isEmpty())
5771 return nullptr; // no name was given
5772
5773 auto &range = Doxygen::symbolMap->find(name);
5774 if (range.empty())
5775 return nullptr; // could not find any matching symbols
5776
5777 // mostly copied from getResolvedClassRec()
5778 QCString explicitScopePart;
5779 int qualifierIndex = computeQualifiedIndex(name);
5780 if (qualifierIndex!=-1)
5781 {
5782 explicitScopePart = name.left(qualifierIndex);
5783 replaceNamespaceAliases(explicitScopePart);
5784 name = name.mid(qualifierIndex+2);
5785 }
5786 //printf("explicitScopePart=%s\n",qPrint(explicitScopePart));
5787
5788 int minDistance = 10000;
5789 MemberDef *bestMatch = nullptr;
5790
5791 for (Definition *d : range)
5792 {
5793 if (d->definitionType()==Definition::TypeMember)
5794 {
5795 SymbolResolver resolver(fileScope);
5796 int distance = resolver.isAccessibleFromWithExpScope(scope,d,explicitScopePart);
5797 if (distance!=-1 && distance<minDistance)
5798 {
5799 minDistance = distance;
5800 bestMatch = toMemberDef(d);
5801 //printf("new best match %s distance=%d\n",qPrint(bestMatch->qualifiedName()),distance);
5802 }
5803 }
5804 }
5805 return bestMatch;
5806}
static SymbolMap< Definition > * symbolMap
Definition doxygen.h:125
void replaceNamespaceAliases(QCString &name)
int computeQualifiedIndex(const QCString &name)
Return the index of the last :: in the string name that is still before the first <.
Definition util.cpp:7311

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

4587{
4588 return theTranslator->trOverloadText();
4589 //"This is an overloaded member function, "
4590 // "provided for convenience. It differs from the above "
4591 // "function only in what argument(s) it accepts.";
4592}
Translator * theTranslator
Definition language.cpp:71

References theTranslator.

Referenced by addMemberDocs(), addOverloaded(), and CommentScanner::parseCommentBlock().

◆ getPrefixIndex()

int getPrefixIndex ( const QCString & name)

Returns the character index within name of the first prefix in Config_getList(IGNORE_PREFIX) that matches name at the left hand side, or zero if no match was found

Definition at line 3736 of file util.cpp.

3737{
3738 if (name.isEmpty()) return 0;
3739 const StringVector &sl = Config_getList(IGNORE_PREFIX);
3740 for (const auto &s : sl)
3741 {
3742 const char *ps=s.c_str();
3743 const char *pd=name.data();
3744 int i=0;
3745 while (*ps!=0 && *pd!=0 && *ps==*pd) ps++,pd++,i++;
3746 if (*ps==0 && *pd!=0)
3747 {
3748 return i;
3749 }
3750 }
3751 return 0;
3752}

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

7299{
7300 QCString projectCookie = Config_getString(HTML_PROJECT_COOKIE);
7301 if (projectCookie.isEmpty()) return QCString();
7302 uint8_t md5_sig[16];
7303 char sigStr[34];
7304 MD5Buffer(projectCookie.data(),static_cast<unsigned int>(projectCookie.length()),md5_sig);
7305 MD5SigToString(md5_sig,sigStr);
7306 sigStr[32]='_'; sigStr[33]=0;
7307 return sigStr;
7308}

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

Referenced by generateJSNavTree(), HtmlGenerator::init(), and writeJavaScriptSearchIndex().

◆ getScopeDefs()

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

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

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
sthe scope name as a string.
pthe start position (0 is the first).
lthe resulting length of the fragment.
Returns
the location of the fragment, or -1 if non is found.

Definition at line 5125 of file util.cpp.

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

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

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

◆ guessSection()

EntryType guessSection ( const QCString & name)

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

Definition at line 349 of file util.cpp.

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

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

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

◆ if() [1/2]

if ( ! insideString)

Definition at line 985 of file util.cpp.

986 {
987 const ClassDef *cd=nullptr;
988 const ConceptDef *cnd=nullptr;
989 //printf("** Match word '%s'\n",qPrint(matchWord));
990
991 SymbolResolver resolver(fileScope);
992 cd=resolver.resolveClass(scope,matchWord);
993 const MemberDef *typeDef = resolver.getTypedef();
994 if (typeDef) // First look at typedef then class, see bug 584184.
995 {
996 if (external ? typeDef->isLinkable() : typeDef->isLinkableInProject())
997 {
998 if (typeDef->getOuterScope()!=self)
999 {
1000 //printf("Found typedef %s word='%s'\n",qPrint(typeDef->name()),qPrint(word));
1001 out.writeLink(typeDef->getReference(),
1002 typeDef->getOutputFileBase(),
1003 typeDef->anchor(),
1004 word);
1005 found=TRUE;
1006 }
1007 }
1008 }
1009 auto writeCompoundName = [&](const auto *cd_) {
1010 if (external ? cd_->isLinkable() : cd_->isLinkableInProject())
1011 {
1012 if (self==nullptr || cd_->qualifiedName()!=self->qualifiedName())
1013 {
1014 //printf("Found compound %s word='%s'\n",qPrint(cd->name()),qPrint(word));
1015 out.writeLink(cd_->getReference(),cd_->getOutputFileBase(),cd_->anchor(),word);
1016 found=TRUE;
1017 }
1018 }
1019 };
1020 if (!found && (cd || (cd=getClass(matchWord))))
1021 {
1022 writeCompoundName(cd);
1023 }
1024 else if ((cd=getClass(matchWord+"-p"))) // search for Obj-C protocols as well
1025 {
1026 writeCompoundName(cd);
1027 }
1028 else if ((cnd=getConcept(matchWord))) // search for concepts
1029 {
1030 writeCompoundName(cnd);
1031 }
1032 else
1033 {
1034 //printf(" -> nothing\n");
1035 }
1036
1037 int m = matchWord.findRev("::");
1038 QCString scopeName;
1039 if (scope &&
1040 (scope->definitionType()==Definition::TypeClass ||
1041 scope->definitionType()==Definition::TypeNamespace
1042 )
1043 )
1044 {
1045 scopeName=scope->name();
1046 }
1047 else if (m!=-1)
1048 {
1049 scopeName = matchWord.left(m);
1050 matchWord = matchWord.mid(m+2);
1051 }
1052
1053 //printf("ScopeName=%s\n",qPrint(scopeName));
1054 //if (!found) printf("Trying to link '%s' in '%s'\n",qPrint(word),qPrint(scopeName));
1055 if (!found)
1056 {
1057 GetDefInput input(scopeName,matchWord,QCString());
1058 GetDefResult result = getDefs(input);
1059 if (result.found && result.md &&
1060 (external ? result.md->isLinkable() : result.md->isLinkableInProject())
1061 )
1062 {
1063 //printf("Found ref scope=%s\n",d ? qPrint(d->name()) : "<global>");
1064 //ol.writeObjectLink(d->getReference(),d->getOutputFileBase(),
1065 // md->anchor(),word);
1066 if (result.md!=self && (self==nullptr || result.md->name()!=self->name()))
1067 // name check is needed for overloaded members, where getDefs just returns one
1068 {
1069 /* in case of Fortran scope and the variable is a non Fortran variable: don't link,
1070 * see also getLink in fortrancode.l
1071 */
1072 if (!(scope &&
1073 (scope->getLanguage() == SrcLangExt::Fortran) &&
1074 result.md->isVariable() &&
1075 (result.md->getLanguage() != SrcLangExt::Fortran)
1076 )
1077 )
1078 {
1079 //printf("found symbol %s word='%s'\n",qPrint(result.md->name()),qPrint(word));
1080 out.writeLink(result.md->getReference(),result.md->getOutputFileBase(),
1081 result.md->anchor(),word);
1082 found=TRUE;
1083 }
1084 }
1085 }
1086 }
1087 }
virtual QCString anchor() const =0
virtual bool isVariable() const =0
ConceptDef * getConcept(const QCString &n)
QCString matchWord
Definition util.cpp:981
GetDefResult getDefs(const GetDefInput &input)
Definition util.cpp:2822

References Definition::anchor(), Definition::definitionType(), Fortran, found, GetDefResult::found, getClass(), getConcept(), getDefs(), Definition::getLanguage(), Definition::getOuterScope(), Definition::getOutputFileBase(), Definition::getReference(), SymbolResolver::getTypedef(), Definition::isLinkable(), Definition::isLinkableInProject(), MemberDef::isVariable(), matchWord, GetDefResult::md, Definition::name(), Definition::qualifiedName(), SymbolResolver::resolveClass(), TRUE, Definition::TypeClass, Definition::TypeNamespace, word, and TextGeneratorIntf::writeLink().

◆ if() [2/2]

if ( strLen ,
35 && floatingIndex,
30 && autoBreak )

Definition at line 949 of file util.cpp.

950 {
951 std::string_view splitText = txtStr.substr(skipIndex,newIndex-skipIndex);
952 size_t splitLength = splitText.length();
953 size_t offset=1;
954 size_t i = splitText.find(',');
955 if (i==std::string::npos) { i=splitText.find('<'); if (i!=std::string::npos) offset=0; }
956 if (i==std::string::npos) i=splitText.find('>');
957 if (i==std::string::npos) i=splitText.find(' ');
958 //printf("splitText=[%s] len=%d i=%d offset=%d\n",qPrint(splitText),splitLength,i,offset);
959 if (i!=std::string::npos) // add a link-break at i in case of Html output
960 {
961 std::string_view part1 = splitText.substr(0,i+offset);
962 out.writeString(part1,keepSpaces);
963 out.writeBreak(indentLevel==0 ? 0 : indentLevel+1);
964 std::string_view part2 = splitText.substr(i+offset);
965 out.writeString(part2,keepSpaces);
966 floatingIndex=splitLength-i-offset+matchLen;
967 }
968 else
969 {
970 out.writeString(splitText,keepSpaces);
971 }
972 }
skipIndex
Definition util.cpp:1095

References skipIndex, TextGeneratorIntf::writeBreak(), and TextGeneratorIntf::writeString().

Referenced by DocLink::DocLink().

◆ initDefaultExtensionMapping()

void initDefaultExtensionMapping ( )

Definition at line 5632 of file util.cpp.

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

References updateLanguageMapping().

Referenced by initDoxygen().

◆ inlineArgListToDoc()

QCString inlineArgListToDoc ( const ArgumentList & al)

Definition at line 1156 of file util.cpp.

1157{
1158 QCString paramDocs;
1159 if (al.hasDocumentation())
1160 {
1161 for (const Argument &a : al)
1162 {
1163 if (a.hasDocumentation())
1164 {
1165 QCString docsWithoutDir = a.docs;
1166 QCString direction = extractDirection(docsWithoutDir);
1167 paramDocs+=" \\ilinebr @param"+direction+" "+a.name+" "+docsWithoutDir;
1168 }
1169 }
1170 }
1171 return paramDocs;
1172}
bool hasDocumentation() const
Definition arguments.cpp:21
QCString extractDirection(QCString &docs)
Strip the direction part from docs and return it as a string in canonical form The input docs string ...
Definition util.cpp:6665

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

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

◆ inlineTemplateArgListToDoc()

QCString inlineTemplateArgListToDoc ( const ArgumentList & al)

Definition at line 1174 of file util.cpp.

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

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

4247{
4248 QCString result=scope;
4249 if (!templ.isEmpty() && scope.find('<')==-1)
4250 {
4251 int si=0, pi=0;
4252 ClassDef *cd=nullptr;
4253 while (
4254 (si=scope.find("::",pi))!=-1 && !getClass(scope.left(si)+templ) &&
4255 ((cd=getClass(scope.left(si)))==nullptr || cd->templateArguments().empty())
4256 )
4257 {
4258 //printf("Tried '%s'\n",qPrint((scope.left(si)+templ)));
4259 pi=si+2;
4260 }
4261 if (si==-1) // not nested => append template specifier
4262 {
4263 result+=templ;
4264 }
4265 else // nested => insert template specifier before after first class name
4266 {
4267 result=scope.left(si) + templ + scope.right(scope.length()-si);
4268 }
4269 }
4270 //printf("insertTemplateSpecifierInScope('%s','%s')=%s\n",
4271 // qPrint(scope),qPrint(templ),qPrint(result));
4272 return result;
4273}
bool empty() const
Definition arguments.h:99
virtual const ArgumentList & templateArguments() const =0
Returns the template arguments of this class.

References ArgumentList::empty(), QCString::find(), getClass(), QCString::isEmpty(), QCString::left(), QCString::length(), QCString::right(), and ClassDef::templateArguments().

Referenced by DotClassGraph::addClass(), generateXMLForClass(), DiagramItem::label(), ClassDefImpl::writeInheritanceGraph(), and ClassDefImpl::writeTagFile().

◆ integerToAlpha()

QCString integerToAlpha ( int n,
bool upper )

Definition at line 7169 of file util.cpp.

7170{
7171 QCString result;
7172 int residual = n;
7173
7174 char modVal[2];
7175 modVal[1] = 0;
7176 while (residual > 0)
7177 {
7178 modVal[0] = (upper ? 'A': 'a') + (residual-1)%26;
7179 result = modVal + result;
7180 residual = (residual-1) / 26;
7181 }
7182 return result;
7183}

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

◆ integerToRoman()

QCString integerToRoman ( int n,
bool upper )

Definition at line 7185 of file util.cpp.

7186{
7187 static const char *str_romans_upper[] = { "M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I" };
7188 static const char *str_romans_lower[] = { "m", "cm", "d", "cd", "c", "xc", "l", "xl", "x", "ix", "v", "iv", "i" };
7189 static const int values[] = { 1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1 };
7190 static const char **str_romans = upper ? str_romans_upper : str_romans_lower;
7191
7192 QCString result;
7193 int residual = n;
7194
7195 for (int i = 0; i < 13; ++i)
7196 {
7197 while (residual - values[i] >= 0)
7198 {
7199 result += str_romans[i];
7200 residual -= values[i];
7201 }
7202 }
7203
7204 return result;
7205}

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

◆ isLowerCase()

static bool isLowerCase ( QCString & s)
static

Definition at line 2952 of file util.cpp.

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

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

6403{
6404 static const std::unordered_set<std::string> schemes = {
6405 "http", "https", "ftp", "ftps", "sftp", "file", "news", "irc", "ircs"
6406 };
6407 QCString loc_url = url.stripWhiteSpace();
6408 int colonPos = loc_url.find(':');
6409 return colonPos!=-1 && schemes.find(loc_url.left(colonPos).str())!=schemes.end();
6410}

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

7157{
7158 std::string result;
7159 bool first=true;
7160 for (const auto &s : sv)
7161 {
7162 if (!first) result+=delimiter;
7163 first=false;
7164 result+=s;
7165 }
7166 return result;
7167}

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

◆ keyWordsFortranC()

static bool keyWordsFortranC ( const char * contents)
static

Definition at line 6810 of file util.cpp.

6811{
6812 static const std::unordered_set<std::string> fortran_C_keywords = {
6813 "character", "call", "close", "common", "continue",
6814 "case", "contains", "cycle", "class", "codimension",
6815 "concurrent", "contiguous", "critical"
6816 };
6817
6818 if (*contents != 'c' && *contents != 'C') return false;
6819
6820 const char *c = contents;
6821 QCString keyword;
6822 while (*c && *c != ' ') {keyword += *c; c++;}
6823 keyword = keyword.lower();
6824
6825 return (fortran_C_keywords.find(keyword.str()) != fortran_C_keywords.end());
6826}

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

Referenced by recognizeFixedForm().

◆ langToString()

QCString langToString ( SrcLangExt lang)

Returns a string representation of lang.

Definition at line 6360 of file util.cpp.

6361{
6362 switch(lang)
6363 {
6364 case SrcLangExt::Unknown: return "Unknown";
6365 case SrcLangExt::IDL: return "IDL";
6366 case SrcLangExt::Java: return "Java";
6367 case SrcLangExt::CSharp: return "C#";
6368 case SrcLangExt::D: return "D";
6369 case SrcLangExt::PHP: return "PHP";
6370 case SrcLangExt::ObjC: return "Objective-C";
6371 case SrcLangExt::Cpp: return "C++";
6372 case SrcLangExt::JS: return "JavaScript";
6373 case SrcLangExt::Python: return "Python";
6374 case SrcLangExt::Fortran: return "Fortran";
6375 case SrcLangExt::VHDL: return "VHDL";
6376 case SrcLangExt::XML: return "XML";
6377 case SrcLangExt::SQL: return "SQL";
6378 case SrcLangExt::Markdown: return "Markdown";
6379 case SrcLangExt::Slice: return "Slice";
6380 case SrcLangExt::Lex: return "Lex";
6381 }
6382 return "Unknown";
6383}
@ Markdown
Definition types.h:57
@ Slice
Definition types.h:59

References Cpp, CSharp, D, Fortran, IDL, Java, JS, Lex, Markdown, ObjC, PHP, Python, Slice, SQL, Unknown, VHDL, and XML.

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

◆ leftScopeMatch()

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

Definition at line 892 of file util.cpp.

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

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

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

◆ lineBlock()

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

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

See also
routine extractBlock

Definition at line 6339 of file util.cpp.

6340{
6341 int result = 1;
6342
6343 // find the character positions of the first marker
6344 int m1 = text.find(marker);
6345 if (m1==-1) return result;
6346
6347 // find start line positions for the markers
6348 bool found=false;
6349 int p=0, i=0;
6350 while (!found && (i=text.find('\n',p))!=-1)
6351 {
6352 found = (p<=m1 && m1<i); // found the line with the start marker
6353 p=i+1;
6354 result++;
6355 }
6356 return result;
6357}

References QCString::find(), and found.

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

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

References end(), FALSE, QCString::isEmpty(), skipIndex, QCString::view(), and TextGeneratorIntf::writeString().

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

◆ linkToText()

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

Definition at line 3219 of file util.cpp.

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

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

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

References Doxygen::mainPage.

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

◆ mangleCSharpGenericName()

QCString mangleCSharpGenericName ( const QCString & name)

Definition at line 7400 of file util.cpp.

7401{
7402 int idx = name.find('<');
7403 if (idx!=-1)
7404 {
7405 return name.left(idx)+"-"+QCString().setNum(name.contains(",")+1)+"-g";
7406 }
7407 return name;
7408}
int contains(char c, bool cs=TRUE) const
Definition qcstring.cpp:143

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

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

◆ matchArgument2()

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

Definition at line 1892 of file util.cpp.

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

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

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

References argListToString(), ASSERT, AUTO_TRACE, ArgumentList::begin(), ArgumentList::constSpecifier(), ArgumentList::empty(), ArgumentList::end(), FALSE, ArgumentList::front(), MATCH, matchArgument2(), Definition::name(), NOMATCH, ArgumentList::refQualifier(), ArgumentList::size(), TRUE, Argument::type, and ArgumentList::volatileSpecifier().

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

◆ matchCanonicalTypes()

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

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

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

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

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

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

References argListToString(), AUTO_TRACE, AUTO_TRACE_ADD, ArgumentList::begin(), QCString::clear(), Argument::defval, Argument::docs, ArgumentList::end(), QCString::find(), QCString::isEmpty(), QCString::left(), QCString::length(), Argument::name, qPrint(), QCString::right(), ArgumentList::size(), QCString::stripWhiteSpace(), and Argument::type.

Referenced by addMemberDocs(), buildFunctionList(), and findFriends().

◆ mergeMemberOverrideOptions()

void mergeMemberOverrideOptions ( MemberDefMutable * md1,
MemberDefMutable * md2 )

Definition at line 7348 of file util.cpp.

7349{
7350 if (Config_getBool(CALL_GRAPH) !=md1->hasCallGraph()) md2->overrideCallGraph(md1->hasCallGraph());
7351 if (Config_getBool(CALLER_GRAPH)!=md1->hasCallerGraph()) md2->overrideCallerGraph(md1->hasCallerGraph());
7352 if (Config_getBool(CALL_GRAPH) !=md2->hasCallGraph()) md1->overrideCallGraph( md2->hasCallGraph());
7353 if (Config_getBool(CALLER_GRAPH)!=md2->hasCallerGraph()) md1->overrideCallerGraph(md2->hasCallerGraph());
7354
7355 if (Config_getBool(SHOW_ENUM_VALUES) !=md1->hasEnumValues()) md2->overrideEnumValues(md1->hasEnumValues());
7356 if (Config_getBool(SHOW_ENUM_VALUES) !=md2->hasEnumValues()) md1->overrideEnumValues( md2->hasEnumValues());
7357
7358 if (Config_getBool(REFERENCED_BY_RELATION)!=md1->hasReferencedByRelation()) md2->overrideReferencedByRelation(md1->hasReferencedByRelation());
7359 if (Config_getBool(REFERENCES_RELATION) !=md1->hasReferencesRelation()) md2->overrideReferencesRelation(md1->hasReferencesRelation());
7360 if (Config_getBool(REFERENCED_BY_RELATION)!=md2->hasReferencedByRelation()) md1->overrideReferencedByRelation(md2->hasReferencedByRelation());
7361 if (Config_getBool(REFERENCES_RELATION) !=md2->hasReferencesRelation()) md1->overrideReferencesRelation(md2->hasReferencesRelation());
7362
7363 if (Config_getBool(INLINE_SOURCES)!=md1->hasInlineSource()) md2->overrideInlineSource(md1->hasInlineSource());
7364 if (Config_getBool(INLINE_SOURCES)!=md2->hasInlineSource()) md1->overrideInlineSource(md2->hasInlineSource());
7365}
virtual bool hasReferencesRelation() const =0
virtual bool hasCallGraph() const =0
virtual bool hasInlineSource() const =0
virtual bool hasEnumValues() const =0
virtual bool hasCallerGraph() const =0
virtual bool hasReferencedByRelation() const =0
virtual void overrideReferencesRelation(bool e)=0
virtual void overrideReferencedByRelation(bool e)=0
virtual void overrideCallGraph(bool e)=0
virtual void overrideInlineSource(bool e)=0
virtual void overrideEnumValues(bool e)=0
virtual void overrideCallerGraph(bool e)=0

References Config_getBool, MemberDef::hasCallerGraph(), MemberDef::hasCallGraph(), MemberDef::hasEnumValues(), MemberDef::hasInlineSource(), MemberDef::hasReferencedByRelation(), MemberDef::hasReferencesRelation(), MemberDefMutable::overrideCallerGraph(), MemberDefMutable::overrideCallGraph(), MemberDefMutable::overrideEnumValues(), MemberDefMutable::overrideInlineSource(), MemberDefMutable::overrideReferencedByRelation(), and MemberDefMutable::overrideReferencesRelation().

Referenced by combineDeclarationAndDefinition(), and findFriends().

◆ mergeScopes()

QCString mergeScopes ( const QCString & leftScope,
const QCString & rightScope )

Merges two scope parts together. The parts may (partially) overlap. Example1: A::B and B::C will result in A::B::C
Example2: A and B will be A::B
Example3: A::B and B will be A::B

Parameters
leftScopethe left hand part of the scope.
rightScopethe right hand part of the scope.
Returns
the merged scope.

Definition at line 5080 of file util.cpp.

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

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

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

◆ nextUTF8CharPosition()

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

Definition at line 5819 of file util.cpp.

5820{
5821 if (startPos>=len) return len;
5822 uint8_t c = static_cast<uint8_t>(utf8Str[startPos]);
5823 int bytes=getUTF8CharNumBytes(c);
5824 if (c=='&') // skip over character entities
5825 {
5826 bytes=1;
5827 int (*matcher)(int) = nullptr;
5828 c = static_cast<uint8_t>(utf8Str[startPos+bytes]);
5829 if (c=='#') // numerical entity?
5830 {
5831 bytes++;
5832 c = static_cast<uint8_t>(utf8Str[startPos+bytes]);
5833 if (c=='x') // hexadecimal entity?
5834 {
5835 bytes++;
5836 matcher = std::isxdigit;
5837 }
5838 else // decimal entity
5839 {
5840 matcher = std::isdigit;
5841 }
5842 }
5843 else if (std::isalnum(c)) // named entity?
5844 {
5845 bytes++;
5846 matcher = std::isalnum;
5847 }
5848 if (matcher)
5849 {
5850 while ((c = static_cast<uint8_t>(utf8Str[startPos+bytes]))!=0 && matcher(c))
5851 {
5852 bytes++;
5853 }
5854 }
5855 if (c!=';')
5856 {
5857 bytes=1; // not a valid entity, reset bytes counter
5858 }
5859 }
5860 return startPos+bytes;
5861}

References getUTF8CharNumBytes().

Referenced by parseCommentAsText().

◆ normalizeNonTemplateArgumentsInString()

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

Definition at line 4786 of file util.cpp.

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

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

Referenced by findUsedClassesForClass().

◆ openOutputFile()

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

Definition at line 6783 of file util.cpp.

6784{
6785 assert(!f.is_open());
6786 bool fileOpened=FALSE;
6787 bool writeToStdout=outFile=="-";
6788 if (writeToStdout) // write to stdout
6789 {
6790 f.basic_ios<char>::rdbuf(std::cout.rdbuf());
6791 fileOpened = true;
6792 }
6793 else // write to file
6794 {
6795 FileInfo fi(outFile.str());
6796 if (fi.exists()) // create a backup
6797 {
6798 Dir dir;
6799 FileInfo backup(fi.filePath()+".bak");
6800 if (backup.exists()) // remove existing backup
6801 dir.remove(backup.filePath());
6802 dir.rename(fi.filePath(),fi.filePath()+".bak");
6803 }
6804 f = Portable::openOutputStream(outFile);
6805 fileOpened = f.is_open();
6806 }
6807 return fileOpened;
6808}
bool remove(const std::string &path, bool acceptsAbsPath=true) const
Definition dir.cpp:314
bool rename(const std::string &orgName, const std::string &newName, bool acceptsAbsPath=true) const
Definition dir.cpp:321
std::ofstream openOutputStream(const QCString &name, bool append=false)
Definition portable.cpp:665

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

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

◆ parseCommentAsText()

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

Definition at line 5863 of file util.cpp.

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

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

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

◆ patternMatch()

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

Definition at line 6157 of file util.cpp.

6158{
6159 std::string elem;
6160 auto getter = [](std::string s) { return QCString(s); };
6161 return genericPatternMatch(fi,patList,elem,getter);
6162}

References genericPatternMatch().

Referenced by checkAndOpenFile(), and readDir().

◆ projectLogoFile()

QCString projectLogoFile ( )

Definition at line 3641 of file util.cpp.

3642{
3643 QCString projectLogo = Config_getString(PROJECT_LOGO);
3644 if (!projectLogo.isEmpty())
3645 {
3646 // check for optional width= and height= specifier
3647 int wi = projectLogo.find(" width=");
3648 if (wi!=-1) // and strip them
3649 {
3650 projectLogo = projectLogo.left(wi);
3651 }
3652 int hi = projectLogo.find(" height=");
3653 if (hi!=-1)
3654 {
3655 projectLogo = projectLogo.left(hi);
3656 }
3657 }
3658 //printf("projectlogo='%s'\n",qPrint(projectLogo));
3659 return projectLogo;
3660}

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

Referenced by copyLogo(), and substituteKeywords().

◆ projectLogoSize()

static QCString projectLogoSize ( )
static

Definition at line 3662 of file util.cpp.

3663{
3664 QCString sizeVal;
3665 QCString projectLogo = Config_getString(PROJECT_LOGO);
3666 if (!projectLogo.isEmpty())
3667 {
3668 auto extractDimension = [&projectLogo](const char *startMarker,size_t startPos,size_t endPos) -> QCString
3669 {
3670 QCString result = projectLogo.mid(startPos,endPos-startPos).stripWhiteSpace().quoted();
3671 if (result.length()>=2 && result.at(0)!='"' && result.at(result.length()-1)!='"')
3672 {
3673 result="\""+result+"\"";
3674 }
3675 result.prepend(startMarker);
3676 return result;
3677 };
3678 // check for optional width= and height= specifier
3679 int wi = projectLogo.find(" width=");
3680 int hi = projectLogo.find(" height=");
3681 if (wi!=-1 && hi!=-1)
3682 {
3683 if (wi<hi) // "... width=x height=y..."
3684 {
3685 sizeVal = extractDimension(" width=", wi+7, hi) + " "
3686 + extractDimension(" height=", hi+8, projectLogo.length());
3687 }
3688 else // "... height=y width=x..."
3689 {
3690 sizeVal = extractDimension(" height=", hi+8, wi) + " "
3691 + extractDimension(" width=", wi+7, projectLogo.length());
3692 }
3693 }
3694 else if (wi!=-1) // ... width=x..."
3695 {
3696 sizeVal = extractDimension(" width=", wi+7, projectLogo.length());
3697 }
3698 else if (hi!=-1) // ... height=x..."
3699 {
3700 sizeVal = extractDimension(" height=", hi+8, projectLogo.length());
3701 }
3702 }
3703 //printf("projectsize='%s'\n",qPrint(sizeVal));
3704 return sizeVal;
3705}
QCString quoted() const
Definition qcstring.h:260

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

Referenced by substituteKeywords().

◆ protectionLevelVisible()

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

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

References err, FileInfo::exists(), Debug::ExtCmd, FALSE, filterCRLF(), Debug::FilterOutput, getEncoding(), getFileFilter(), QCString::isEmpty(), Portable::openInputStream(), Portable::pclose(), Portable::popen(), Debug::print(), FileInfo::size(), QCString::str(), and transcodeCharacterBuffer().

Referenced by checkAndOpenFile(), fileToString(), HtmlDocVisitor::operator()(), RTFDocVisitor::operator()(), parseFile(), parseInput(), readIncludeFile(), DocbookDocVisitor::startPlantUmlFile(), and LatexDocVisitor::startPlantUmlFile().

◆ recognizeFixedForm()

bool recognizeFixedForm ( const QCString & contents,
FortranFormat format )

Definition at line 6830 of file util.cpp.

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

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

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

◆ recursivelyAddGroupListToTitle()

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

Definition at line 5350 of file util.cpp.

5351{
5352 ModuleDef *mod = root ? findModuleDef(d) : nullptr;
5353 if (!d->partOfGroups().empty() || mod!=nullptr) // write list of group to which this definition belongs
5354 {
5355 if (root)
5356 {
5357 ol.pushGeneratorState();
5359 ol.writeString("<div class=\"ingroups\">");
5360 }
5361 bool first=true;
5362 for (const auto &gd : d->partOfGroups())
5363 {
5364 if (!first) { ol.writeString(" &#124; "); } else first=false;
5366 {
5367 ol.writeString(" &raquo; ");
5368 }
5369 ol.writeObjectLink(gd->getReference(),gd->getOutputFileBase(),QCString(),gd->groupTitle());
5370 }
5371 if (root)
5372 {
5373 // add module as a group to the file as well
5374 if (mod)
5375 {
5376 if (!first) { ol.writeString(" &#124; "); } else first=false;
5377 ol.writeString(theTranslator->trModule(false,true)+" ");
5379 mod->displayName());
5380 }
5381 ol.writeString("</div>");
5382 ol.popGeneratorState();
5383 }
5384 return true;
5385 }
5386 return false;
5387}
virtual const GroupList & partOfGroups() const =0
virtual QCString displayName(bool includeScope=TRUE) const =0
void writeString(const QCString &text)
Definition outputlist.h:412
void pushGeneratorState()
void disableAllBut(OutputType o)
void popGeneratorState()
static ModuleDef * findModuleDef(const Definition *d)
Definition util.cpp:5321

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

4080{
4081 QCString result;
4082 if (Config_getBool(CREATE_SUBDIRS))
4083 {
4084 if (name.isEmpty())
4085 {
4086 return REL_PATH_TO_ROOT;
4087 }
4088 else
4089 {
4090 int i = name.findRev('/');
4091 if (i!=-1)
4092 {
4093 result=REL_PATH_TO_ROOT;
4094 }
4095 }
4096 }
4097 return result;
4098}
#define REL_PATH_TO_ROOT
Definition util.cpp:95

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

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

◆ removeAnonymousScopes()

QCString removeAnonymousScopes ( const QCString & str)

Removes all anonymous scopes from string s Possible examples:

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

Definition at line 172 of file util.cpp.

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

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

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

◆ removeEmptyLines()

QCString removeEmptyLines ( const QCString & s)

Definition at line 7073 of file util.cpp.

7074{
7075 std::string out;
7076 out.reserve(s.length());
7077 const char *p=s.data();
7078 if (p)
7079 {
7080 char c = 0;
7081 while ((c=*p++))
7082 {
7083 if (c=='\n')
7084 {
7085 const char *e = p;
7086 while (*e==' ' || *e=='\t') e++;
7087 if (*e=='\n')
7088 {
7089 p=e;
7090 }
7091 else out+=c;
7092 }
7093 else
7094 {
7095 out+=c;
7096 }
7097 }
7098 }
7099 //printf("removeEmptyLines(%s)=%s\n",qPrint(s),qPrint(out));
7100 return out;
7101}

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

Referenced by substituteHtmlKeywords(), and substituteLatexKeywords().

◆ removeLongPathMarker()

QCString removeLongPathMarker ( QCString path)

Definition at line 298 of file util.cpp.

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

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

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

◆ removeRedundantWhiteSpace()

QCString removeRedundantWhiteSpace ( const QCString & s)

Definition at line 578 of file util.cpp.

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

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

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

◆ replaceAnonymousScopes()

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

Definition at line 229 of file util.cpp.

230{
231 if (s.isEmpty()) return s;
232 static const reg::Ex marker(R"(@\d+)");
233 std::string result = reg::replace(s.str(),marker,
234 !replacement.isEmpty() ? replacement.data() : "__anonymous__");
235 //printf("replaceAnonymousScopes('%s')='%s'\n",qPrint(s),qPrint(result));
236 return QCString(result);
237}
std::string replace(std::string_view str, const Ex &re, std::string_view replacement)
Searching in a given input string for parts that match regular expression re and replaces those parts...
Definition regex.cpp:770

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

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

◆ replaceColorMarkers()

QCString replaceColorMarkers ( const QCString & str)

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

Definition at line 6275 of file util.cpp.

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

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

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

◆ resolveLink()

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

Definition at line 3245 of file util.cpp.

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

References FileInfo::absFilePath(), Definition::anchor(), AUTO_TRACE, AUTO_TRACE_EXIT, CSharp, 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(), Java, SectionInfo::label(), mangleCSharpGenericName(), Definition::name(), Doxygen::namespaceLinkedMap, Doxygen::pageLinkedMap, prefix, resolveRef(), QCString::str(), stripTemplateSpecifiersFromScope(), and TRUE.

Referenced by DocLink::DocLink(), and DocRef::DocRef().

◆ resolveRef()

bool resolveRef ( const QCString & scName,
const QCString & name,
bool inSeeBlock,
const Definition ** resContext,
const MemberDef ** resMember,
SrcLangExt lang,
bool lookForSpecialization,
const FileDef * currentFile,
bool checkScope )

Returns an object to reference to given its name and context

Postcondition
return value TRUE implies *resContext!=0 or *resMember!=0

Definition at line 2964 of file util.cpp.

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

References ASSERT, AUTO_TRACE, AUTO_TRACE_ADD, GetDefResult::cd, GetDefInput::checkCV, GetDefResult::cnd, Doxygen::conceptLinkedMap, CSharp, 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 384 of file util.cpp.

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

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

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

◆ rightScopeMatch()

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

Definition at line 881 of file util.cpp.

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

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

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

◆ selectBlocks()

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

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

Definition at line 6896 of file util.cpp.

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

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

Referenced by substituteHtmlKeywords(), and substituteLatexKeywords().

◆ showDate()

static QCString showDate ( const QCString & fmt)
static

Definition at line 3628 of file util.cpp.

3629{
3630 // get the current date and time
3631 std::tm dat{};
3632 int specFormat=0;
3633 QCString specDate = "";
3634 QCString err = dateTimeFromString(specDate,dat,specFormat);
3635
3636 // do the conversion
3637 int usedFormat=0;
3638 return formatDateTime(fmt,dat,usedFormat);
3639}
QCString formatDateTime(const QCString &format, const std::tm &dt, int &formatUsed)
Return a string representation for a given std::tm value that is formatted according to the pattern g...
Definition datetime.cpp:175
QCString dateTimeFromString(const QCString &spec, std::tm &dt, int &format)
Returns the filled in std::tm for a given string representing a date and/or time.
Definition datetime.cpp:134
Definition message.h:144

References dateTimeFromString(), err, and formatDateTime().

Referenced by substituteKeywords().

◆ showFileDefMatches()

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

Definition at line 3534 of file util.cpp.

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

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

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

◆ split() [1/2]

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

split input string s by regular expression delimiter delimiter.

returns a vector of non-empty strings that are between the delimiters

Definition at line 7122 of file util.cpp.

7123{
7124 StringVector result;
7125 reg::Iterator iter(s, delimiter);
7127 size_t p=0;
7128 for ( ; iter != end; ++iter)
7129 {
7130 const auto &match = *iter;
7131 size_t i=match.position();
7132 size_t l=match.length();
7133 if (i>p) result.push_back(s.substr(p,i-p));
7134 p=i+l;
7135 }
7136 if (p<s.length()) result.push_back(s.substr(p));
7137 return result;
7138}

References end().

◆ split() [2/2]

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

split input string s by string delimiter delimiter.

returns a vector of non-empty strings that are between the delimiters

Definition at line 7105 of file util.cpp.

7106{
7107 StringVector result;
7108 size_t prev = 0, pos = 0, len = s.length();
7109 do
7110 {
7111 pos = s.find(delimiter, prev);
7112 if (pos == std::string::npos) pos = len;
7113 if (pos>prev) result.push_back(s.substr(prev,pos-prev));
7114 prev = pos + delimiter.length();
7115 }
7116 while (pos<len && prev<len);
7117 return result;
7118}

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

◆ stackTrace()

void stackTrace ( )

Definition at line 5933 of file util.cpp.

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

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

◆ stripAnonymousNamespaceScope()

QCString stripAnonymousNamespaceScope ( const QCString & s)

Definition at line 241 of file util.cpp.

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

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

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

◆ stripDeclKeywords()

static QCString stripDeclKeywords ( const QCString & s)
static

Definition at line 1561 of file util.cpp.

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

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

Referenced by getCanonicalTypeForIdentifier().

◆ stripExtension()

QCString stripExtension ( const QCString & fName)

Definition at line 5421 of file util.cpp.

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

References Doxygen::htmlFileExtension, and stripExtensionGeneral().

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

◆ stripExtensionGeneral()

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

◆ stripFromIncludePath()

QCString stripFromIncludePath ( const QCString & path)

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

Definition at line 340 of file util.cpp.

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

References Config_getList, and stripFromPath().

Referenced by addIncludeFile(), and findFileDef().

◆ stripFromPath() [1/2]

static QCString stripFromPath ( const QCString & p,
const StringVector & l )
static

Definition at line 309 of file util.cpp.

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

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() [2/2]

QCString stripFromPath ( const QCString & path)

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

Definition at line 332 of file util.cpp.

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

References Config_getList, and stripFromPath().

◆ stripIndentation()

QCString stripIndentation ( const QCString & s,
bool skipFirstLine )

Definition at line 6438 of file util.cpp.

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

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

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

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

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

1552{
1553 //printf("stripIrrelevantConstVolatile(%s)=",qPrint(s));
1554 stripIrrelevantString(s,"const");
1555 stripIrrelevantString(s,"volatile");
1556 stripIrrelevantString(s,"final");
1557 //printf("%s\n",qPrint(s));
1558}
static void stripIrrelevantString(QCString &target, const QCString &str)
Definition util.cpp:1500

References stripIrrelevantString().

Referenced by extractCanonicalType(), and matchArgument2().

◆ stripIrrelevantString()

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

Definition at line 1500 of file util.cpp.

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

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
sthe string to be stripped
docLinethe line number corresponding to the start of the string. This will be adjusted based on the number of lines stripped from the start.
Returns
The stripped string.

Definition at line 5524 of file util.cpp.

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

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

5449{
5450 QCString result=s;
5451 int i=result.findRev('/');
5452 if (i!=-1)
5453 {
5454 result=result.mid(i+1);
5455 }
5456 i=result.findRev('\\');
5457 if (i!=-1)
5458 {
5459 result=result.mid(i+1);
5460 }
5461 return result;
5462}

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

Referenced by LatexGenerator::addLabel(), anonymous_namespace{tagreader.cpp}::TagFileParser::buildLists(), RTFGenerator::endDoxyAnchor(), LatexGenerator::endIndexItem(), LatexGenerator::endIndexValue(), LatexGenerator::endTitleHead(), objectLinkToString(), objectLinkToString(), objectLinkToString(), DocbookDocVisitor::operator()(), DocbookDocVisitor::operator()(), DocbookDocVisitor::operator()(), DocbookDocVisitor::operator()(), DocbookDocVisitor::operator()(), DocbookDocVisitor::operator()(), DocbookDocVisitor::operator()(), DocbookDocVisitor::operator()(), HtmlDocVisitor::operator()(), HtmlDocVisitor::operator()(), HtmlDocVisitor::operator()(), HtmlDocVisitor::operator()(), LatexDocVisitor::operator()(), LatexDocVisitor::operator()(), LatexDocVisitor::operator()(), LatexDocVisitor::operator()(), LatexDocVisitor::operator()(), LatexDocVisitor::operator()(), LatexDocVisitor::operator()(), LatexDocVisitor::operator()(), LatexDocVisitor::operator()(), RTFDocVisitor::operator()(), RTFDocVisitor::operator()(), RTFDocVisitor::operator()(), RTFDocVisitor::operator()(), RTFDocVisitor::operator()(), RTFDocVisitor::operator()(), RTFDocVisitor::operator()(), RTFDocVisitor::operator()(), XmlDocVisitor::operator()(), XmlDocVisitor::operator()(), XmlDocVisitor::operator()(), XmlDocVisitor::operator()(), XmlDocVisitor::operator()(), DotFilePatcher::run(), SearchIndexExternal::setCurrentDoc(), DocbookGenerator::startDoxyAnchor(), LatexGenerator::startDoxyAnchor(), DocbookGenerator::startFile(), LatexGenerator::startFile(), RTFGenerator::startFile(), DocbookDocVisitor::startLink(), LatexDocVisitor::startLink(), RTFDocVisitor::startLink(), DocbookGenerator::startSection(), LatexGenerator::startSection(), LatexGenerator::startTextLink(), RTFGenerator::startTextLink(), substituteHtmlKeywords(), substituteKeywords(), LatexGenerator::writeAnchor(), RTFGenerator::writeAnchor(), LatexCodeGenerator::writeCodeLink(), RTFCodeGenerator::writeCodeLink(), DocbookCodeGenerator::writeCodeLinkLine(), MemberList::writeDeclarations(), writeDocbookLink(), LatexCodeGenerator::writeLineNumber(), RTFCodeGenerator::writeLineNumber(), RTFGenerator::writeRTFReference(), and RTFGenerator::writeStartAnnoItem().

◆ stripScope()

QCString stripScope ( const QCString & name)

Strips the scope from a name. Examples: A::B will return A and A<T>::B<N::C<D> > will return A<T>.

Definition at line 4279 of file util.cpp.

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

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

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

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() [1/2]

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

Definition at line 3564 of file util.cpp.

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

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

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

◆ substituteKeywords() [2/2]

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

Definition at line 3707 of file util.cpp.

3709{
3710 return substituteKeywords(s,
3711 {
3712 // keyword value getter
3713 { "$title", [&]() { return !title.isEmpty() ? title : projName; } },
3714 { "$datetime", [&]() { return dateToString(DateTimeType::DateTime); } },
3715 { "$date", [&]() { return dateToString(DateTimeType::Date); } },
3716 { "$time", [&]() { return dateToString(DateTimeType::Time); } },
3717 { "$year", [&]() { return yearToString(); } },
3718 { "$doxygenversion", [&]() { return getDoxygenVersion(); } },
3719 { "$projectname", [&]() { return projName; } },
3720 { "$projectnumber", [&]() { return projNum; } },
3721 { "$projectbrief", [&]() { return projBrief; } },
3722 { "$projectlogo", [&]() { return stripPath(projectLogoFile()); } },
3723 { "$logosize", [&]() { return projectLogoSize(); } },
3724 { "$projecticon", [&]() { return stripPath(Config_getString(PROJECT_ICON)); } },
3725 { "$langISO", [&]() { return theTranslator->trISOLang(); } },
3726 { "$showdate", [&](const QCString &fmt) { return showDate(fmt); } }
3727 });
3728}
QCString dateToString(DateTimeType includeTime)
Returns the current date, when includeTime is set also the time is provided.
Definition datetime.cpp:63
QCString yearToString()
Returns the current year as a string.
Definition datetime.cpp:76
QCString stripPath(const QCString &s)
Definition util.cpp:5448
QCString substituteKeywords(const QCString &s, const KeywordSubstitutionList &keywords)
Definition util.cpp:3564
QCString projectLogoFile()
Definition util.cpp:3641
static QCString projectLogoSize()
Definition util.cpp:3662
static QCString showDate(const QCString &fmt)
Definition util.cpp:3628

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

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

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

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

◆ tempArgListToString()

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

Definition at line 1246 of file util.cpp.

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

References CSharp, ArgumentList::empty(), isId(), Java, removeRedundantWhiteSpace(), and QCString::right().

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

◆ transcodeCharacterBuffer()

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

Definition at line 5961 of file util.cpp.

5963{
5964 if (inputEncoding.isEmpty() || outputEncoding.isEmpty()) return; // no encoding specified
5965 if (qstricmp(inputEncoding,outputEncoding)==0) return; // input encoding same as output encoding
5966 void *cd = portable_iconv_open(outputEncoding.data(),inputEncoding.data());
5967 if (cd==reinterpret_cast<void *>(-1))
5968 {
5969 term("unsupported character conversion: '{}'->'{}': {}\n"
5970 "Check the INPUT_ENCODING setting in the config file!\n",
5971 inputEncoding,outputEncoding,strerror(errno));
5972 }
5973 size_t iLeft = contents.size();
5974 const char *srcPtr = contents.data();
5975 size_t tmpBufSize = contents.size()*4+1;
5976 size_t oLeft = tmpBufSize;
5977 std::string tmpBuf;
5978 tmpBuf.resize(tmpBufSize);
5979 char *dstPtr = tmpBuf.data();
5980 size_t newSize=0;
5981 if (!portable_iconv(cd, &srcPtr, &iLeft, &dstPtr, &oLeft))
5982 {
5983 newSize = tmpBufSize-oLeft;
5984 tmpBuf.resize(newSize);
5985 std::swap(contents,tmpBuf);
5986 //printf("iconv: input size=%d output size=%d\n[%s]\n",size,newSize,qPrint(srcBuf));
5987 }
5988 else
5989 {
5990 term("{}: failed to translate characters from {} to {}: check INPUT_ENCODING\n",
5991 fileName,inputEncoding,outputEncoding);
5992 }
5994}
int portable_iconv_close(void *cd)
size_t portable_iconv(void *cd, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft)
void * portable_iconv_open(const char *tocode, const char *fromcode)

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

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

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

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

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

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

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

◆ updateColumnCount()

size_t updateColumnCount ( const char * s,
size_t col )

Definition at line 7367 of file util.cpp.

7368{
7369 if (s)
7370 {
7371 const int tabSize = Config_getInt(TAB_SIZE);
7372 char c;
7373 while ((c=*s++))
7374 {
7375 switch(c)
7376 {
7377 case '\t': col+=tabSize - (col%tabSize);
7378 break;
7379 case '\n': col=0;
7380 break;
7381 default:
7382 col++;
7383 if (c<0) // multi-byte character
7384 {
7385 int numBytes = getUTF8CharNumBytes(c);
7386 for (int i=0;i<numBytes-1 && (c=*s++);i++) {} // skip over extra chars
7387 if (c==0) return col; // end of string half way a multibyte char
7388 }
7389 break;
7390 }
7391 }
7392 }
7393 return col;
7394}

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

5601{
5602 QCString langName = language.lower();
5603 auto it1 = std::find_if(g_lang2extMap.begin(),g_lang2extMap.end(),
5604 [&langName](const auto &info) { return info.langName==langName; });
5605 if (it1 == g_lang2extMap.end()) return false;
5606
5607 // found the language
5608 SrcLangExt parserId = it1->parserId;
5609 QCString extName = extension.lower();
5610 if (extName.isEmpty()) return FALSE;
5611 if (extName.at(0)!='.') extName.prepend(".");
5612 auto it2 = g_extLookup.find(extName.str());
5613 if (it2!=g_extLookup.end())
5614 {
5615 g_extLookup.erase(it2); // language was already register for this ext
5616 }
5617 //printf("registering extension %s\n",qPrint(extName));
5618 g_extLookup.emplace(extName.str(),parserId);
5619 if (!Doxygen::parserManager->registerExtension(extName,it1->parserName))
5620 {
5621 err("Failed to assign extension {} to parser {} for language {}\n",
5622 extName.data(),it1->parserName,language);
5623 }
5624 else
5625 {
5626 //msg("Registered extension {} to language parser {}...\n",
5627 // extName,language);
5628 }
5629 return TRUE;
5630}
SrcLangExt
Language as given by extension.
Definition types.h:42

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

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

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

Referenced by ResourceMgr::copyResourceAs().

◆ writeExamples()

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

Definition at line 1127 of file util.cpp.

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

References OutputList::disable(), Docbook, Html, Latex, Man, OutputList::popGeneratorState(), OutputList::pushGeneratorState(), RTF, theTranslator, writeMarkerList(), OutputList::writeObjectLink(), and OutputList::writeString().

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

◆ writeMarkerList()

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

Definition at line 1103 of file util.cpp.

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

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

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

◆ writePageRef()

void writePageRef ( OutputList & ol,
const QCString & cn,
const QCString & mn )

◆ writeString() [1/2]

out writeString ( lastPart ,
keepSpaces  )

References lastPart.

◆ writeString() [2/2]

out writeString ( part ,
keepSpaces  )

◆ writeTypeConstraints()

void writeTypeConstraints ( OutputList & ol,
const Definition * d,
const ArgumentList & al )

Definition at line 5911 of file util.cpp.

5912{
5913 if (al.empty()) return;
5914 ol.startConstraintList(theTranslator->trTypeConstraints());
5915 for (const Argument &a : al)
5916 {
5918 ol.parseText(a.name);
5919 ol.endConstraintParam();
5921 linkifyText(TextGeneratorOLImpl(ol),d,nullptr,nullptr,a.type);
5922 ol.endConstraintType();
5924 ol.generateDoc(d->docFile(),d->docLine(),d,nullptr,a.docs,TRUE,FALSE,
5925 QCString(),FALSE,FALSE,Config_getBool(MARKDOWN_SUPPORT));
5926 ol.endConstraintDocs();
5927 }
5928 ol.endConstraintList();
5929}
virtual int docLine() const =0
void endConstraintType()
Definition outputlist.h:713
void endConstraintList()
Definition outputlist.h:719
void startConstraintParam()
Definition outputlist.h:707
void startConstraintDocs()
Definition outputlist.h:715
void startConstraintType()
Definition outputlist.h:711
void endConstraintDocs()
Definition outputlist.h:717
void generateDoc(const QCString &fileName, int startLine, const Definition *ctx, const MemberDef *md, const QCString &docStr, bool indexWords, bool isExample, const QCString &exampleName, bool singleLine, bool linkFromIndex, bool markdownSupport)
void endConstraintParam()
Definition outputlist.h:709
void startConstraintList(const QCString &header)
Definition outputlist.h:705
Implements TextGeneratorIntf for an OutputDocInterface stream.
Definition util.h:77
void linkifyText(const TextGeneratorIntf &out, const Definition *scope, const FileDef *fileScope, const Definition *self, const QCString &text, bool autoBreak, bool external, bool keepSpaces, int indentLevel)
Definition util.cpp:904

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

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

Variable Documentation

◆ constScope

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

Definition at line 531 of file util.cpp.

531{ 'c', 'o', 'n', 's', 't', ':' };

Referenced by removeRedundantWhiteSpace().

◆ else

else
Initial value:
{
std::string_view part = txtStr.substr(skipIndex,newIndex-skipIndex)

Definition at line 973 of file util.cpp.

◆ found

bool found =FALSE

Definition at line 984 of file util.cpp.

Referenced by SearchIndex::addWordRec(), buildFunctionList(), buildTypedefList(), DocParser::checkArgumentName(), FlowChart::colTextNodes(), ClassDefImpl::containsOverload(), NamespaceLinkedRefMap::declVisible(), LatexGenerator::endIndexSection(), extractBlock(), extractCopyDocId(), extractNoExcept(), findAndRemoveWord(), findClassRelation(), findEnumDocumentation(), findFilePath(), findGlobalMember(), findMember(), findUsedClassesForClass(), HtmlDocVisitor::forceEndParagraph(), generateJSTree(), genericPatternMatch(), getDefsOld(), getFileFilter(), getFilterFromList(), getScopeFragment(), DocPara::handleCommand(), DocParser::handleImg(), hasNonReferenceNestedGroupRec(), hasNonReferenceNestedNamespaceRec(), hasNonReferenceSuperClassRec(), if(), insertPath(), ClassDefImpl::isSubClass(), VhdlDocGen::isSubClass(), lineBlock(), reg::Ex::match(), reg::Ex::Private::matchAt(), ClassDefImpl::mergeMembersFromBaseClasses(), mergeScopes(), newEntry(), normalizeNonTemplateArgumentsInString(), DocIncOperator::parse(), DocParser::processCopyDoc(), processData(), readCodeFragment(), readSVGSize(), removeIdsAndMarkers(), replaceAliases(), replaceFunctionMacro(), selectBlocks(), DefinitionImpl::setOuterScope(), skipOverFileAndLineCommands(), substituteKeywords(), substituteTemplateArgumentsInString(), substituteTemplatesInString(), LayoutNavEntry::url(), ClassLinkedRefMap::writeDeclaration(), ConceptLinkedRefMap::writeDeclaration(), ModuleLinkedRefMap::writeDeclaration(), ClassDef::writeDeclarationLink(), ClassDefAliasImpl::writeDeclarationLink(), ClassDefImpl::writeDeclarationLink(), ConceptDef::writeDeclarationLink(), ConceptDefAliasImpl::writeDeclarationLink(), ConceptDefImpl::writeDeclarationLink(), ModuleDefImpl::writeDeclarationLink(), ClassLinkedRefMap::writeDocumentation(), MemberDefImpl::writeDocumentation(), writeJavasScriptSearchDataPage(), PageDefImpl::writeTagFile(), and writeWord().

◆ g_charAroundSpace

CharAroundSpace g_charAroundSpace
static

Definition at line 575 of file util.cpp.

Referenced by removeRedundantWhiteSpace().

◆ g_extLookup

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

Definition at line 5566 of file util.cpp.

Referenced by getLanguageFromFileName(), and updateLanguageMapping().

◆ g_findFileDefCache

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

Referenced by findFileDef().

◆ g_findFileDefMutex

std::mutex g_findFileDefMutex
static

Definition at line 3406 of file util.cpp.

Referenced by findFileDef().

◆ g_lang2extMap

std::vector<Lang2ExtMap> g_lang2extMap
static
Initial value:
=
{
{ "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 5576 of file util.cpp.

5577{
5578// language parser parser option
5579 { "idl", "c", SrcLangExt::IDL, ".idl" },
5580 { "java", "c", SrcLangExt::Java, ".java"},
5581 { "javascript", "c", SrcLangExt::JS, ".js" },
5582 { "csharp", "c", SrcLangExt::CSharp, ".cs" },
5583 { "d", "c", SrcLangExt::D, ".d" },
5584 { "php", "c", SrcLangExt::PHP, ".php" },
5585 { "objective-c", "c", SrcLangExt::ObjC, ".m" },
5586 { "c", "c", SrcLangExt::Cpp, ".c" },
5587 { "c++", "c", SrcLangExt::Cpp, ".cpp" },
5588 { "slice", "c", SrcLangExt::Slice, ".ice" },
5589 { "python", "python", SrcLangExt::Python, ".py" },
5590 { "fortran", "fortran", SrcLangExt::Fortran, ".f" },
5591 { "fortranfree", "fortranfree", SrcLangExt::Fortran, ".f90" },
5592 { "fortranfixed", "fortranfixed", SrcLangExt::Fortran, ".f" },
5593 { "vhdl", "vhdl", SrcLangExt::VHDL, ".vhdl"},
5594 { "xml", "xml", SrcLangExt::XML, ".xml" },
5595 { "sql", "sql", SrcLangExt::SQL, ".sql" },
5596 { "md", "md", SrcLangExt::Markdown, ".md" },
5597 { "lex", "lex", SrcLangExt::Lex, ".l" },
5598};

Referenced by getLanguageFromCodeLang(), and updateLanguageMapping().

◆ g_matchArgsMutex

std::mutex g_matchArgsMutex
static

Definition at line 1850 of file util.cpp.

Referenced by matchArgument2().

◆ g_usedNames

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

Definition at line 3994 of file util.cpp.

Referenced by convertNameToFile().

◆ g_usedNamesCount

int g_usedNamesCount =1
static

Definition at line 3996 of file util.cpp.

Referenced by convertNameToFile().

◆ g_usedNamesMutex

std::mutex g_usedNamesMutex
static

Definition at line 3995 of file util.cpp.

Referenced by convertNameToFile().

◆ hex

const char* hex = "0123456789ABCDEF"
static

Definition at line 97 of file util.cpp.

◆ lastPart

std::string_view lastPart = txtStr.substr(skipIndex)

Definition at line 1099 of file util.cpp.

Referenced by writeString().

◆ matchWord

QCString matchWord = substitute(substitute(QCString(word),"\\","::"),".","::")

Definition at line 981 of file util.cpp.

Referenced by if().

◆ maxInheritanceDepth

const int maxInheritanceDepth = 100000

Definition at line 156 of file util.cpp.

Referenced by getDefsOld(), ClassDefImpl::getMemberByName(), and minClassDistance().

◆ operatorScope

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

Definition at line 534 of file util.cpp.

534{ 'o', 'p', 'e', 'r', 'a', 't', 'o', 'r', '?', '?', '?' };

Referenced by removeRedundantWhiteSpace().

◆ skipIndex

skipIndex =index=newIndex+matchLen

Definition at line 1095 of file util.cpp.

Referenced by if(), and linkifyText().

◆ virtualScope

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

Definition at line 533 of file util.cpp.

533{ '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 532 of file util.cpp.

532{ 'v', 'o', 'l', 'a', 't', 'i', 'l', 'e', ':' };

Referenced by removeRedundantWhiteSpace().

◆ word