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 "htmldocvisitor.h"
#include "portable.h"
#include "parserintf.h"
#include "image.h"
#include "growbuf.h"
#include "entry.h"
#include "arguments.h"
#include "memberlist.h"
#include "classlist.h"
#include "namespacedef.h"
#include "membername.h"
#include "filename.h"
#include "membergroup.h"
#include "dirdef.h"
#include "htmlentity.h"
#include "symbolresolver.h"
#include "fileinfo.h"
#include "dir.h"
#include "utf8.h"
#include "textstream.h"
#include "indexlist.h"
#include "datetime.h"
#include "moduledef.h"
#include "trace.h"
#include "stringutil.h"
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)
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 &file, const QCString &s, const KeywordSubstitutionList &keywords)
static QCString showDate (const QCString &fmt)
QCString projectLogoFile ()
static QCString projectLogoSize ()
QCString substituteKeywords (const QCString &file, const QCString &s, const QCString &title, const QCString &projName, const QCString &projNum, const QCString &projBrief)
int getPrefixIndex (const QCString &name)
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, bool keepEntities, bool singleQuotes)
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)
QCString parseCommentAsHtml (const Definition *scope, const MemberDef *member, 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)
QCString extractBeginRawStringDelimiter (const char *rawStart)
QCString extractEndRawStringDelimiter (const char *rawEnd)

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
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
static std::mutex g_docCacheMutex
static std::unordered_map< std::string, QCStringg_docCache

Macro Definition Documentation

◆ ENABLE_TRACINGSUPPORT

#define ENABLE_TRACINGSUPPORT   0

Definition at line 82 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 1854 of file util.cpp.

Referenced by matchArgument2(), and matchArguments2().

◆ NOMATCH

#define NOMATCH

Definition at line 1855 of file util.cpp.

Referenced by matchArgument2(), and matchArguments2().

◆ REL_PATH_TO_ROOT

#define REL_PATH_TO_ROOT   "../../"

Definition at line 96 of file util.cpp.

Referenced by relativePathToRoot().

Function Documentation

◆ addCodeOnlyMappings()

void addCodeOnlyMappings ( )

Definition at line 5718 of file util.cpp.

5719{
5720 updateLanguageMapping(".xml", "xml");
5721 updateLanguageMapping(".sql", "sql");
5722}
bool updateLanguageMapping(const QCString &extension, const QCString &language)
Definition util.cpp:5619

References updateLanguageMapping().

Referenced by generateOutput().

◆ addGroupListToTitle()

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

◆ addHtmlExtensionIfMissing()

void addHtmlExtensionIfMissing ( QCString & fName)

Definition at line 5418 of file util.cpp.

5419{
5420 if (fName.isEmpty()) return;
5421 int i_fs = fName.findRev('/');
5422 int i_bs = fName.findRev('\\');
5423 int i = fName.find('.',std::max({ i_fs, i_bs ,0})); // search for . after path part
5424 if (i==-1)
5425 {
5427 }
5428}
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 4613 of file util.cpp.

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

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

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

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

◆ argListToString()

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

Definition at line 1202 of file util.cpp.

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

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

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

◆ checkBlocks()

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

Definition at line 7039 of file util.cpp.

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

5414{
5415 return fName.right(ext.length())==ext;
5416}

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

5829{
5830 MemberDef *bestMatch = getMemberFromSymbol(scope,fileScope,n);
5831
5832 if (bestMatch && bestMatch->isTypedef())
5833 return TRUE; // closest matching symbol is a typedef
5834 else
5835 return FALSE;
5836}
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:5776

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

Referenced by isVarWithConstructor().

◆ clearSubDirs()

void clearSubDirs ( const Dir & d)

Definition at line 4183 of file util.cpp.

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

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

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

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

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

◆ convertCharEntitiesToUTF8()

QCString convertCharEntitiesToUTF8 ( const QCString & str)

Definition at line 4563 of file util.cpp.

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

6914{
6916 QCString parserName = Doxygen::parserManager->getParserName(ext);
6917
6918 if (parserName == "fortranfixed") return FortranFormat::Fixed;
6919 else if (parserName == "fortranfree") return FortranFormat::Free;
6920
6922}
static ParserManager * parserManager
Definition doxygen.h:131
QCString getFileNameExtension(const QCString &fn)
Definition util.cpp:5766

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

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

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

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

References Config_getBool, MemberListType::Invalid(), MemberListType::isPrivate(), MemberListType::isProtected(), MemberListType::isPublic(), MemberListType::toProtected(), and MemberListType::toPublic().

Referenced by ClassDefImpl::countInheritedDecMembers(), and ClassDefImpl::writeInheritedMemberDeclarations().

◆ convertToHtml()

QCString convertToHtml ( const QCString & s,
bool keepEntities )

Converts a string to a HTML-encoded string

Definition at line 4479 of file util.cpp.

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

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

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

◆ convertToId()

QCString convertToId ( const QCString & s)

Converts a string to a HTML id string

Definition at line 4388 of file util.cpp.

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

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

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

◆ convertToJSString()

QCString convertToJSString ( const QCString & s,
bool keepEntities,
bool singleQuotes )

Definition at line 4539 of file util.cpp.

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

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

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

◆ convertToXML()

QCString convertToXML ( const QCString & s,
bool keepEntities )

Converts a string to an XML-encoded string

Definition at line 4428 of file util.cpp.

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

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

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

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

6445{
6446 QCString result = url;
6447 if (!relPath.isEmpty() && !isURL(url))
6448 {
6449 result.prepend(relPath);
6450 }
6451 return result;
6452}
bool isURL(const QCString &url)
Checks whether the given url starts with a supported protocol.
Definition util.cpp:6432

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

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

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

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

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

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

Referenced by ClassDefImpl::className().

◆ detab()

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

Definition at line 7237 of file util.cpp.

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

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

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

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

6229{
6230 bool extLinksInWindow = Config_getBool(EXT_LINKS_IN_WINDOW);
6231 if (extLinksInWindow)
6232 return "target=\"_blank\" ";
6233 else if (parent)
6234 return "target=\"_parent\" ";
6235 else
6236 return "";
6237}
constexpr DocNodeVariant * parent(DocNodeVariant *n)
returns the parent node of a given node n or nullptr if the node has no parent.
Definition docnode.h:1330

References Config_getBool, and parent().

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

◆ externalRef()

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

Definition at line 6272 of file util.cpp.

6273{
6274 QCString result;
6275 if (!ref.isEmpty())
6276 {
6277 auto it = Doxygen::tagDestinationMap.find(ref.str());
6279 {
6280 result = it->second;
6281 size_t l = result.length();
6282 if (!relPath.isEmpty() && l>0 && result.at(0)=='.')
6283 { // relative path -> prepend relPath.
6284 result.prepend(relPath);
6285 l+=relPath.length();
6286 }
6287 if (l>0 && result.at(l-1)!='/') result+='/';
6288 if (!href) result.append("\" ");
6289 }
6290 }
6291 else
6292 {
6293 result = relPath;
6294 }
6295 return result;
6296}
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().

◆ extractBeginRawStringDelimiter()

QCString extractBeginRawStringDelimiter ( const char * rawStart)

Definition at line 7451 of file util.cpp.

7452{
7453 QCString text=rawStart;
7454 int i = text.find('"');
7455 assert(i!=-1);
7456 return text.mid(i+1,text.length()-i-2); // text=...R"xyz( -> delimiter=xyz
7457}

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

◆ extractCanonicalArgType()

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

Definition at line 1828 of file util.cpp.

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

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

Referenced by matchArgument2().

◆ extractCanonicalType()

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

Definition at line 1752 of file util.cpp.

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

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

Referenced by extractCanonicalArgType(), and getCanonicalTemplateSpec().

◆ extractClassNameFromType()

int extractClassNameFromType ( const QCString & type,
int & pos,
QCString & name,
QCString & templSpec,
SrcLangExt lang )

Extracts a (sub-)string from type starting at pos that could form a class. The index of the match is returned and the found class name and a template argument list templSpec. If -1 is returned there are no more matches.

Definition at line 4731 of file util.cpp.

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

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

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

◆ extractDirection()

QCString extractDirection ( QCString & docs)

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

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

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

Definition at line 6695 of file util.cpp.

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

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

Referenced by inlineArgListToDoc().

◆ extractEndRawStringDelimiter()

QCString extractEndRawStringDelimiter ( const char * rawEnd)

Definition at line 7459 of file util.cpp.

7460{
7461 QCString text=rawEnd;
7462 return text.mid(1,text.length()-2); // text=)xyz" -> delimiter=xyz
7463}

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

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

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

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

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

◆ fileToString()

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

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

Definition at line 1442 of file util.cpp.

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

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

6607{
6608 bool allExternals = Config_getBool(ALLEXTERNALS);
6609 bool isDocFile = fd->isDocumentationFile();
6610 genSourceFile = !isDocFile && fd->generateSourceFile();
6611 return ( ((allExternals && fd->isLinkable()) ||
6613 ) &&
6614 !isDocFile
6615 );
6616}
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()

void filterCRLF ( std::string & contents)
static

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

Definition at line 1303 of file util.cpp.

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

Referenced by readInputFile().

◆ filterTitle()

QCString filterTitle ( const QCString & title)

Definition at line 6133 of file util.cpp.

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

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

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

◆ findAndRemoveWord()

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

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

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

Definition at line 5500 of file util.cpp.

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

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

Referenced by isVarWithConstructor().

◆ findFileDef()

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

Definition at line 3417 of file util.cpp.

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

References Dir::cleanDirPath(), QCString::endsWith(), 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 3502 of file util.cpp.

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

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

7180{
7182 return reg::search(s,match,re) ? static_cast<int>(match.position()) : -1;
7183}
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 7171 of file util.cpp.

7172{
7173 auto it = std::find(sv.begin(),sv.end(),s);
7174 return it!=sv.end() ? static_cast<int>(it-sv.begin()) : -1;
7175}

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

◆ findMembersWithSpecificName()

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

Definition at line 2230 of file util.cpp.

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

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

Referenced by getDefsOld().

◆ findModuleDef()

ModuleDef * findModuleDef ( const Definition * d)
static

Definition at line 5340 of file util.cpp.

5341{
5342 ModuleDef *mod = nullptr;
5344 {
5345 const FileDef *fd = toFileDef(d);
5346 if (fd) mod = fd->getModuleDef();
5347 }
5349 {
5350 const ClassDef *cd = toClassDef(d);
5351 if (cd)
5352 {
5353 const FileDef *fd = cd->getFileDef();
5354 if (fd) mod = fd->getModuleDef();
5355 }
5356 }
5358 {
5359 const ConceptDef *cd = toConceptDef(d);
5360 if (cd)
5361 {
5362 const FileDef *fd = cd->getFileDef();
5363 if (fd) mod = fd->getModuleDef();
5364 }
5365 }
5366 return mod;
5367}
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:1939

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

Referenced by recursivelyAddGroupListToTitle().

◆ findParameterList()

int findParameterList ( const QCString & name)

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

Definition at line 837 of file util.cpp.

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

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

Referenced by resolveRef().

◆ generateAnonymousAnchor()

QCString generateAnonymousAnchor ( const QCString & fileName,
int count )

Definition at line 4074 of file util.cpp.

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

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

◆ generateFileRef()

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

Definition at line 3389 of file util.cpp.

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

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

◆ generateMarker()

QCString generateMarker ( int id)

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

Definition at line 291 of file util.cpp.

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

References qsnprintf.

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

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

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

Referenced by getEncoding(), and patternMatch().

◆ getCanonicalTemplateSpec()

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

Definition at line 1578 of file util.cpp.

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

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

Referenced by getCanonicalTypeForIdentifier().

◆ getCanonicalTypeForIdentifier()

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

Definition at line 1598 of file util.cpp.

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

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

Referenced by extractCanonicalType(), and getCanonicalTypeForIdentifier().

◆ getCaseSenseNames()

bool getCaseSenseNames ( )

Definition at line 3836 of file util.cpp.

3837{
3838 auto caseSenseNames = Config_getEnum(CASE_SENSE_NAMES);
3839
3840 if (caseSenseNames == CASE_SENSE_NAMES_t::YES) return true;
3841 else if (caseSenseNames == CASE_SENSE_NAMES_t::NO) return false;
3843}
#define Config_getEnum(name)
Definition config.h:35

References Config_getEnum, and Portable::fileSystemIsCaseSensitive().

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

◆ getDefs()

GetDefResult getDefs ( const GetDefInput & input)

Definition at line 2823 of file util.cpp.

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

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

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

◆ getDefsNew()

GetDefResult getDefsNew ( const GetDefInput & input)

Definition at line 2274 of file util.cpp.

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

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

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

Referenced by getDefs().

◆ getDotImageExtension()

QCString getDotImageExtension ( )

Definition at line 6806 of file util.cpp.

6807{
6808 QCString imgExt = Config_getEnumAsString(DOT_IMAGE_FORMAT);
6809 int i= imgExt.find(':'); // strip renderer part when using e.g. 'png:cairo:gd' as format
6810 return i==-1 ? imgExt : imgExt.left(i);
6811}
#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 6214 of file util.cpp.

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

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

Referenced by readCodeFragment(), and readInputFile().

◆ getFileFilter()

QCString getFileFilter ( const QCString & name,
bool isSourceCode )

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

Definition at line 1370 of file util.cpp.

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

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

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

◆ getFileNameExtension()

◆ getFilterFromList()

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

Definition at line 1329 of file util.cpp.

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

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

Referenced by getFileFilter().

◆ getLanguageFromCodeLang()

SrcLangExt getLanguageFromCodeLang ( QCString & fileName)

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

Definition at line 5742 of file util.cpp.

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

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

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

◆ getLanguageFromFileName()

SrcLangExt getLanguageFromFileName ( const QCString & fileName,
SrcLangExt defLang )

Definition at line 5724 of file util.cpp.

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

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

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

◆ getLanguageSpecificSeparator()

QCString getLanguageSpecificSeparator ( SrcLangExt lang,
bool classScope )

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

Definition at line 6416 of file util.cpp.

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

Referenced by DefinitionImpl::_writeSourceRefList(), addGlobalFunction(), MemberDefImpl::addListReference(), addMethodToClass(), addVariableToFile(), MemberDefImpl::displayDefinition(), DefinitionAliasImpl::init(), linkToText(), makeDisplayName(), makeDisplayName(), makeQualifiedNameWithTemplateParameters(), ClassDefImpl::mergeMembersFromBaseClasses(), DefinitionImpl::qualifiedName(), MemberDefImpl::qualifiedName(), SearchIndex::setCurrentDoc(), validatingParseDoc(), MemberDefImpl::warnIfUndocumented(), writeAlphabeticalClassList(), MemberDefImpl::writeDeclaration(), writeDefArgumentList(), MemberDefImpl::writeDocumentation(), writeJavasScriptSearchDataPage(), MemberDefImpl::writeLink(), and writeMemberReference().

◆ getMemberFromSymbol()

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

Definition at line 5776 of file util.cpp.

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

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

4606{
4607 return theTranslator->trOverloadText();
4608 //"This is an overloaded member function, "
4609 // "provided for convenience. It differs from the above "
4610 // "function only in what argument(s) it accepts.";
4611}
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 3752 of file util.cpp.

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

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

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

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

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

◆ getScopeDefs()

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

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

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

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

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

Definition at line 2891 of file util.cpp.

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

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

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

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

◆ guessSection()

EntryType guessSection ( const QCString & name)

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

Definition at line 350 of file util.cpp.

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

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

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

◆ initDefaultExtensionMapping()

void initDefaultExtensionMapping ( )

Definition at line 5651 of file util.cpp.

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

References updateLanguageMapping().

Referenced by initDoxygen().

◆ inlineArgListToDoc()

QCString inlineArgListToDoc ( const ArgumentList & al)

Definition at line 1157 of file util.cpp.

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

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

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

◆ inlineTemplateArgListToDoc()

QCString inlineTemplateArgListToDoc ( const ArgumentList & al)

Definition at line 1175 of file util.cpp.

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

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

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

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

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

◆ integerToRoman()

QCString integerToRoman ( int n,
bool upper )

Definition at line 7215 of file util.cpp.

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

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

◆ isLowerCase()

bool isLowerCase ( QCString & s)
static

Definition at line 2953 of file util.cpp.

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

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

Referenced by resolveRef().

◆ isURL()

bool isURL ( const QCString & url)

Checks whether the given url starts with a supported protocol.

Definition at line 6432 of file util.cpp.

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

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

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

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

◆ keyWordsFortranC()

bool keyWordsFortranC ( const char * contents)
static

Definition at line 6840 of file util.cpp.

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

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

Referenced by recognizeFixedForm().

◆ langToString()

QCString langToString ( SrcLangExt lang)

Returns a string representation of lang.

Definition at line 6410 of file util.cpp.

6411{
6412 return to_string(lang);
6413}
static const char * to_string(Protection prot)
Definition types.h:38

References to_string().

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

◆ leftScopeMatch()

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

Definition at line 893 of file util.cpp.

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

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

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

◆ lineBlock()

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

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

See also
routine extractBlock

Definition at line 6389 of file util.cpp.

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

References QCString::find().

Referenced by readIncludeFile().

◆ linkifyText()

void linkifyText ( const TextGeneratorIntf & out,
const Definition * scope,
const FileDef * fileScope,
const Definition * self,
const QCString & text,
bool autoBreak,
bool external,
bool keepSpaces,
int indentLevel )

Definition at line 905 of file util.cpp.

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

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

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

◆ linkToText()

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

Definition at line 3221 of file util.cpp.

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

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

6802{
6803 return Doxygen::mainPage!=nullptr && Doxygen::mainPage->hasTitle();
6804}
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 7430 of file util.cpp.

7431{
7432 int idx = name.find('<');
7433 if (idx!=-1)
7434 {
7435 return name.left(idx)+"-"+QCString().setNum(name.contains(",")+1)+"-g";
7436 }
7437 return name;
7438}
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()

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

Definition at line 1893 of file util.cpp.

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

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

Referenced by matchArguments2().

◆ matchArguments2()

bool matchArguments2 ( const Definition * srcScope,
const FileDef * srcFileScope,
const ArgumentList * srcAl,
const Definition * dstScope,
const FileDef * dstFileScope,
const ArgumentList * dstAl,
bool checkCV,
SrcLangExt lang )

Definition at line 1959 of file util.cpp.

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

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

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

◆ matchCanonicalTypes()

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

Definition at line 1861 of file util.cpp.

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

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

Referenced by matchArgument2().

◆ matchTemplateArguments()

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

Definition at line 2197 of file util.cpp.

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

References argListToString(), AUTO_TRACE, AUTO_TRACE_EXIT, ArgumentList::begin(), ArgumentList::end(), ArgumentList::size(), and Argument::type.

Referenced by buildFunctionList().

◆ mergeArguments()

void mergeArguments ( ArgumentList & srcAl,
ArgumentList & dstAl,
bool forceNameOverwrite )

Definition at line 2053 of file util.cpp.

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

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

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

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

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

◆ nextUTF8CharPosition()

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

Definition at line 5838 of file util.cpp.

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

References getUTF8CharNumBytes().

Referenced by parseCommentAsText().

◆ normalizeNonTemplateArgumentsInString()

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

Definition at line 4805 of file util.cpp.

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

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

Referenced by findUsedClassesForClass().

◆ openOutputFile()

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

Definition at line 6813 of file util.cpp.

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

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

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

◆ parseCommentAsHtml()

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

Definition at line 5933 of file util.cpp.

5934{
5935 std::lock_guard lock(g_docCacheMutex);
5936 auto it = g_docCache.find(doc.str());
5937 if (it != g_docCache.end())
5938 {
5939 //printf("Cache: [%s]->[%s]\n",qPrint(doc),qPrint(it->second));
5940 return it->second;
5941 }
5942 auto parser { createDocParser() };
5943 auto ast { validatingParseTitle(*parser.get(),fileName,lineNr,doc) };
5944 auto astImpl = dynamic_cast<const DocNodeAST*>(ast.get());
5945 QCString result;
5946 if (astImpl)
5947 {
5948 TextStream t;
5949 OutputCodeList codeList;
5950 codeList.add<HtmlCodeGenerator>(&t);
5951 HtmlDocVisitor visitor(t,codeList,scope,fileName);
5952 std::visit(visitor,astImpl->root);
5953 result = t.str();
5954 }
5955 else // fallback, should not happen
5956 {
5957 result = filterTitle(doc);
5958 }
5959 //printf("Conversion: [%s]->[%s]\n",qPrint(doc),qPrint(result));
5960 g_docCache.insert(std::make_pair(doc.str(),result));
5961 return result;
5962}
Class representing the abstract syntax tree of a documentation block.
Definition docnode.h:1466
Generator for HTML code fragments.
Definition htmlgen.h:26
Concrete visitor implementation for HTML output.
Class representing a list of different code generators.
Definition outputlist.h:164
void add(OutputCodeIntfPtr &&p)
Definition outputlist.h:194
Text streaming class that buffers data.
Definition textstream.h:36
std::string str() const
Return the contents of the buffer as a std::string object.
Definition textstream.h:229
IDocParserPtr createDocParser()
factory function to create a parser
Definition docparser.cpp:55
IDocNodeASTPtr validatingParseTitle(IDocParser &parserIntf, const QCString &fileName, int lineNr, const QCString &input)
static std::unordered_map< std::string, QCString > g_docCache
Definition util.cpp:5931
QCString filterTitle(const QCString &title)
Definition util.cpp:6133
static std::mutex g_docCacheMutex
Definition util.cpp:5930

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

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

◆ parseCommentAsText()

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

Definition at line 5882 of file util.cpp.

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

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

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

◆ patternMatch()

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

Definition at line 6207 of file util.cpp.

6208{
6209 std::string elem;
6210 auto getter = [](std::string s) { return QCString(s); };
6211 return genericPatternMatch(fi,patList,elem,getter);
6212}

References genericPatternMatch().

Referenced by checkAndOpenFile(), and readDir().

◆ projectLogoFile()

QCString projectLogoFile ( )

Definition at line 3661 of file util.cpp.

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

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

Referenced by copyLogo(), and substituteKeywords().

◆ projectLogoSize()

QCString projectLogoSize ( )
static

Definition at line 3682 of file util.cpp.

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

bool protectionLevelVisible ( Protection prot)

Definition at line 6456 of file util.cpp.

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

References Config_getBool.

Referenced by MemberDefImpl::_computeLinkableInProject(), addClassAndNestedClasses(), computeClassRelations(), MemberDefImpl::hasDetailedDescription(), ClassDefImpl::internalInsertMember(), MemberDefImpl::isBriefSectionVisible(), ClassDefImpl::isLinkableInProject(), ClassDefImpl::isVisibleInHierarchy(), MemberDefImpl::warnIfUndocumented(), MemberDefImpl::writeDeclaration(), ClassDefImpl::writeDocumentationForInnerClasses(), ClassDefImpl::writeMemberList(), and ClassDefImpl::writeTagFile().

◆ readInputFile()

bool readInputFile ( const QCString & fileName,
std::string & contents,
bool filter,
bool isSourceCode )

read a file name fileName and optionally filter and transcode it

Definition at line 6053 of file util.cpp.

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

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

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

◆ recognizeFixedForm()

bool recognizeFixedForm ( const QCString & contents,
FortranFormat format )

Definition at line 6860 of file util.cpp.

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

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

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

◆ recursivelyAddGroupListToTitle()

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

Definition at line 5369 of file util.cpp.

5370{
5371 ModuleDef *mod = root ? findModuleDef(d) : nullptr;
5372 if (!d->partOfGroups().empty() || mod!=nullptr) // write list of group to which this definition belongs
5373 {
5374 if (root)
5375 {
5376 ol.pushGeneratorState();
5378 ol.writeString("<div class=\"ingroups\">");
5379 }
5380 bool first=true;
5381 for (const auto &gd : d->partOfGroups())
5382 {
5383 if (!first) { ol.writeString(" &#124; "); } else first=false;
5385 {
5386 ol.writeString(" &raquo; ");
5387 }
5388 ol.writeObjectLink(gd->getReference(),gd->getOutputFileBase(),QCString(),gd->groupTitle());
5389 }
5390 if (root)
5391 {
5392 // add module as a group to the file as well
5393 if (mod)
5394 {
5395 if (!first) { ol.writeString(" &#124; "); } else first=false;
5396 ol.writeString(theTranslator->trModule(false,true)+" ");
5398 mod->displayName());
5399 }
5400 ol.writeString("</div>");
5401 ol.popGeneratorState();
5402 }
5403 return true;
5404 }
5405 return false;
5406}
virtual const GroupList & partOfGroups() const =0
virtual QCString displayName(bool includeScope=TRUE) const =0
void writeString(const QCString &text)
Definition outputlist.h:413
void pushGeneratorState()
void disableAllBut(OutputType o)
void popGeneratorState()
static ModuleDef * findModuleDef(const Definition *d)
Definition util.cpp:5340

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

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

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

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

◆ removeAnonymousScopes()

QCString removeAnonymousScopes ( const QCString & str)

Removes all anonymous scopes from string s Possible examples:

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

Definition at line 173 of file util.cpp.

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

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

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

◆ removeEmptyLines()

QCString removeEmptyLines ( const QCString & s)

Definition at line 7103 of file util.cpp.

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

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

Referenced by substituteHtmlKeywords(), and substituteLatexKeywords().

◆ removeLongPathMarker()

QCString removeLongPathMarker ( QCString path)

Definition at line 299 of file util.cpp.

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

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

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

◆ removeRedundantWhiteSpace()

QCString removeRedundantWhiteSpace ( const QCString & s)

Definition at line 579 of file util.cpp.

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

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

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

◆ replaceAnonymousScopes()

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

Definition at line 230 of file util.cpp.

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

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

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

◆ replaceColorMarkers()

QCString replaceColorMarkers ( const QCString & str)

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

Definition at line 6325 of file util.cpp.

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

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

References FileInfo::absFilePath(), Definition::anchor(), AUTO_TRACE, AUTO_TRACE_EXIT, SectionInfo::definition(), Doxygen::dirLinkedMap, Doxygen::exampleLinkedMap, FALSE, LinkedMap< T, Hash, KeyEqual, Map >::find(), findFileDef(), getClass(), getConcept(), PageDef::getGroupDef(), Doxygen::groupLinkedMap, Doxygen::inputNameLinkedMap, ModuleManager::instance(), SectionManager::instance(), QCString::isEmpty(), Definition::isLinkable(), SectionInfo::label(), mangleCSharpGenericName(), Definition::name(), Doxygen::namespaceLinkedMap, Doxygen::pageLinkedMap, prefix, resolveRef(), QCString::str(), stripTemplateSpecifiersFromScope(), and TRUE.

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

◆ resolveRef()

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

Returns an object to reference to given its name and context

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

Definition at line 2965 of file util.cpp.

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

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

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

◆ resolveTypeDef()

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

Definition at line 385 of file util.cpp.

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

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

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

◆ rightScopeMatch()

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

Definition at line 882 of file util.cpp.

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

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

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

◆ selectBlocks()

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

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

Definition at line 6926 of file util.cpp.

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

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

Referenced by substituteHtmlKeywords(), and substituteLatexKeywords().

◆ showDate()

QCString showDate ( const QCString & fmt)
static

Definition at line 3648 of file util.cpp.

3649{
3650 // get the current date and time
3651 std::tm dat{};
3652 int specFormat=0;
3653 QCString specDate = "";
3654 QCString err = dateTimeFromString(specDate,dat,specFormat);
3655
3656 // do the conversion
3657 int usedFormat=0;
3658 return formatDateTime(fmt,dat,usedFormat);
3659}
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 3545 of file util.cpp.

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

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

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

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

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

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

◆ stackTrace()

void stackTrace ( )

Definition at line 5989 of file util.cpp.

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

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

◆ stripAnonymousNamespaceScope()

QCString stripAnonymousNamespaceScope ( const QCString & s)

Definition at line 242 of file util.cpp.

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

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

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

◆ stripDeclKeywords()

QCString stripDeclKeywords ( const QCString & s)
static

Definition at line 1562 of file util.cpp.

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

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

Referenced by getCanonicalTypeForIdentifier().

◆ stripExtension()

QCString stripExtension ( const QCString & fName)

Definition at line 5440 of file util.cpp.

5441{
5443}
QCString stripExtensionGeneral(const QCString &fName, const QCString &ext)
Definition util.cpp:5430

References Doxygen::htmlFileExtension, and stripExtensionGeneral().

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

◆ stripExtensionGeneral()

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

◆ stripFromIncludePath()

QCString stripFromIncludePath ( const QCString & path)

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

Definition at line 341 of file util.cpp.

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

References Config_getList, and stripFromPath().

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

◆ stripFromPath() [1/2]

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

Definition at line 310 of file util.cpp.

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

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

References Config_getList, and stripFromPath().

◆ stripIndentation()

QCString stripIndentation ( const QCString & s,
bool skipFirstLine )

Definition at line 6468 of file util.cpp.

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

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

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

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

References stripIrrelevantString().

Referenced by extractCanonicalType(), and matchArgument2().

◆ stripIrrelevantString()

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

Definition at line 1501 of file util.cpp.

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

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

Referenced by stripIrrelevantConstVolatile().

◆ stripLeadingAndTrailingEmptyLines()

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

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

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

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

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

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

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

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

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

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

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 & file,
const QCString & s,
const KeywordSubstitutionList & keywords )

Definition at line 3575 of file util.cpp.

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

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

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

◆ substituteKeywords() [2/2]

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

Definition at line 3727 of file util.cpp.

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

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

◆ substituteTemplateArgumentsInString()

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

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

Definition at line 4870 of file util.cpp.

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

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

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

◆ tempArgListToString()

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

Definition at line 1247 of file util.cpp.

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

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

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

◆ transcodeCharacterBuffer()

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

Definition at line 6017 of file util.cpp.

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

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

References QCString::at(), QCString::ExplicitSize, portable_iconv(), portable_iconv_close(), portable_iconv_open(), qstricmp(), QCString::rawData(), QCString::resize(), and QCString::str().

Referenced by LayoutDocManager::parse(), and readCodeFragment().

◆ trimBaseClassScope()

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

Definition at line 1479 of file util.cpp.

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

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

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

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

◆ updateColumnCount()

size_t updateColumnCount ( const char * s,
size_t col )

Definition at line 7397 of file util.cpp.

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

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

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

References QCString::at(), QCString::data(), err, FALSE, g_extLookup, g_lang2extMap, QCString::isEmpty(), QCString::lower(), Doxygen::parserManager, QCString::prepend(), QCString::str(), and TRUE.

Referenced by addCodeOnlyMappings(), adjustConfiguration(), and initDefaultExtensionMapping().

◆ writeColoredImgData()

void writeColoredImgData ( const QCString & dir,
ColoredImgDataItem data[] )

Writes the intensity only bitmap represented by data as an image to directory dir using the colors defined by HTML_COLORSTYLE_*.

Definition at line 6301 of file util.cpp.

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

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

◆ writeExamples()

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

Definition at line 1128 of file util.cpp.

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

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

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

◆ writeMarkerList()

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

Definition at line 1104 of file util.cpp.

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

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

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

◆ writePageRef()

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

◆ writeTypeConstraints()

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

Definition at line 5967 of file util.cpp.

5968{
5969 if (al.empty()) return;
5970 ol.startConstraintList(theTranslator->trTypeConstraints());
5971 for (const Argument &a : al)
5972 {
5974 ol.parseText(a.name);
5975 ol.endConstraintParam();
5977 linkifyText(TextGeneratorOLImpl(ol),d,nullptr,nullptr,a.type);
5978 ol.endConstraintType();
5980 ol.generateDoc(d->docFile(),d->docLine(),d,nullptr,a.docs,TRUE,FALSE,
5981 QCString(),FALSE,FALSE);
5982 ol.endConstraintDocs();
5983 }
5984 ol.endConstraintList();
5985}
virtual int docLine() const =0
void endConstraintType()
Definition outputlist.h:716
void endConstraintList()
Definition outputlist.h:722
void startConstraintParam()
Definition outputlist.h:710
void startConstraintDocs()
Definition outputlist.h:718
void startConstraintType()
Definition outputlist.h:714
void endConstraintDocs()
Definition outputlist.h:720
void endConstraintParam()
Definition outputlist.h:712
void startConstraintList(const QCString &header)
Definition outputlist.h:708
void generateDoc(const QCString &fileName, int startLine, const Definition *ctx, const MemberDef *md, const QCString &docStr, bool indexWords, bool isExample, const QCString &exampleName, bool singleLine, bool linkFromIndex, bool markdownSupport=Config_getBool(MARKDOWN_SUPPORT), bool autolinkSupport=Config_getBool(AUTOLINK_SUPPORT))
Implements TextGeneratorIntf for an OutputDocInterface stream.
Definition util.h:77
void linkifyText(const TextGeneratorIntf &out, const Definition *scope, const FileDef *fileScope, const Definition *self, const QCString &text, bool autoBreak, bool external, bool keepSpaces, int indentLevel)
Definition util.cpp:905

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

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

Variable Documentation

◆ constScope

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

Definition at line 532 of file util.cpp.

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

Referenced by removeRedundantWhiteSpace().

◆ g_charAroundSpace

CharAroundSpace g_charAroundSpace
static

Definition at line 576 of file util.cpp.

Referenced by removeRedundantWhiteSpace().

◆ g_docCache

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

Definition at line 5931 of file util.cpp.

Referenced by parseCommentAsHtml().

◆ g_docCacheMutex

std::mutex g_docCacheMutex
static

Definition at line 5930 of file util.cpp.

Referenced by parseCommentAsHtml().

◆ g_extLookup

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

Definition at line 5585 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 3415 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 5595 of file util.cpp.

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

Referenced by getLanguageFromCodeLang(), and updateLanguageMapping().

◆ g_matchArgsMutex

std::mutex g_matchArgsMutex
static

Definition at line 1851 of file util.cpp.

Referenced by matchArgument2().

◆ g_usedNames

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

Definition at line 4010 of file util.cpp.

Referenced by convertNameToFile().

◆ g_usedNamesCount

int g_usedNamesCount =1
static

Definition at line 4012 of file util.cpp.

Referenced by convertNameToFile().

◆ g_usedNamesMutex

std::mutex g_usedNamesMutex
static

Definition at line 4011 of file util.cpp.

Referenced by convertNameToFile().

◆ hex

const char* hex = "0123456789ABCDEF"
static

Definition at line 98 of file util.cpp.

◆ maxInheritanceDepth

const int maxInheritanceDepth = 100000

Definition at line 157 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 535 of file util.cpp.

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

Referenced by removeRedundantWhiteSpace().

◆ virtualScope

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

Definition at line 534 of file util.cpp.

534{ 'v', 'i', 'r', 't', 'u', 'a', 'l', ':' };

Referenced by removeRedundantWhiteSpace().

◆ volatileScope

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

Definition at line 533 of file util.cpp.

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

Referenced by removeRedundantWhiteSpace().