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   AUTO_TRACE_EXIT("match at line {}",__LINE__);
#define NOMATCH   AUTO_TRACE_EXIT("no match at line {}",__LINE__);
#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, bool insideTemplate)
void stripIrrelevantConstVolatile (QCString &s, bool insideTemplate)
static QCString stripDeclKeywords (const QCString &s)
static QCString extractCanonicalType (const Definition *d, const FileDef *fs, QCString type, SrcLangExt lang, bool insideTemplate)
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 QCString &srcReturnType, const ArgumentList *srcAl, const Definition *dstScope, const FileDef *dstFileScope, const QCString &dstReturnType, const ArgumentList *dstAl, bool checkCV, SrcLangExt lang)
void mergeArguments (ArgumentList &srcAl, ArgumentList &dstAl, bool forceNameOverwrite)
bool matchTemplateArguments (const ArgumentList &srcAl, const ArgumentList &dstAl)
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"
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   AUTO_TRACE_EXIT("match at line {}",__LINE__);

Definition at line 1865 of file util.cpp.

Referenced by matchArgument2(), and matchArguments2().

◆ NOMATCH

#define NOMATCH   AUTO_TRACE_EXIT("no match at line {}",__LINE__);

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

5129{
5130 updateLanguageMapping(".xml", "xml");
5131 updateLanguageMapping(".sql", "sql");
5132}
bool updateLanguageMapping(const QCString &extension, const QCString &language)
Definition util.cpp:5029

References updateLanguageMapping().

Referenced by generateOutput().

◆ addGroupListToTitle()

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

◆ addHtmlExtensionIfMissing()

void addHtmlExtensionIfMissing ( QCString & fName)

Definition at line 4850 of file util.cpp.

4851{
4852 if (fName.isEmpty()) return;
4853 int i_fs = fName.findRev('/');
4854 int i_bs = fName.findRev('\\');
4855 int i = fName.find('.',std::max({ i_fs, i_bs ,0})); // search for . after path part
4856 if (i==-1)
4857 {
4859 }
4860}
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:163
int findRev(char c, int index=-1, bool cs=TRUE) const
Definition qcstring.cpp:96

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

4037{
4038 ASSERT(context!=nullptr);
4039 //printf("addMemberToMemberGroup() context=%s\n",qPrint(context->name()));
4040 if (ml==nullptr) return;
4041
4042 struct MoveMemberInfo
4043 {
4044 MoveMemberInfo(MemberDef *md,MemberGroup *mg,const RefItemVector &rv)
4045 : memberDef(md), memberGroup(mg), sli(rv) {}
4046 MemberDef *memberDef;
4047 MemberGroup *memberGroup;
4048 RefItemVector sli;
4049 };
4050 std::vector<MoveMemberInfo> movedMembers;
4051
4052 for (const auto &md : *ml)
4053 {
4054 if (md->isEnumerate()) // insert enum value of this enum into groups
4055 {
4056 for (const auto &fmd : md->enumFieldList())
4057 {
4058 int groupId=fmd->getMemberGroupId();
4059 if (groupId!=-1)
4060 {
4061 auto it = Doxygen::memberGroupInfoMap.find(groupId);
4063 {
4064 const auto &info = it->second;
4065 auto mg_it = std::find_if(pMemberGroups->begin(),
4066 pMemberGroups->end(),
4067 [&groupId](const auto &g)
4068 { return g->groupId()==groupId; }
4069 );
4070 MemberGroup *mg_ptr = nullptr;
4071 if (mg_it==pMemberGroups->end())
4072 {
4073 auto mg = std::make_unique<MemberGroup>(
4074 context,
4075 groupId,
4076 info->header,
4077 info->doc,
4078 info->docFile,
4079 info->docLine,
4080 ml->container());
4081 mg_ptr = mg.get();
4082 pMemberGroups->push_back(std::move(mg));
4083 }
4084 else
4085 {
4086 mg_ptr = (*mg_it).get();
4087 }
4088 mg_ptr->insertMember(fmd); // insert in member group
4090 if (fmdm)
4091 {
4092 fmdm->setMemberGroup(mg_ptr);
4093 }
4094 }
4095 }
4096 }
4097 }
4098 int groupId=md->getMemberGroupId();
4099 if (groupId!=-1)
4100 {
4101 auto it = Doxygen::memberGroupInfoMap.find(groupId);
4103 {
4104 const auto &info = it->second;
4105 auto mg_it = std::find_if(pMemberGroups->begin(),
4106 pMemberGroups->end(),
4107 [&groupId](const auto &g)
4108 { return g->groupId()==groupId; }
4109 );
4110 MemberGroup *mg_ptr = nullptr;
4111 if (mg_it==pMemberGroups->end())
4112 {
4113 auto mg = std::make_unique<MemberGroup>(
4114 context,
4115 groupId,
4116 info->header,
4117 info->doc,
4118 info->docFile,
4119 info->docLine,
4120 ml->container());
4121 mg_ptr = mg.get();
4122 pMemberGroups->push_back(std::move(mg));
4123 }
4124 else
4125 {
4126 mg_ptr = (*mg_it).get();
4127 }
4128 movedMembers.emplace_back(md,mg_ptr,info->m_sli);
4129 }
4130 }
4131 }
4132
4133 // move the members to their group
4134 for (const auto &mmi : movedMembers)
4135 {
4136 ml->remove(mmi.memberDef); // remove from member list
4137 mmi.memberGroup->insertMember(mmi.memberDef->resolveAlias()); // insert in member group
4138 mmi.memberGroup->setRefItems(mmi.sli);
4139 MemberDefMutable *rmdm = toMemberDefMutable(mmi.memberDef);
4140 if (rmdm)
4141 {
4142 rmdm->setMemberGroup(mmi.memberGroup);
4143 }
4144 }
4145}
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 4753 of file util.cpp.

4756{
4757 //printf("addRefItem(sli=%d,key=%s,prefix=%s,name=%s,title=%s,args=%s)\n",(int)sli.size(),key,prefix,name,title,args);
4758 if (!key.isEmpty() && key[0]!='@') // check for @ to skip anonymous stuff (see bug427012)
4759 {
4760 for (RefItem *item : sli)
4761 {
4762 item->setPrefix(prefix);
4763 item->setScope(scope);
4764 item->setName(name);
4765 item->setTitle(title);
4766 item->setArgs(args);
4767 item->setGroup(key);
4768 }
4769 }
4770}
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 4623 of file util.cpp.

4634{
4635 PageDef *pd=nullptr;
4636 //printf("addRelatedPage(name=%s gd=%p)\n",qPrint(name),gd);
4637 QCString title=ptitle.stripWhiteSpace();
4638 bool newPage = true;
4639 if ((pd=Doxygen::pageLinkedMap->find(name)) && !pd->isReference())
4640 {
4641 if (!xref && !title.isEmpty() && pd->title()!=pd->name() && pd->title()!=title)
4642 {
4643 warn(fileName,startLine,"multiple use of page label '{}' with different titles, (other occurrence: {}, line: {})",
4644 name,pd->docFile(),pd->getStartBodyLine());
4645 }
4646 if (!title.isEmpty() && pd->title()==pd->name()) // pd has no real title yet
4647 {
4648 pd->setTitle(title);
4650 if (si)
4651 {
4652 si->setTitle(title);
4653 }
4654 }
4655 // append documentation block to the page.
4656 pd->setDocumentation(doc,fileName,docLine);
4657 //printf("Adding page docs '%s' pi=%p name=%s\n",qPrint(doc),pd,name);
4658 // append (x)refitems to the page.
4659 pd->setRefItems(sli);
4660 newPage = false;
4661 }
4662
4663 if (newPage) // new page
4664 {
4665 QCString baseName=name;
4666 if (baseName.endsWith(".tex"))
4667 baseName=baseName.left(baseName.length()-4);
4668 else if (baseName.right(Doxygen::htmlFileExtension.length())==Doxygen::htmlFileExtension)
4669 baseName=baseName.left(baseName.length()-Doxygen::htmlFileExtension.length());
4670
4671 //printf("Appending page '%s'\n",qPrint(baseName));
4672 if (pd) // replace existing page
4673 {
4674 pd->setDocumentation(doc,fileName,docLine);
4676 pd->setShowLineNo(FALSE);
4677 pd->setNestingLevel(0);
4678 pd->setPageScope(nullptr);
4679 pd->setTitle(title);
4680 pd->setReference(QCString());
4681 }
4682 else // newPage
4683 {
4684 pd = Doxygen::pageLinkedMap->add(baseName,
4685 createPageDef(fileName,docLine,baseName,doc,title));
4686 }
4687 pd->setBodySegment(startLine,startLine,-1);
4688
4689 pd->setRefItems(sli);
4690 pd->setLanguage(lang);
4691
4692 if (tagInfo)
4693 {
4694 pd->setReference(tagInfo->tagName);
4695 pd->setFileName(tagInfo->fileName);
4696 }
4697
4698 if (gd) gd->addPage(pd);
4699
4700 if (pd->hasTitle())
4701 {
4702 //outputList->writeTitle(pi->name,pi->title);
4703
4704 // a page name is a label as well!
4705 QCString file;
4706 QCString orgFile;
4707 int line = -1;
4708 if (gd)
4709 {
4710 file=gd->getOutputFileBase();
4711 orgFile=gd->getOutputFileBase();
4712 }
4713 else
4714 {
4715 file=pd->getOutputFileBase();
4716 orgFile=pd->docFile();
4717 line = pd->getStartBodyLine();
4718 }
4719 const SectionInfo *si = SectionManager::instance().find(pd->name());
4720 if (si)
4721 {
4722 if (!si->ref().isEmpty()) // we are from a tag file
4723 {
4725 file,-1,pd->title(),SectionType::Page,0,pd->getReference());
4726 }
4727 else if (si->lineNr() != -1)
4728 {
4729 warn(orgFile,line,"multiple use of section label '{}', (first occurrence: {}, line {})",pd->name(),si->fileName(),si->lineNr());
4730 }
4731 else
4732 {
4733 warn(orgFile,line,"multiple use of section label '{}', (first occurrence: {})",pd->name(),si->fileName());
4734 }
4735 }
4736 else
4737 {
4739 file,-1,pd->title(),SectionType::Page,0,pd->getReference());
4740 //printf("si->label='%s' si->definition=%s si->fileName='%s'\n",
4741 // qPrint(si->label),si->definition?si->definition->name().data():"<none>",
4742 // qPrint(si->fileName));
4743 //printf(" SectionInfo: sec=%p sec->fileName=%s\n",si,qPrint(si->fileName));
4744 //printf("Adding section key=%s si->fileName=%s\n",qPrint(pageName),qPrint(si->fileName));
4745 }
4746 }
4747 }
4748 return pd;
4749}
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:166
bool endsWith(const char *s) const
Definition qcstring.h:524
QCString stripWhiteSpace() const
returns a copy of this string with leading and trailing whitespace removed
Definition qcstring.h:260
QCString right(size_t len) const
Definition qcstring.h:234
QCString left(size_t len) const
Definition qcstring.h:229
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:3441

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

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

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

6460{
6461 if (s.isEmpty()) return;
6462
6463 const char *p = s.data();
6464 char c = 0;
6465 while ((c=*p))
6466 {
6467 if (c==markerInfo.markerChar) // potential start of marker
6468 {
6469 if (qstrncmp(p,markerInfo.beginStr,markerInfo.beginLen)==0) // start of begin marker
6470 {
6471 size_t len = markerInfo.beginLen;
6472 bool negate = *(p+len)=='!';
6473 if (negate) len++;
6474 p += len;
6475 QCString marker;
6476 while (*p)
6477 {
6478 if (markerInfo.closeLen==0 && *p=='\n') // matching end of line
6479 {
6480 warn(fileName,-1,"Remaining begin replacement with marker '{}'",marker);
6481 break;
6482 }
6483 else if (markerInfo.closeLen!= 0 && qstrncmp(p,markerInfo.closeStr,markerInfo.closeLen)==0) // matching marker closing
6484 {
6485 p += markerInfo.closeLen;
6486 warn(fileName,-1,"Remaining begin replacement with marker '{}'",marker);
6487 break;
6488 }
6489 marker += *p;
6490 p++;
6491 }
6492 }
6493 else if (qstrncmp(p,markerInfo.endStr,markerInfo.endLen)==0) // start of end marker
6494 {
6495 size_t len = markerInfo.endLen;
6496 bool negate = *(p+len)=='!';
6497 if (negate) len++;
6498 p += len;
6499 QCString marker;
6500 while (*p)
6501 {
6502 if (markerInfo.closeLen==0 && *p=='\n') // matching end of line
6503 {
6504 warn(fileName,-1,"Remaining end replacement with marker '{}'",marker);
6505 break;
6506 }
6507 else if (markerInfo.closeLen!= 0 && qstrncmp(p,markerInfo.closeStr,markerInfo.closeLen)==0) // matching marker closing
6508 {
6509 p += markerInfo.closeLen;
6510 warn(fileName,-1,"Remaining end replacement with marker '{}'",marker);
6511 break;
6512 }
6513 marker += *p;
6514 p++;
6515 }
6516 }
6517 }
6518 p++;
6519 }
6520}
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:172
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 4845 of file util.cpp.

4846{
4847 return fName.right(ext.length())==ext;
4848}

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

5239{
5240 MemberDef *bestMatch = getMemberFromSymbol(scope,fileScope,n);
5241
5242 if (bestMatch && bestMatch->isTypedef())
5243 return TRUE; // closest matching symbol is a typedef
5244 else
5245 return FALSE;
5246}
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:5186

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

Referenced by isVarWithConstructor().

◆ clearSubDirs()

void clearSubDirs ( const Dir & d)

Definition at line 3604 of file util.cpp.

3605{
3606 if (Config_getBool(CREATE_SUBDIRS))
3607 {
3608 // remove empty subdirectories
3609 int createSubdirsLevelPow2 = 1 << Config_getInt(CREATE_SUBDIRS_LEVEL);
3610 for (int l1=0;l1<16;l1++)
3611 {
3612 QCString subdir;
3613 subdir.sprintf("d%x",l1);
3614 for (int l2=0; l2 < createSubdirsLevelPow2; l2++)
3615 {
3616 QCString subsubdir;
3617 subsubdir.sprintf("d%x/d%02x",l1,l2);
3618 if (d.exists(subsubdir.str()) && d.isEmpty(subsubdir.str()))
3619 {
3620 d.rmdir(subsubdir.str());
3621 }
3622 }
3623 if (d.exists(subdir.str()) && d.isEmpty(subdir.str()))
3624 {
3625 d.rmdir(subdir.str());
3626 }
3627 }
3628 }
3629}
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:552
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 6761 of file util.cpp.

6762{
6763 int l = static_cast<int>(name.length());
6764 int lastSepPos = -1;
6765 const char *p = name.data();
6766 int i=l-2;
6767 int sharpCount=0;
6768 // --- begin optimized version of ts=name.findRev(">::");
6769 int ts = -1;
6770 while (i>=0)
6771 {
6772 if (p[i]=='>')
6773 {
6774 if (sharpCount==0 && p[i+1]==':' && p[i+2]==':')
6775 {
6776 ts=i;
6777 break;
6778 }
6779 sharpCount++;
6780 }
6781 else if (p[i]=='<')
6782 {
6783 sharpCount--;
6784 }
6785 i--;
6786 }
6787 // --- end optimized version
6788 if (ts==-1) ts=0; else p+=++ts;
6789 for (i=ts;i<l-1;i++)
6790 {
6791 char c=*p++;
6792 if (c==':' && *p==':') lastSepPos=i;
6793 if (c=='<') break;
6794 }
6795 return lastSepPos;
6796}

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

4895{
4896 if (str.isEmpty() || word==nullptr) return false;
4897 static const reg::Ex re(R"(\a+)");
4898 std::string s = str.str();
4899 for (reg::Iterator it(s,re) ; it!=reg::Iterator() ; ++it)
4900 {
4901 if (it->str()==word) return true;
4902 }
4903 return false;
4904}
Class representing a regular expression.
Definition regex.h:39
Class to iterate through matches.
Definition regex.h:230

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

◆ convertCharEntitiesToUTF8()

QCString convertCharEntitiesToUTF8 ( const QCString & str)

Definition at line 3984 of file util.cpp.

3985{
3986 if (str.isEmpty()) return QCString();
3987
3988 std::string s = str.data();
3989 static const reg::Ex re(R"(&\a\w*;)");
3990 reg::Iterator it(s,re);
3992
3993 GrowBuf growBuf;
3994 size_t p=0, i=0, l=0;
3995 for (; it!=end ; ++it)
3996 {
3997 const auto &match = *it;
3998 p = match.position();
3999 l = match.length();
4000 if (p>i)
4001 {
4002 growBuf.addStr(s.substr(i,p-i));
4003 }
4004 QCString entity(match.str());
4006 const char *code=nullptr;
4007 if (symType!=HtmlEntityMapper::Sym_Unknown && (code=HtmlEntityMapper::instance().utf8(symType)))
4008 {
4009 growBuf.addStr(code);
4010 }
4011 else
4012 {
4013 growBuf.addStr(entity);
4014 }
4015 i=p+l;
4016 }
4017 growBuf.addStr(s.substr(i));
4018 growBuf.addChar(0);
4019 //printf("convertCharEntitiesToUTF8(%s)->%s\n",qPrint(s),growBuf.get());
4020 return growBuf.get();
4021}
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:853

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

6334{
6336 QCString parserName = Doxygen::parserManager->getParserName(ext);
6337
6338 if (parserName == "fortranfixed") return FortranFormat::Fixed;
6339 else if (parserName == "fortranfree") return FortranFormat::Free;
6340
6342}
static ParserManager * parserManager
Definition doxygen.h:131
QCString getFileNameExtension(const QCString &fn)
Definition util.cpp:5176

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

3442{
3443 if (name.isEmpty()) return name;
3444 bool shortNames = Config_getBool(SHORT_NAMES);
3445 bool createSubdirs = Config_getBool(CREATE_SUBDIRS);
3446 QCString result;
3447 if (shortNames) // use short names only
3448 {
3449 std::lock_guard<std::mutex> lock(g_usedNamesMutex);
3450 auto kv = g_usedNames.find(name.str());
3451 uint32_t num=0;
3452 if (kv!=g_usedNames.end())
3453 {
3454 num = kv->second;
3455 }
3456 else
3457 {
3458 num = g_usedNamesCount;
3459 g_usedNames.emplace(name.str(),g_usedNamesCount++);
3460 }
3461 result.sprintf("a%05d",num);
3462 }
3463 else // long names
3464 {
3465 result=escapeCharsInString(name,allowDots,allowUnderscore);
3466 size_t resultLen = result.length();
3467 if (resultLen>=128) // prevent names that cannot be created!
3468 {
3469 // third algorithm based on MD5 hash
3470 uint8_t md5_sig[16];
3471 char sigStr[33];
3472 MD5Buffer(result.data(),static_cast<unsigned int>(resultLen),md5_sig);
3473 MD5SigToString(md5_sig,sigStr);
3474 result=result.left(128-32)+sigStr;
3475 }
3476 }
3477 if (createSubdirs)
3478 {
3479 int l1Dir=0,l2Dir=0;
3480 int createSubdirsLevel = Config_getInt(CREATE_SUBDIRS_LEVEL);
3481 int createSubdirsBitmaskL2 = (1<<createSubdirsLevel)-1;
3482
3483 // compute md5 hash to determine sub directory to use
3484 uint8_t md5_sig[16];
3485 MD5Buffer(result.data(),static_cast<unsigned int>(result.length()),md5_sig);
3486 l1Dir = md5_sig[14] & 0xf;
3487 l2Dir = md5_sig[15] & createSubdirsBitmaskL2;
3488
3489 result.prepend(QCString().sprintf("d%x/d%02x/",l1Dir,l2Dir));
3490 }
3491 //printf("*** convertNameToFile(%s)->%s\n",qPrint(name),qPrint(result));
3492 return result;
3493}
QCString & prepend(const char *s)
Definition qcstring.h:422
static int g_usedNamesCount
Definition util.cpp:3433
QCString escapeCharsInString(const QCString &name, bool allowDots, bool allowUnderscore)
Definition util.cpp:3267
static std::mutex g_usedNamesMutex
Definition util.cpp:3432
static std::unordered_map< std::string, int > g_usedNames
Definition util.cpp:3431

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

6172{
6173 bool extractPrivate = Config_getBool(EXTRACT_PRIVATE);
6174
6175 // default representing 1-1 mapping
6176 *outListType1=inListType;
6177 *outListType2=MemberListType::Invalid();
6178
6179 if (inProt==Protection::Public)
6180 {
6181 if (inListType.isPrivate())
6182 {
6183 *outListType1=MemberListType::Invalid();
6184 }
6185 }
6186 else if (inProt==Protection::Protected)
6187 {
6188 if (inListType.isPrivate() || inListType.isPublic())
6189 {
6190 *outListType1=MemberListType::Invalid();
6191 }
6192 else if (inListType.isProtected())
6193 {
6194 *outListType2=inListType.toPublic();
6195 }
6196 }
6197 else if (inProt==Protection::Private)
6198 {
6199 if (inListType.isPublic() || inListType.isProtected())
6200 {
6201 *outListType1=MemberListType::Invalid();
6202 }
6203 else if (inListType.isPrivate())
6204 {
6205 if (extractPrivate)
6206 {
6207 *outListType1=inListType.toPublic();
6208 *outListType2=inListType.toProtected();
6209 }
6210 else
6211 {
6212 *outListType1=MemberListType::Invalid();
6213 }
6214 }
6215 }
6216
6217 //printf("convertProtectionLevel(type=%s prot=%d): %s,%s\n",
6218 // qPrint(inListType.to_string()),inProt,qPrint(outListType1->to_string()),qPrint(outListType2->to_string()));
6219}
constexpr bool isPrivate() const noexcept
Definition types.h:382
constexpr MemberListType toPublic() const noexcept
Definition types.h:426
static constexpr MemberListType Invalid() noexcept
Definition types.h:371
constexpr MemberListType toProtected() const noexcept
Definition types.h:438
constexpr bool isProtected() const noexcept
Definition types.h:380
ML_TYPES constexpr bool isPublic() const noexcept
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 3900 of file util.cpp.

3901{
3902 if (s.isEmpty()) return s;
3903 GrowBuf growBuf;
3904 const char *p=s.data();
3905 char c = 0;
3906 while ((c=*p++))
3907 {
3908 switch (c)
3909 {
3910 case '<': growBuf.addStr("&lt;"); break;
3911 case '>': growBuf.addStr("&gt;"); break;
3912 case '&': if (keepEntities)
3913 {
3914 const char *e=p;
3915 char ce = 0;
3916 while ((ce=*e++))
3917 {
3918 if (ce==';' || (!(isId(ce) || ce=='#'))) break;
3919 }
3920 if (ce==';') // found end of an entity
3921 {
3922 // copy entry verbatim
3923 growBuf.addChar(c);
3924 while (p<e) growBuf.addChar(*p++);
3925 }
3926 else
3927 {
3928 growBuf.addStr("&amp;");
3929 }
3930 }
3931 else
3932 {
3933 growBuf.addStr("&amp;");
3934 }
3935 break;
3936 case '\'': growBuf.addStr("&#39;"); break;
3937 case '"': growBuf.addStr("&quot;"); break;
3938 default:
3939 {
3940 uint8_t uc = static_cast<uint8_t>(c);
3941 if (uc<32 && !isspace(c))
3942 {
3943 growBuf.addStr("&#x24");
3944 growBuf.addChar(hex[uc>>4]);
3945 growBuf.addChar(hex[uc&0xF]);
3946 growBuf.addChar(';');
3947 }
3948 else
3949 {
3950 growBuf.addChar(c);
3951 }
3952 }
3953 break;
3954 }
3955 }
3956 growBuf.addChar(0);
3957 return growBuf.get();
3958}
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(), addMembersToIndex(), convertToHtmlAndTruncate(), FTVHelp::Private::generateLink(), DefinitionImpl::navigationPathAsString(), HtmlDocVisitor::operator()(), HtmlDocVisitor::operator()(), HtmlDocVisitor::operator()(), HtmlGenerator::startFile(), HtmlDocVisitor::startLink(), substituteHtmlKeywords(), writeClassTree(), writeClassTreeForList(), writeClassTreeToOutput(), 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 3809 of file util.cpp.

3810{
3811 if (s.isEmpty()) return s;
3812 GrowBuf growBuf;
3813 const char *p = s.data();
3814 char c = 0;
3815 bool first = true;
3816 while ((c=*p++))
3817 {
3818 char encChar[4];
3819 if ((c>='0' && c<='9') || (c>='a' && c<='z') || (c>='A' && c<='Z') || c=='-')
3820 { // any permissive character except _
3821 if (first && c>='0' && c<='9') growBuf.addChar('a'); // don't start with a digit
3822 growBuf.addChar(c);
3823 }
3824 else
3825 {
3826 encChar[0]='_';
3827 encChar[1]=hex[static_cast<unsigned char>(c)>>4];
3828 encChar[2]=hex[static_cast<unsigned char>(c)&0xF];
3829 encChar[3]=0;
3830 growBuf.addStr(encChar);
3831 }
3832 first=FALSE;
3833 }
3834 growBuf.addChar(0);
3835 return growBuf.get();
3836}

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

3961{
3962 if (s.isEmpty()) return s;
3963 GrowBuf growBuf;
3964 const char *p=s.data();
3965 char c = 0;
3966 while ((c=*p++))
3967 {
3968 switch (c)
3969 {
3970 case '"': if (!singleQuotes) growBuf.addStr("\\\""); else growBuf.addChar(c);
3971 break;
3972 case '\'': if (singleQuotes) growBuf.addStr("\\\'"); else growBuf.addChar(c);
3973 break;
3974 case '\\': if (*p=='u' && *(p+1)=='{') growBuf.addStr("\\"); // keep \u{..} unicode escapes
3975 else growBuf.addStr("\\\\");
3976 break;
3977 default: growBuf.addChar(c); break;
3978 }
3979 }
3980 growBuf.addChar(0);
3981 return keepEntities ? growBuf.get() : convertCharEntitiesToUTF8(growBuf.get());
3982}
QCString convertCharEntitiesToUTF8(const QCString &str)
Definition util.cpp:3984

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

3850{
3851 if (s.isEmpty()) return s;
3852 GrowBuf growBuf;
3853 const char *p = s.data();
3854 char c = 0;
3855 while ((c=*p++))
3856 {
3857 switch (c)
3858 {
3859 case '<': growBuf.addStr("&lt;"); break;
3860 case '>': growBuf.addStr("&gt;"); break;
3861 case '&': if (keepEntities)
3862 {
3863 const char *e=p;
3864 char ce = 0;
3865 while ((ce=*e++))
3866 {
3867 if (ce==';' || (!(isId(ce) || ce=='#'))) break;
3868 }
3869 if (ce==';') // found end of an entity
3870 {
3871 // copy entry verbatim
3872 growBuf.addChar(c);
3873 while (p<e) growBuf.addChar(*p++);
3874 }
3875 else
3876 {
3877 growBuf.addStr("&amp;");
3878 }
3879 }
3880 else
3881 {
3882 growBuf.addStr("&amp;");
3883 }
3884 break;
3885 case '\'': growBuf.addStr("&apos;"); break;
3886 case '"': growBuf.addStr("&quot;"); break;
3887 case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8:
3888 case 11: case 12: case 13: case 14: case 15: case 16: case 17: case 18:
3889 case 19: case 20: case 21: case 22: case 23: case 24: case 25: case 26:
3890 case 27: case 28: case 29: case 30: case 31:
3891 break; // skip invalid XML characters (see http://www.w3.org/TR/2000/REC-xml-20001006#NT-Char)
3892 default: growBuf.addChar(c); break;
3893 }
3894 }
3895 growBuf.addChar(0);
3896 return growBuf.get();
3897}

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

3843{
3844 if (s.isEmpty()) return s;
3845 return "a" + s;
3846}

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

5865{
5866 QCString result = url;
5867 if (!relPath.isEmpty() && !isURL(url))
5868 {
5869 result.prepend(relPath);
5870 }
5871 return result;
5872}
bool isURL(const QCString &url)
Checks whether the given url starts with a supported protocol.
Definition util.cpp:5852

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

5665{
5666 QCString url;
5667 if (!ref.isEmpty())
5668 {
5669 url = externalRef(relPath,ref,href);
5670 }
5671 if (!targetFileName.isEmpty())
5672 {
5673 QCString fn = targetFileName;
5674 if (ref.isEmpty())
5675 {
5676 if (!anchor.isEmpty() && isLocalFile)
5677 {
5678 fn=""; // omit file name for local links
5679 }
5680 else
5681 {
5682 url = relPath;
5683 }
5684 }
5685 url+=fn;
5686 }
5687 if (!anchor.isEmpty()) url+="#"+anchor;
5688 //printf("createHtmlUrl(relPath=%s,local=%d,target=%s,anchor=%s)=%s\n",qPrint(relPath),isLocalFile,qPrint(targetFileName),qPrint(anchor),qPrint(url));
5689 return url;
5690}
QCString externalRef(const QCString &relPath, const QCString &ref, bool href)
Definition util.cpp:5692

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

3578{
3579 if (Config_getBool(CREATE_SUBDIRS))
3580 {
3581 // create up to 4096 subdirectories
3582 int createSubdirsLevelPow2 = 1 << Config_getInt(CREATE_SUBDIRS_LEVEL);
3583 for (int l1=0; l1<16; l1++)
3584 {
3585 QCString subdir;
3586 subdir.sprintf("d%x",l1);
3587 if (!d.exists(subdir.str()) && !d.mkdir(subdir.str()))
3588 {
3589 term("Failed to create output directory '{}'\n",subdir);
3590 }
3591 for (int l2=0; l2<createSubdirsLevelPow2; l2++)
3592 {
3593 QCString subsubdir;
3594 subsubdir.sprintf("d%x/d%02x",l1,l2);
3595 if (!d.exists(subsubdir.str()) && !d.mkdir(subsubdir.str()))
3596 {
3597 term("Failed to create output directory '{}'\n",subsubdir);
3598 }
3599 }
3600 }
3601 }
3602}
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 6860 of file util.cpp.

6861{
6862 QCString result=name;
6863 if (result.endsWith("-g"))
6864 {
6865 int idx = result.find('-');
6866 result = result.left(idx)+templArgs;
6867 }
6868 return result;
6869}

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

Referenced by ClassDefImpl::className().

◆ detab()

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

Definition at line 6657 of file util.cpp.

6658{
6659 int tabSize = Config_getInt(TAB_SIZE);
6660 size_t size = s.length();
6661 GrowBuf out(size);
6662 const char *data = s.data();
6663 size_t i=0;
6664 int col=0;
6665 constexpr auto doxy_nbsp = "&_doxy_nbsp;"; // doxygen escape command for UTF-8 nbsp
6666 const int maxIndent=1000000; // value representing infinity
6667 int minIndent=maxIndent;
6668 bool skip = false;
6669 while (i<size)
6670 {
6671 char c = data[i++];
6672 switch(c)
6673 {
6674 case '\t': // expand tab
6675 {
6676 int stop = tabSize - (col%tabSize);
6677 //printf("expand at %d stop=%d\n",col,stop);
6678 col+=stop;
6679 while (stop--) out.addChar(' ');
6680 }
6681 break;
6682 case '\\':
6683 if (data[i] == '\\') // escaped command -> ignore
6684 {
6685 out.addChar(c);
6686 out.addChar(data[i++]);
6687 col+=2;
6688 }
6689 else if (i+5<size && literal_at(data+i,"iskip")) // command
6690 {
6691 i+=5;
6692 skip = true;
6693 }
6694 else if (i+8<size && literal_at(data+i,"endiskip")) // command
6695 {
6696 i+=8;
6697 skip = false;
6698 }
6699 else // some other command
6700 {
6701 out.addChar(c);
6702 col++;
6703 }
6704 break;
6705 case '\n': // reset column counter
6706 out.addChar(c);
6707 col=0;
6708 break;
6709 case ' ': // increment column counter
6710 out.addChar(c);
6711 col++;
6712 break;
6713 default: // non-whitespace => update minIndent
6714 if (c<0 && i<size) // multibyte sequence
6715 {
6716 // special handling of the UTF-8 nbsp character 0xC2 0xA0
6717 int nb = isUTF8NonBreakableSpace(data);
6718 if (nb>0)
6719 {
6720 out.addStr(doxy_nbsp);
6721 i+=nb-1;
6722 }
6723 else
6724 {
6725 int bytes = getUTF8CharNumBytes(c);
6726 for (int j=0;j<bytes-1 && c;j++)
6727 {
6728 out.addChar(c);
6729 c = data[i++];
6730 }
6731 out.addChar(c);
6732 }
6733 }
6734 else
6735 {
6736 out.addChar(c);
6737 }
6738 if (!skip && col<minIndent) minIndent=col;
6739 col++;
6740 }
6741 }
6742 if (minIndent!=maxIndent) refIndent=minIndent; else refIndent=0;
6743 out.addChar(0);
6744 //printf("detab(\n%s\n)=[\n%s\n]\n",qPrint(s),qPrint(out.get()));
6745 return out.get();
6746}
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 FileDefImpl::parseSource(), Markdown::process(), readTextFileByName(), MemberDefImpl::setInitializer(), DefinitionImpl::writeInlineCode(), and FileDefImpl::writeSourceBody().

◆ determineAbsoluteIncludeName()

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

Definition at line 3537 of file util.cpp.

3538{
3539 bool searchIncludes = Config_getBool(SEARCH_INCLUDES);
3540 QCString absIncFileName = incFileName;
3541 FileInfo fi(curFile.str());
3542 if (fi.exists())
3543 {
3544 QCString absName = fi.dirPath(TRUE)+"/"+incFileName;
3545 FileInfo fi2(absName.str());
3546 if (fi2.exists())
3547 {
3548 absIncFileName=fi2.absFilePath();
3549 }
3550 else if (searchIncludes) // search in INCLUDE_PATH as well
3551 {
3552 const StringVector &includePath = Config_getList(INCLUDE_PATH);
3553 for (const auto &incPath : includePath)
3554 {
3555 FileInfo fi3(incPath);
3556 if (fi3.exists() && fi3.isDir())
3557 {
3558 absName = fi3.absFilePath()+"/"+incFileName;
3559 //printf("trying absName=%s\n",qPrint(absName));
3560 FileInfo fi4(absName.str());
3561 if (fi4.exists())
3562 {
3563 absIncFileName=fi4.absFilePath();
3564 break;
3565 }
3566 //printf( "absIncFileName = %s\n", qPrint(absIncFileName) );
3567 }
3568 }
3569 }
3570 //printf( "absIncFileName = %s\n", qPrint(absIncFileName) );
3571 }
3572 return absIncFileName;
3573}
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 3267 of file util.cpp.

3268{
3269 if (name.isEmpty()) return name;
3270 bool caseSenseNames = getCaseSenseNames();
3271 bool allowUnicodeNames = Config_getBool(ALLOW_UNICODE_NAMES);
3272 GrowBuf growBuf;
3273 signed char c = 0;
3274 const char *p=name.data();
3275 while ((c=*p++)!=0)
3276 {
3277 switch(c)
3278 {
3279 case '_': if (allowUnderscore) growBuf.addChar('_'); else growBuf.addStr("__"); break;
3280 case '-': growBuf.addChar('-'); break;
3281 case ':': growBuf.addStr("_1"); break;
3282 case '/': growBuf.addStr("_2"); break;
3283 case '<': growBuf.addStr("_3"); break;
3284 case '>': growBuf.addStr("_4"); break;
3285 case '*': growBuf.addStr("_5"); break;
3286 case '&': growBuf.addStr("_6"); break;
3287 case '|': growBuf.addStr("_7"); break;
3288 case '.': if (allowDots) growBuf.addChar('.'); else growBuf.addStr("_8"); break;
3289 case '!': growBuf.addStr("_9"); break;
3290 case ',': growBuf.addStr("_00"); break;
3291 case ' ': growBuf.addStr("_01"); break;
3292 case '{': growBuf.addStr("_02"); break;
3293 case '}': growBuf.addStr("_03"); break;
3294 case '?': growBuf.addStr("_04"); break;
3295 case '^': growBuf.addStr("_05"); break;
3296 case '%': growBuf.addStr("_06"); break;
3297 case '(': growBuf.addStr("_07"); break;
3298 case ')': growBuf.addStr("_08"); break;
3299 case '+': growBuf.addStr("_09"); break;
3300 case '=': growBuf.addStr("_0a"); break;
3301 case '$': growBuf.addStr("_0b"); break;
3302 case '\\': growBuf.addStr("_0c"); break;
3303 case '@': growBuf.addStr("_0d"); break;
3304 case ']': growBuf.addStr("_0e"); break;
3305 case '[': growBuf.addStr("_0f"); break;
3306 case '#': growBuf.addStr("_0g"); break;
3307 case '"': growBuf.addStr("_0h"); break;
3308 case '~': growBuf.addStr("_0i"); break;
3309 case '\'': growBuf.addStr("_0j"); break;
3310 case ';': growBuf.addStr("_0k"); break;
3311 case '`': growBuf.addStr("_0l"); break;
3312 default:
3313 if (c<0)
3314 {
3315 bool doEscape = true;
3316 if (allowUnicodeNames)
3317 {
3318 int charLen = getUTF8CharNumBytes(c);
3319 if (charLen>0)
3320 {
3321 growBuf.addStr(p-1,charLen);
3322 p+=charLen;
3323 doEscape = false;
3324 }
3325 }
3326 if (doEscape) // not a valid unicode char or escaping needed
3327 {
3328 char ids[5];
3329 unsigned char id = static_cast<unsigned char>(c);
3330 ids[0]='_';
3331 ids[1]='x';
3332 ids[2]=hex[id>>4];
3333 ids[3]=hex[id&0xF];
3334 ids[4]=0;
3335 growBuf.addStr(ids);
3336 }
3337 }
3338 else if (caseSenseNames || !isupper(c))
3339 {
3340 growBuf.addChar(c);
3341 }
3342 else
3343 {
3344 growBuf.addChar('_');
3345 growBuf.addChar(static_cast<char>(tolower(c)));
3346 }
3347 break;
3348 }
3349 }
3350 growBuf.addChar(0);
3351 return growBuf.get();
3352}
bool getCaseSenseNames()
Definition util.cpp:3258

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

5649{
5650 bool extLinksInWindow = Config_getBool(EXT_LINKS_IN_WINDOW);
5651 if (extLinksInWindow)
5652 return "target=\"_blank\" ";
5653 else if (parent)
5654 return "target=\"_parent\" ";
5655 else
5656 return "";
5657}
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 5692 of file util.cpp.

5693{
5694 QCString result;
5695 if (!ref.isEmpty())
5696 {
5697 auto it = Doxygen::tagDestinationMap.find(ref.str());
5699 {
5700 result = it->second;
5701 size_t l = result.length();
5702 if (!relPath.isEmpty() && l>0 && result.at(0)=='.')
5703 { // relative path -> prepend relPath.
5704 result.prepend(relPath);
5705 l+=relPath.length();
5706 }
5707 if (l>0 && result.at(l-1)!='/') result+='/';
5708 if (!href) result.append("\" ");
5709 }
5710 }
5711 else
5712 {
5713 result = relPath;
5714 }
5715 return result;
5716}
static StringMap tagDestinationMap
Definition doxygen.h:116
char & at(size_t i)
Returns a reference to the character at index i.
Definition qcstring.h:593
QCString & append(char c)
Definition qcstring.h:396

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

6872{
6873 QCString text=rawStart;
6874 int i = text.find('"');
6875 assert(i!=-1);
6876 return text.mid(i+1,text.length()-i-2); // text=...R"xyz( -> delimiter=xyz
6877}

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

1836{
1837 QCString type = arg.type.stripWhiteSpace();
1838 QCString name = arg.name;
1839 //printf("----- extractCanonicalArgType(type=%s,name=%s)\n",qPrint(type),qPrint(name));
1840 if ((type=="const" || type=="volatile") && !name.isEmpty())
1841 { // name is part of type => correct
1842 type+=" ";
1843 type+=name;
1844 }
1845 if (name=="const" || name=="volatile")
1846 { // name is part of type => correct
1847 if (!type.isEmpty()) type+=" ";
1848 type+=name;
1849 }
1850 if (!arg.array.isEmpty())
1851 {
1852 type+=arg.array;
1853 }
1854
1855 return extractCanonicalType(d,fs,type,lang,false);
1856}
static QCString extractCanonicalType(const Definition *d, const FileDef *fs, QCString type, SrcLangExt lang, bool insideTemplate)
Definition util.cpp:1759

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,
bool insideTemplate )
static

Definition at line 1759 of file util.cpp.

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

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

4153{
4154 AUTO_TRACE("type='{}' name='{}' lang={}",type,name,lang);
4155 static const reg::Ex re_norm(R"(\a[\w:]*)");
4156 static const reg::Ex re_fortran(R"(\a[\w:()=]*)");
4157 const reg::Ex *re = &re_norm;
4158
4159 name.clear();
4160 templSpec.clear();
4161 if (type.isEmpty())
4162 {
4163 AUTO_TRACE_EXIT("empty type");
4164 return -1;
4165 }
4166 size_t typeLen=type.length();
4167 if (typeLen>0)
4168 {
4169 if (lang == SrcLangExt::Fortran)
4170 {
4171 if (type[pos]==',')
4172 {
4173 AUTO_TRACE_EXIT("comma");
4174 return -1;
4175 }
4176 if (!type.lower().startsWith("type"))
4177 {
4178 re = &re_fortran;
4179 }
4180 }
4181 std::string s = type.str();
4182 reg::Iterator it(s,*re,static_cast<int>(pos));
4184
4185 if (it!=end)
4186 {
4187 const auto &match = *it;
4188 size_t i = match.position();
4189 size_t l = match.length();
4190 size_t ts = i+l;
4191 size_t te = ts;
4192 size_t tl = 0;
4193
4194 while (ts<typeLen && type[static_cast<uint32_t>(ts)]==' ') ts++,tl++; // skip any whitespace
4195 if (ts<typeLen && type[static_cast<uint32_t>(ts)]=='<') // assume template instance
4196 {
4197 // locate end of template
4198 te=ts+1;
4199 int brCount=1;
4200 while (te<typeLen && brCount!=0)
4201 {
4202 if (type[static_cast<uint32_t>(te)]=='<')
4203 {
4204 if (te<typeLen-1 && type[static_cast<uint32_t>(te)+1]=='<') te++; else brCount++;
4205 }
4206 if (type[static_cast<uint32_t>(te)]=='>')
4207 {
4208 if (te<typeLen-1 && type[static_cast<uint32_t>(te)+1]=='>') te++; else brCount--;
4209 }
4210 te++;
4211 }
4212 }
4213 name = match.str();
4214 if (te>ts)
4215 {
4216 templSpec = QCString(type).mid(ts,te-ts);
4217 tl+=te-ts;
4218 pos=static_cast<int>(i+l+tl);
4219 }
4220 else // no template part
4221 {
4222 pos=static_cast<int>(i+l);
4223 }
4224 //printf("extractClassNameFromType([in] type=%s,[out] pos=%d,[out] name=%s,[out] templ=%s)=TRUE i=%d\n",
4225 // qPrint(type),pos,qPrint(name),qPrint(templSpec),i);
4226 AUTO_TRACE_EXIT("pos={} templSpec='{}' return={}",pos,templSpec,i);
4227 return static_cast<int>(i);
4228 }
4229 }
4230 pos = static_cast<int>(typeLen);
4231 //printf("extractClassNameFromType([in] type=%s,[out] pos=%d,[out] name=%s,[out] templ=%s)=FALSE\n",
4232 // qPrint(type),pos,qPrint(name),qPrint(templSpec));
4233 AUTO_TRACE_EXIT("not found");
4234 return -1;
4235}
bool startsWith(const char *s) const
Definition qcstring.h:507
QCString lower() const
Definition qcstring.h:249
void clear()
Definition qcstring.h:182

References AUTO_TRACE, AUTO_TRACE_EXIT, 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 6115 of file util.cpp.

6116{
6117 std::string s = docs.str();
6118 static const reg::Ex re(R"(\‍[([ inout,]+)\‍])");
6119 reg::Iterator it(s,re);
6121 if (it!=end)
6122 {
6123 const auto &match = *it;
6124 size_t p = match.position();
6125 size_t l = match.length();
6126 if (p==0 && l>2)
6127 {
6128 // make dir the part inside [...] without separators
6129 std::string dir = match[1].str();
6130 // strip , and ' ' from dir
6131 dir.erase(std::remove_if(dir.begin(),dir.end(),
6132 [](const char c) { return c==' ' || c==','; }
6133 ),dir.end());
6134 unsigned char ioMask=0;
6135 size_t inIndex = dir.find( "in");
6136 if ( inIndex!=std::string::npos) dir.erase( inIndex,2),ioMask|=(1<<0);
6137 size_t outIndex = dir.find("out");
6138 if (outIndex!=std::string::npos) dir.erase(outIndex,3),ioMask|=(1<<1);
6139 if (dir.empty() && ioMask!=0) // only in and/or out attributes found
6140 {
6141 docs = s.substr(l); // strip attributes
6142 if (ioMask==((1<<0)|(1<<1))) return "[in,out]";
6143 else if (ioMask==(1<<0)) return "[in]";
6144 else if (ioMask==(1<<1)) return "[out]";
6145 }
6146 }
6147 }
6148 return "";
6149}

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

Referenced by inlineArgListToDoc().

◆ extractEndRawStringDelimiter()

QCString extractEndRawStringDelimiter ( const char * rawEnd)

Definition at line 6879 of file util.cpp.

6880{
6881 QCString text=rawEnd;
6882 return text.mid(1,text.length()-2); // text=)xyz" -> delimiter=xyz
6883}

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

3637{
3638 int i=0, p=0;
3639 QCString clName=scopeName;
3640 NamespaceDef *nd = nullptr;
3641 if (!clName.isEmpty() && (nd=getResolvedNamespace(clName)) && getClass(clName)==nullptr)
3642 { // the whole name is a namespace (and not a class)
3643 namespaceName=nd->name();
3644 className.clear();
3645 goto done;
3646 }
3647 p=static_cast<int>(clName.length())-2;
3648 while (p>=0 && (i=clName.findRev("::",p))!=-1)
3649 // see if the first part is a namespace (and not a class)
3650 {
3651 //printf("Trying %s\n",qPrint(clName.left(i)));
3652 if (i>0 && (nd=getResolvedNamespace(clName.left(i))) && getClass(clName.left(i))==nullptr)
3653 {
3654 //printf("found!\n");
3655 namespaceName=nd->name();
3656 className=clName.right(clName.length()-i-2);
3657 goto done;
3658 }
3659 p=i-2; // try a smaller piece of the scope
3660 }
3661 //printf("not found!\n");
3662
3663 // not found, so we just have to guess.
3664 className=scopeName;
3665 namespaceName.clear();
3666
3667done:
3668 if (className.isEmpty() && !namespaceName.isEmpty() && !allowEmptyClass)
3669 {
3670 // class and namespace with the same name, correct to return the class.
3671 className=namespaceName;
3672 namespaceName.clear();
3673 }
3674 //printf("extractNamespace '%s' => '%s|%s'\n",qPrint(scopeName),
3675 // qPrint(className),qPrint(namespaceName));
3676 if (className.endsWith("-p"))
3677 {
3678 className = className.left(className.length()-2);
3679 }
3680 return;
3681}
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 1439 of file util.cpp.

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

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

6027{
6028 bool allExternals = Config_getBool(ALLEXTERNALS);
6029 bool isDocFile = fd->isDocumentationFile();
6030 genSourceFile = !isDocFile && fd->generateSourceFile();
6031 return ( ((allExternals && fd->isLinkable()) ||
6033 ) &&
6034 !isDocFile
6035 );
6036}
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 1300 of file util.cpp.

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

Referenced by readInputFile().

◆ filterTitle()

QCString filterTitle ( const QCString & title)

Definition at line 5553 of file util.cpp.

5554{
5555 std::string tf;
5556 std::string t = title.str();
5557 static const reg::Ex re(R"(%[a-z_A-Z]+)");
5558 reg::Iterator it(t,re);
5560 size_t p = 0;
5561 for (; it!=end ; ++it)
5562 {
5563 const auto &match = *it;
5564 size_t i = match.position();
5565 size_t l = match.length();
5566 if (i>p) tf+=t.substr(p,i-p);
5567 tf+=match.str().substr(1); // skip %
5568 p=i+l;
5569 }
5570 tf+=t.substr(p);
5571 return tf;
5572}

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

4911{
4912 static reg::Ex re(R"(\s*(<\a+>)\s*)");
4913 std::string s = sentence.str();
4914 reg::Iterator it(s,re);
4916 std::string result;
4917 bool found=false;
4918 size_t p=0;
4919 for ( ; it!=end ; ++it)
4920 {
4921 const auto match = *it;
4922 std::string part = match[1].str();
4923 if (part!=word)
4924 {
4925 size_t i = match.position();
4926 size_t l = match.length();
4927 result+=s.substr(p,i-p);
4928 result+=match.str();
4929 p=i+l;
4930 }
4931 else
4932 {
4933 found=true;
4934 size_t i = match[1].position();
4935 size_t l = match[1].length();
4936 result+=s.substr(p,i-p);
4937 p=i+l;
4938 }
4939 }
4940 result+=s.substr(p);
4941 sentence = QCString(result).simplifyWhiteSpace();
4942 return found;
4943}
QCString simplifyWhiteSpace() const
return a copy of this string with leading and trailing whitespace removed and multiple whitespace cha...
Definition qcstring.cpp:190

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

Referenced by isVarWithConstructor().

◆ findFileDef()

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

Definition at line 2839 of file util.cpp.

2840{
2841 ambig=FALSE;
2842 if (n.isEmpty()) return nullptr;
2843
2844
2845 const int maxAddrSize = 20;
2846 char addr[maxAddrSize];
2847 qsnprintf(addr,maxAddrSize,"%p:",reinterpret_cast<const void*>(fnMap));
2848 QCString key = addr;
2849 key+=n;
2850
2851 std::lock_guard<std::mutex> lock(g_findFileDefMutex);
2852 FindFileCacheElem *cachedResult = g_findFileDefCache.find(key.str());
2853 //printf("key=%s cachedResult=%p\n",qPrint(key),cachedResult);
2854 if (cachedResult)
2855 {
2856 ambig = cachedResult->isAmbig;
2857 //printf("cached: fileDef=%p\n",cachedResult->fileDef);
2858 return cachedResult->fileDef;
2859 }
2860 else
2861 {
2862 cachedResult = g_findFileDefCache.insert(key.str(),FindFileCacheElem(nullptr,FALSE));
2863 }
2864
2865 QCString name=Dir::cleanDirPath(n.str());
2866 QCString path;
2867 if (name.isEmpty()) return nullptr;
2868 int slashPos=std::max(name.findRev('/'),name.findRev('\\'));
2869 if (slashPos!=-1)
2870 {
2871 path=removeLongPathMarker(name.left(slashPos+1));
2872 name=name.right(name.length()-slashPos-1);
2873 }
2874 if (name.isEmpty()) return nullptr;
2875 const FileName *fn = fnMap->find(name);
2876 if (fn)
2877 {
2878 //printf("fn->size()=%zu\n",fn->size());
2879 if (fn->size()==1)
2880 {
2881 const std::unique_ptr<FileDef> &fd = fn->front();
2882 bool isSamePath = Portable::fileSystemIsCaseSensitive() ?
2883 fd->getPath().right(path.length())==path :
2884 fd->getPath().right(path.length()).lower()==path.lower();
2885 if (path.isEmpty() || isSamePath)
2886 {
2887 cachedResult->fileDef = fd.get();
2888 return fd.get();
2889 }
2890 }
2891 else // file name alone is ambiguous
2892 {
2893 int count=0;
2894 FileDef *lastMatch=nullptr;
2895 QCString pathStripped = stripFromIncludePath(path);
2896 for (const auto &fd_p : *fn)
2897 {
2898 FileDef *fd = fd_p.get();
2899 QCString fdStripPath = stripFromIncludePath(fd->getPath());
2900 if (path.isEmpty() ||
2901 (!pathStripped.isEmpty() && fdStripPath.endsWith(pathStripped)) ||
2902 (pathStripped.isEmpty() && fdStripPath.isEmpty()))
2903 {
2904 count++;
2905 lastMatch=fd;
2906 }
2907 }
2908
2909 ambig=(count>1);
2910 cachedResult->isAmbig = ambig;
2911 cachedResult->fileDef = lastMatch;
2912 return lastMatch;
2913 }
2914 }
2915 else
2916 {
2917 //printf("not found!\n");
2918 }
2919 return nullptr;
2920}
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:471
#define qsnprintf
Definition qcstring.h:49
Cache element for the file name to FileDef mapping cache.
Definition util.cpp:2829
FileDef * fileDef
Definition util.cpp:2831
QCString stripFromIncludePath(const QCString &path)
Definition util.cpp:331
static Cache< std::string, FindFileCacheElem > g_findFileDefCache(5000)
static std::mutex g_findFileDefMutex
Definition util.cpp:2837
QCString removeLongPathMarker(QCString path)
Definition util.cpp:289

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

2925{
2926 ambig=false;
2927 QCString result;
2928 bool found=false;
2929 if (!found)
2930 {
2931 FileInfo fi(file.str());
2932 if (fi.exists())
2933 {
2934 result=fi.absFilePath();
2935 found=true;
2936 }
2937 }
2938 if (!found)
2939 {
2940 const StringVector &examplePathList = Config_getList(EXAMPLE_PATH);
2941 for (const auto &s : examplePathList)
2942 {
2943 std::string absFileName = s+(Portable::pathSeparator()+file).str();
2944 FileInfo fi(absFileName);
2945 if (fi.exists())
2946 {
2947 result=fi.absFilePath();
2948 found=true;
2949 }
2950 }
2951 }
2952
2953 if (!found)
2954 {
2955 // as a fallback we also look in the exampleNameDict
2957 if (fd && !ambig)
2958 {
2959 result=fd->absFilePath();
2960 }
2961 }
2962 return result;
2963}
static FileNameLinkedMap * exampleNameLinkedMap
Definition doxygen.h:103
virtual QCString absFilePath() const =0
QCString pathSeparator()
Definition portable.cpp:375
FileDef * findFileDef(const FileNameLinkedMap *fnMap, const QCString &n, bool &ambig)
Definition util.cpp:2839

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

6600{
6602 return reg::search(s,match,re) ? static_cast<int>(match.position()) : -1;
6603}
Object representing the matching results.
Definition regex.h:151
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:842

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

6592{
6593 auto it = std::find(sv.begin(),sv.end(),s);
6594 return it!=sv.end() ? static_cast<int>(it-sv.begin()) : -1;
6595}

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

◆ findModuleDef()

ModuleDef * findModuleDef ( const Definition * d)
static

Definition at line 4772 of file util.cpp.

4773{
4774 ModuleDef *mod = nullptr;
4776 {
4777 const FileDef *fd = toFileDef(d);
4778 if (fd) mod = fd->getModuleDef();
4779 }
4781 {
4782 const ClassDef *cd = toClassDef(d);
4783 if (cd)
4784 {
4785 const FileDef *fd = cd->getFileDef();
4786 if (fd) mod = fd->getModuleDef();
4787 }
4788 }
4790 {
4791 const ConceptDef *cd = toConceptDef(d);
4792 if (cd)
4793 {
4794 const FileDef *fd = cd->getFileDef();
4795 if (fd) mod = fd->getModuleDef();
4796 }
4797 }
4798 return mod;
4799}
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:1956

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

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

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

Referenced by resolveRef().

◆ generateAnonymousAnchor()

QCString generateAnonymousAnchor ( const QCString & fileName,
int count )

Definition at line 3495 of file util.cpp.

3496{
3497 QCString fn = stripFromPath(fileName)+":"+QCString().setNum(count);
3498 const int sig_size=16;
3499 uint8_t md5_sig[sig_size];
3500 MD5Buffer(fn.data(),static_cast<unsigned int>(fn.length()),md5_sig);
3501 char result[sig_size*3+2];
3502 char *p = result;
3503 *p++='@';
3504 for (int i=0;i<sig_size;i++)
3505 {
3506 static const char oct[]="01234567";
3507 uint8_t byte = md5_sig[i];
3508 *p++=oct[(byte>>6)&7];
3509 *p++=oct[(byte>>3)&7];
3510 *p++=oct[(byte>>0)&7];
3511 }
3512 *p='\0';
3513 return result;
3514}
QCString & setNum(short n)
Definition qcstring.h:459
static QCString stripFromPath(const QCString &p, const StringVector &l)
Definition util.cpp:300

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

◆ generateFileRef()

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

Definition at line 2811 of file util.cpp.

2812{
2813 //printf("generateFileRef(%s,%s)\n",name,text);
2814 QCString linkText = text.isEmpty() ? text : name;
2815 //FileInfo *fi;
2816 bool ambig = false;
2818 if (fd && fd->isLinkable())
2819 // link to documented input file
2820 ol.writeObjectLink(fd->getReference(),fd->getOutputFileBase(),QCString(),linkText);
2821 else
2822 ol.docify(linkText);
2823}
static FileNameLinkedMap * inputNameLinkedMap
Definition doxygen.h:105
void writeObjectLink(const QCString &ref, const QCString &file, const QCString &anchor, const QCString &name)
Definition outputlist.h:439
void docify(const QCString &s)
Definition outputlist.h:437

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

282{
283 const int maxMarkerStrLen = 20;
284 char result[maxMarkerStrLen];
285 qsnprintf(result,maxMarkerStrLen,"@%d",id);
286 return result;
287}

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

5581{
5582 bool caseSenseNames = getCaseSenseNames();
5583 bool found = FALSE;
5584
5585 if (!patList.empty())
5586 {
5587 std::string fn = fi.fileName();
5588 std::string fp = fi.filePath();
5589 std::string afp= fi.absFilePath();
5590
5591 for (const auto &li : patList)
5592 {
5593 std::string pattern = getter(li).str();
5594 if (!pattern.empty())
5595 {
5596 size_t i=pattern.find('=');
5597 if (i!=std::string::npos) pattern=pattern.substr(0,i); // strip of the extension specific filter name
5598
5599 if (!caseSenseNames)
5600 {
5601 pattern = QCString(pattern).lower().str();
5602 fn = QCString(fn).lower().str();
5603 fp = QCString(fp).lower().str();
5604 afp = QCString(afp).lower().str();
5605 }
5606 reg::Ex re(pattern,reg::Ex::Mode::Wildcard);
5607 found = re.isValid() && (reg::match(fn,re) ||
5608 (fn!=fp && reg::match(fp,re)) ||
5609 (fn!=afp && fp!=afp && reg::match(afp,re)));
5610 if (found)
5611 {
5612 elem = li;
5613 break;
5614 }
5615 //printf("Matching '%s' against pattern '%s' found=%d\n",
5616 // qPrint(fi->fileName()),qPrint(pattern),found);
5617 }
5618 }
5619 }
5620 return found;
5621}
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 1584 of file util.cpp.

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

References QCString::at(), AUTO_TRACE, AUTO_TRACE_EXIT, 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 1605 of file util.cpp.

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

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

3259{
3260 auto caseSenseNames = Config_getEnum(CASE_SENSE_NAMES);
3261
3262 if (caseSenseNames == CASE_SENSE_NAMES_t::YES) return true;
3263 else if (caseSenseNames == CASE_SENSE_NAMES_t::NO) return false;
3265}
#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 2243 of file util.cpp.

2244{
2245 GetDefResult result;
2246 if (input.memberName.isEmpty()) return result;
2247 AUTO_TRACE("scopeName={},memberName={},forceEmptyScope={}",
2248 input.scopeName,input.memberName,input.forceEmptyScope);
2249
2250 //printf("@@ --- getDefsNew(%s,%s)-----------\n",qPrint(scName),qPrint(mbName));
2251 const Definition *scope = Doxygen::globalScope;
2252 SymbolResolver resolver;
2253 if (input.currentFile) resolver.setFileScope(input.currentFile);
2254 if (!input.scopeName.isEmpty() && !input.forceEmptyScope)
2255 {
2256 scope = resolver.resolveSymbol(scope,input.scopeName);
2257 }
2258 if (scope==Doxygen::globalScope)
2259 {
2260 scope = input.currentFile;
2261 }
2262 //printf("@@ -> found scope scope=%s member=%s out=%s\n",qPrint(input.scopeName),qPrint(input.memberName),qPrint(scope?scope->name():""));
2263 //
2264 const Definition *symbol = resolver.resolveSymbol(scope,input.memberName,input.args,input.checkCV,input.insideCode,true);
2265 //printf("@@ -> found symbol in=%s out=%s\n",qPrint(input.memberName),qPrint(symbol?symbol->qualifiedName():QCString()));
2266 if (symbol && symbol->definitionType()==Definition::TypeMember)
2267 {
2268 result.md = toMemberDef(symbol);
2269 result.cd = result.md->getClassDef();
2270 if (result.cd==nullptr) result.nd = result.md->getNamespaceDef();
2271 if (result.cd==nullptr && result.nd==nullptr) result.fd = result.md->getFileDef();
2272 result.gd = result.md->getGroupDef();
2273 result.found = true;
2274 }
2275 else if (symbol && symbol->definitionType()==Definition::TypeClass)
2276 {
2277 result.cd = toClassDef(symbol);
2278 result.found = true;
2279 }
2280 else if (symbol && symbol->definitionType()==Definition::TypeNamespace)
2281 {
2282 result.nd = toNamespaceDef(symbol);
2283 result.found = true;
2284 }
2285 else if (symbol && symbol->definitionType()==Definition::TypeConcept)
2286 {
2287 result.cnd = toConceptDef(symbol);
2288 result.found = true;
2289 }
2290 else if (symbol && symbol->definitionType()==Definition::TypeModule)
2291 {
2292 result.modd = toModuleDef(symbol);
2293 result.found = true;
2294 }
2295 return result;
2296}
The common base class of all entity definitions found in the sources.
Definition definition.h:76
static NamespaceDefMutable * globalScope
Definition doxygen.h:121
virtual const ClassDef * getClassDef() const =0
virtual GroupDef * getGroupDef()=0
virtual const FileDef * getFileDef() const =0
virtual const NamespaceDef * getNamespaceDef() 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 forceEmptyScope
Definition util.h:116
const FileDef * currentFile
Definition util.h:117
QCString scopeName
Definition util.h:113
bool insideCode
Definition util.h:119
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 ConceptDef * cnd
Definition util.h:130
const FileDef * fd
Definition util.h:127
const ModuleDef * modd
Definition util.h:131
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

References GetDefInput::args, AUTO_TRACE, GetDefResult::cd, GetDefInput::checkCV, GetDefResult::cnd, GetDefInput::currentFile, Definition::definitionType(), GetDefResult::fd, GetDefInput::forceEmptyScope, 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 DocParser::findDocsForMemberOrCompound(), getLinkInScope(), getLinkInScope(), linkifyText(), and resolveRef().

◆ getDotImageExtension()

QCString getDotImageExtension ( )

Definition at line 6226 of file util.cpp.

6227{
6228 QCString imgExt = Config_getEnumAsString(DOT_IMAGE_FORMAT);
6229 int i= imgExt.find(':'); // strip renderer part when using e.g. 'png:cairo:gd' as format
6230 return i==-1 ? imgExt : imgExt.left(i);
6231}
#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 5634 of file util.cpp.

5635{
5636 InputFileEncoding elem;
5637 auto getter = [](const InputFileEncoding &e) -> QCString { return e.pattern; };
5638 if (genericPatternMatch(fi,Doxygen::inputFileEncodingList,elem,getter)) // check for file specific encoding
5639 {
5640 return elem.encoding;
5641 }
5642 else // fall back to default encoding
5643 {
5644 return Config_getString(INPUT_ENCODING);
5645 }
5646}
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:5577

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

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

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

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

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

5153{
5154 // try the extension
5155 auto lang = getLanguageFromFileName(fileName, SrcLangExt::Unknown);
5156 if (lang == SrcLangExt::Unknown)
5157 {
5158 // try the language names
5159 QCString langName = fileName.lower();
5160 if (langName.at(0)=='.') langName = langName.mid(1);
5161 auto it = std::find_if(g_lang2extMap.begin(),g_lang2extMap.end(),
5162 [&langName](const auto &info) { return info.langName==langName; });
5163 if (it != g_lang2extMap.end())
5164 {
5165 lang = it->parserId;
5166 fileName = it->defExt;
5167 }
5168 else // default to C++
5169 {
5170 return SrcLangExt::Cpp;
5171 }
5172 }
5173 return lang;
5174}
SrcLangExt getLanguageFromFileName(const QCString &fileName, SrcLangExt defLang)
Definition util.cpp:5134
static std::vector< Lang2ExtMap > g_lang2extMap
Definition util.cpp:5005

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

5135{
5136 FileInfo fi(fileName.str());
5137 // we need only the part after the last ".", newer implementations of FileInfo have 'suffix()' for this.
5138 QCString extName = QCString(fi.extension(FALSE)).lower();
5139 if (extName.isEmpty()) extName=".no_extension";
5140 if (extName.at(0)!='.') extName.prepend(".");
5141 auto it = g_extLookup.find(extName.str());
5142 if (it!=g_extLookup.end()) // listed extension
5143 {
5144 //printf("getLanguageFromFileName(%s)=%x\n",qPrint(fi.extension()),*pVal);
5145 return it->second;
5146 }
5147 //printf("getLanguageFromFileName(%s) not found!\n",qPrint(fileName));
5148 return defLang; // not listed => assume C-ish language.
5149}
static std::unordered_map< std::string, SrcLangExt > g_extLookup
Definition util.cpp:4995

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

5837{
5838 if (lang==SrcLangExt::Java || lang==SrcLangExt::CSharp || lang==SrcLangExt::VHDL || lang==SrcLangExt::Python)
5839 {
5840 return ".";
5841 }
5842 else if (lang==SrcLangExt::PHP && !classScope)
5843 {
5844 return "\\";
5845 }
5846 else
5847 {
5848 return "::";
5849 }
5850}

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

5188{
5189 if (scope==nullptr ||
5192 )
5193 )
5194 {
5196 }
5197
5198 QCString name = n;
5199 if (name.isEmpty())
5200 return nullptr; // no name was given
5201
5202 auto &range = Doxygen::symbolMap->find(name);
5203 if (range.empty())
5204 return nullptr; // could not find any matching symbols
5205
5206 // mostly copied from getResolvedClassRec()
5207 QCString explicitScopePart;
5208 int qualifierIndex = computeQualifiedIndex(name);
5209 if (qualifierIndex!=-1)
5210 {
5211 explicitScopePart = name.left(qualifierIndex);
5212 replaceNamespaceAliases(explicitScopePart);
5213 name = name.mid(qualifierIndex+2);
5214 }
5215 //printf("explicitScopePart=%s\n",qPrint(explicitScopePart));
5216
5217 int minDistance = 10000;
5218 MemberDef *bestMatch = nullptr;
5219
5220 for (Definition *d : range)
5221 {
5222 if (d->definitionType()==Definition::TypeMember)
5223 {
5224 SymbolResolver resolver(fileScope);
5225 int distance = resolver.isAccessibleFromWithExpScope(scope,d,explicitScopePart);
5226 if (distance!=-1 && distance<minDistance)
5227 {
5228 minDistance = distance;
5229 bestMatch = toMemberDef(d);
5230 //printf("new best match %s distance=%d\n",qPrint(bestMatch->qualifiedName()),distance);
5231 }
5232 }
5233 }
5234 return bestMatch;
5235}
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:6761

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

4027{
4028 return theTranslator->trOverloadText();
4029 //"This is an overloaded member function, "
4030 // "provided for convenience. It differs from the above "
4031 // "function only in what argument(s) it accepts.";
4032}
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 3174 of file util.cpp.

3175{
3176 if (name.isEmpty()) return 0;
3177 const StringVector &sl = Config_getList(IGNORE_PREFIX);
3178 for (const auto &s : sl)
3179 {
3180 const char *ps=s.c_str();
3181 const char *pd=name.data();
3182 int i=0;
3183 while (*ps!=0 && *pd!=0 && *ps==*pd) ps++,pd++,i++;
3184 if (*ps==0 && *pd!=0)
3185 {
3186 return i;
3187 }
3188 }
3189 return 0;
3190}

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

6749{
6750 QCString projectCookie = Config_getString(HTML_PROJECT_COOKIE);
6751 if (projectCookie.isEmpty()) return QCString();
6752 uint8_t md5_sig[16];
6753 char sigStr[34];
6754 MD5Buffer(projectCookie.data(),static_cast<unsigned int>(projectCookie.length()),md5_sig);
6755 MD5SigToString(md5_sig,sigStr);
6756 sigStr[32]='_'; sigStr[33]=0;
6757 return sigStr;
6758}

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

2315{
2316 cd=nullptr;
2317 cnd=nullptr;
2318 nd=nullptr;
2319 modd=nullptr;
2320
2321 QCString scopeName=scope;
2322 //printf("getScopeDefs: docScope='%s' scope='%s'\n",qPrint(docScope),qPrint(scope));
2323 if (scopeName.isEmpty()) return FALSE;
2324
2325 bool explicitGlobalScope=FALSE;
2326 if (scopeName.at(0)==':' && scopeName.at(1)==':')
2327 {
2328 scopeName=scopeName.right(scopeName.length()-2);
2329 explicitGlobalScope=TRUE;
2330 }
2331 if (scopeName.isEmpty())
2332 {
2333 return FALSE;
2334 }
2335
2336 QCString docScopeName=docScope;
2337 int scopeOffset=explicitGlobalScope ? 0 : static_cast<int>(docScopeName.length());
2338
2339 do // for each possible docScope (from largest to and including empty)
2340 {
2341 QCString fullName=scopeName;
2342 if (scopeOffset>0) fullName.prepend(docScopeName.left(scopeOffset)+"::");
2343
2344 if (((cd=getClass(fullName)) || // normal class
2345 (cd=getClass(fullName+"-p")) // ObjC protocol
2346 ) && cd->isLinkable())
2347 {
2348 return TRUE; // class link written => quit
2349 }
2350 else if ((nd=Doxygen::namespaceLinkedMap->find(fullName)) && nd->isLinkable())
2351 {
2352 return TRUE; // namespace link written => quit
2353 }
2354 else if ((cnd=Doxygen::conceptLinkedMap->find(fullName)) && cnd->isLinkable())
2355 {
2356 return TRUE; // concept link written => quit
2357 }
2358 else if ((modd=ModuleManager::instance().modules().find(fullName)) && modd->isLinkable())
2359 {
2360 return TRUE; // module link written => quit
2361 }
2362 if (scopeOffset==0)
2363 {
2364 scopeOffset=-1;
2365 }
2366 else if ((scopeOffset=docScopeName.findRev("::",scopeOffset-1))==-1)
2367 {
2368 scopeOffset=0;
2369 }
2370 } while (scopeOffset>=0);
2371
2372 return FALSE;
2373}
static NamespaceLinkedMap * namespaceLinkedMap
Definition doxygen.h:115
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 4576 of file util.cpp.

4577{
4578 int sl=static_cast<int>(s.length());
4579 int sp=p;
4580 int count=0;
4581 bool done=false;
4582 if (sp>=sl) return -1;
4583 while (sp<sl)
4584 {
4585 char c=s.at(sp);
4586 if (c==':') sp++,p++; else break;
4587 }
4588 while (sp<sl)
4589 {
4590 char c=s.at(sp);
4591 switch (c)
4592 {
4593 case ':': // found next part
4594 goto found;
4595 case '<': // skip template specifier
4596 count=1;sp++;
4597 done=false;
4598 while (sp<sl && !done)
4599 {
4600 // TODO: deal with << and >> operators!
4601 c=s.at(sp++);
4602 switch(c)
4603 {
4604 case '<': count++; break;
4605 case '>': count--; if (count==0) done=true; break;
4606 default: break;
4607 }
4608 }
4609 break;
4610 default:
4611 sp++;
4612 break;
4613 }
4614 }
4615found:
4616 *l=sp-p;
4617 //printf("getScopeFragment(%s,%d)=%s\n",qPrint(s),p,qPrint(s.mid(p,*l)));
4618 return p;
4619}

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

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

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

5062{
5063 // NOTE: when adding an extension, also add the extension in config.xml
5064 // extension parser id
5065 updateLanguageMapping(".dox", "c");
5066 updateLanguageMapping(".txt", "c"); // see bug 760836
5067 updateLanguageMapping(".doc", "c");
5068 updateLanguageMapping(".c", "c");
5069 updateLanguageMapping(".C", "c");
5070 updateLanguageMapping(".cc", "c");
5071 updateLanguageMapping(".CC", "c");
5072 updateLanguageMapping(".cxx", "c");
5073 updateLanguageMapping(".cpp", "c");
5074 updateLanguageMapping(".c++", "c");
5075 updateLanguageMapping(".cxxm", "c"); // C++20 modules
5076 updateLanguageMapping(".cppm", "c"); // C++20 modules
5077 updateLanguageMapping(".ccm", "c"); // C++20 modules
5078 updateLanguageMapping(".c++m", "c"); // C++20 modules
5079 updateLanguageMapping(".ii", "c");
5080 updateLanguageMapping(".ixx", "c");
5081 updateLanguageMapping(".ipp", "c");
5082 updateLanguageMapping(".i++", "c");
5083 updateLanguageMapping(".inl", "c");
5084 updateLanguageMapping(".h", "c");
5085 updateLanguageMapping(".H", "c");
5086 updateLanguageMapping(".hh", "c");
5087 updateLanguageMapping(".HH", "c");
5088 updateLanguageMapping(".hxx", "c");
5089 updateLanguageMapping(".hpp", "c");
5090 updateLanguageMapping(".h++", "c");
5091 updateLanguageMapping(".idl", "idl");
5092 updateLanguageMapping(".ddl", "idl");
5093 updateLanguageMapping(".odl", "idl");
5094 updateLanguageMapping(".java", "java");
5095 //updateLanguageMapping(".as", "javascript"); // not officially supported
5096 //updateLanguageMapping(".js", "javascript"); // not officially supported
5097 updateLanguageMapping(".cs", "csharp");
5098 updateLanguageMapping(".d", "d");
5099 updateLanguageMapping(".php", "php");
5100 updateLanguageMapping(".php4", "php");
5101 updateLanguageMapping(".php5", "php");
5102 updateLanguageMapping(".inc", "php");
5103 updateLanguageMapping(".phtml", "php");
5104 updateLanguageMapping(".m", "objective-c");
5105 updateLanguageMapping(".M", "objective-c");
5106 updateLanguageMapping(".mm", "c"); // see bug746361
5107 updateLanguageMapping(".py", "python");
5108 updateLanguageMapping(".pyw", "python");
5109 updateLanguageMapping(".f", "fortran");
5110 updateLanguageMapping(".for", "fortran");
5111 updateLanguageMapping(".f90", "fortran");
5112 updateLanguageMapping(".f95", "fortran");
5113 updateLanguageMapping(".f03", "fortran");
5114 updateLanguageMapping(".f08", "fortran");
5115 updateLanguageMapping(".f18", "fortran");
5116 updateLanguageMapping(".vhd", "vhdl");
5117 updateLanguageMapping(".vhdl", "vhdl");
5118 updateLanguageMapping(".ucf", "vhdl");
5119 updateLanguageMapping(".qsf", "vhdl");
5120 updateLanguageMapping(".md", "md");
5121 updateLanguageMapping(".markdown", "md");
5122 updateLanguageMapping(".ice", "slice");
5123 updateLanguageMapping(".l", "lex");
5124 updateLanguageMapping(".doxygen_lex_c", "c"); // this is a placeholder so we can map initializations
5125 // in the lex scanning to cpp
5126}

References updateLanguageMapping().

Referenced by initDoxygen().

◆ inlineArgListToDoc()

QCString inlineArgListToDoc ( const ArgumentList & al)

Definition at line 1154 of file util.cpp.

1155{
1156 QCString paramDocs;
1157 if (al.hasDocumentation())
1158 {
1159 for (const Argument &a : al)
1160 {
1161 if (a.hasDocumentation())
1162 {
1163 QCString docsWithoutDir = a.docs;
1164 QCString direction = extractDirection(docsWithoutDir);
1165 paramDocs+=" \\ilinebr @param"+direction+" "+a.name+" "+docsWithoutDir;
1166 }
1167 }
1168 }
1169 return paramDocs;
1170}
bool hasDocumentation() const
Definition arguments.cpp:22
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:6115

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

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

◆ inlineTemplateArgListToDoc()

QCString inlineTemplateArgListToDoc ( const ArgumentList & al)

Definition at line 1172 of file util.cpp.

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

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

3684{
3685 QCString result=scope;
3686 if (!templ.isEmpty() && scope.find('<')==-1)
3687 {
3688 int si=0, pi=0;
3689 ClassDef *cd=nullptr;
3690 while (
3691 (si=scope.find("::",pi))!=-1 && !getClass(scope.left(si)+templ) &&
3692 ((cd=getClass(scope.left(si)))==nullptr || cd->templateArguments().empty())
3693 )
3694 {
3695 //printf("Tried '%s'\n",qPrint((scope.left(si)+templ)));
3696 pi=si+2;
3697 }
3698 if (si==-1) // not nested => append template specifier
3699 {
3700 result+=templ;
3701 }
3702 else // nested => insert template specifier before after first class name
3703 {
3704 result=scope.left(si) + templ + scope.right(scope.length()-si);
3705 }
3706 }
3707 //printf("insertTemplateSpecifierInScope('%s','%s')=%s\n",
3708 // qPrint(scope),qPrint(templ),qPrint(result));
3709 return result;
3710}
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 6619 of file util.cpp.

6620{
6621 QCString result;
6622 int residual = n;
6623
6624 char modVal[2];
6625 modVal[1] = 0;
6626 while (residual > 0)
6627 {
6628 modVal[0] = (upper ? 'A': 'a') + (residual-1)%26;
6629 result = modVal + result;
6630 residual = (residual-1) / 26;
6631 }
6632 return result;
6633}

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

◆ integerToRoman()

QCString integerToRoman ( int n,
bool upper )

Definition at line 6635 of file util.cpp.

6636{
6637 static const char *str_romans_upper[] = { "M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I" };
6638 static const char *str_romans_lower[] = { "m", "cm", "d", "cd", "c", "xc", "l", "xl", "x", "ix", "v", "iv", "i" };
6639 static const int values[] = { 1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1 };
6640 static const char **str_romans = upper ? str_romans_upper : str_romans_lower;
6641
6642 QCString result;
6643 int residual = n;
6644
6645 for (int i = 0; i < 13; ++i)
6646 {
6647 while (residual - values[i] >= 0)
6648 {
6649 result += str_romans[i];
6650 residual -= values[i];
6651 }
6652 }
6653
6654 return result;
6655}

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

◆ isLowerCase()

bool isLowerCase ( QCString & s)
static

Definition at line 2375 of file util.cpp.

2376{
2377 if (s.isEmpty()) return true;
2378 const char *p=s.data();
2379 int c=0;
2380 while ((c=static_cast<uint8_t>(*p++))) if (!islower(c)) return false;
2381 return true;
2382}

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

5853{
5854 static const std::unordered_set<std::string> schemes = {
5855 "http", "https", "ftp", "ftps", "sftp", "file", "news", "irc", "ircs"
5856 };
5857 QCString loc_url = url.stripWhiteSpace();
5858 int colonPos = loc_url.find(':');
5859 return colonPos!=-1 && schemes.find(loc_url.left(colonPos).str())!=schemes.end();
5860}

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

6607{
6608 std::string result;
6609 bool first=true;
6610 for (const auto &s : sv)
6611 {
6612 if (!first) result+=delimiter;
6613 first=false;
6614 result+=s;
6615 }
6616 return result;
6617}

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

◆ keyWordsFortranC()

bool keyWordsFortranC ( const char * contents)
static

Definition at line 6260 of file util.cpp.

6261{
6262 static const std::unordered_set<std::string> fortran_C_keywords = {
6263 "character", "call", "close", "common", "continue",
6264 "case", "contains", "cycle", "class", "codimension",
6265 "concurrent", "contiguous", "critical"
6266 };
6267
6268 if (*contents != 'c' && *contents != 'C') return false;
6269
6270 const char *c = contents;
6271 QCString keyword;
6272 while (*c && *c != ' ') {keyword += *c; c++;}
6273 keyword = keyword.lower();
6274
6275 return (fortran_C_keywords.find(keyword.str()) != fortran_C_keywords.end());
6276}

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

Referenced by recognizeFixedForm().

◆ langToString()

QCString langToString ( SrcLangExt lang)

Returns a string representation of lang.

Definition at line 5830 of file util.cpp.

5831{
5832 return to_string(lang);
5833}
static constexpr const char * to_string(Protection prot) noexcept
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 883 of file util.cpp.

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

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

5810{
5811 int result = 1;
5812
5813 // find the character positions of the first marker
5814 int m1 = text.find(marker);
5815 if (m1==-1) return result;
5816
5817 // find start line positions for the markers
5818 bool found=false;
5819 int p=0, i=0;
5820 while (!found && (i=text.find('\n',p))!=-1)
5821 {
5822 found = (p<=m1 && m1<i); // found the line with the start marker
5823 p=i+1;
5824 result++;
5825 }
5826 return result;
5827}

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

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

References Definition::anchor(), AUTO_TRACE, 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(), SymbolResolver::resolveSymbol(), 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 2643 of file util.cpp.

2644{
2645 //bool optimizeOutputJava = Config_getBool(OPTIMIZE_OUTPUT_JAVA);
2646 QCString result=link;
2647 if (!result.isEmpty())
2648 {
2649 // replace # by ::
2650 result=substitute(result,"#","::");
2651 // replace . by ::
2652 if (!isFileName && result.find('<')==-1) result=substitute(result,".","::",3);
2653 // strip leading :: prefix if present
2654 if (result.at(0)==':' && result.at(1)==':')
2655 {
2656 result=result.right(result.length()-2);
2657 }
2659 if (sep!="::")
2660 {
2661 result=substitute(result,"::",sep);
2662 }
2663 }
2664 //printf("linkToText(%s,lang=%d)=%s\n",qPrint(link),lang,qPrint(result));
2665 return result;
2666}
QCString getLanguageSpecificSeparator(SrcLangExt lang, bool classScope)
Returns the scope separator to use given the programming language lang.
Definition util.cpp:5836

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

6222{
6223 return Doxygen::mainPage!=nullptr && Doxygen::mainPage->hasTitle();
6224}
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 6850 of file util.cpp.

6851{
6852 int idx = name.find('<');
6853 if (idx!=-1)
6854 {
6855 return name.left(idx)+"-"+QCString().setNum(name.contains(",")+1)+"-g";
6856 }
6857 return name;
6858}
int contains(char c, bool cs=TRUE) const
Definition qcstring.cpp:148

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

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

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 QCString & srcReturnType,
const ArgumentList * srcAl,
const Definition * dstScope,
const FileDef * dstFileScope,
const QCString & dstReturnType,
const ArgumentList * dstAl,
bool checkCV,
SrcLangExt lang )

Definition at line 1966 of file util.cpp.

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

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(), ArgumentList::trailingReturnType(), TRUE, Argument::type, and ArgumentList::volatileSpecifier().

Referenced by addMemberDocs(), addMemberFunction(), buildFunctionList(), combineDeclarationAndDefinition(), computeMemberRelationsForBaseClass(), ClassDefImpl::containsOverload(), findFriends(), findGlobalMember(), findMember(), 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 1868 of file util.cpp.

1872{
1873 AUTO_TRACE("srcType='{}' dstType='{}'",srcType,dstType);
1874 if (srcType==dstType) return true;
1875
1876 // check if the types are function pointers
1877 int i1=srcType.find(")(");
1878 if (i1==-1) return false;
1879 int i2=dstType.find(")(");
1880 if (i1!=i2) return false;
1881
1882 // check if the result part of the function pointer types matches
1883 int j1=srcType.find("(");
1884 if (j1==-1 || j1>i1) return false;
1885 int j2=dstType.find("(");
1886 if (j2!=j1) return false;
1887 if (srcType.left(j1)!=dstType.left(j2)) return false; // different return types
1888
1889 // if srcType and dstType are both function pointers with the same return type,
1890 // then match against the parameter lists.
1891 // This way srcType='void (*fptr)(int x)' will match against `void (*fptr)(int y)' because
1892 // 'int x' matches 'int y'. A simple literal string match would treat these as different.
1893 auto srcAl = stringToArgumentList(lang,srcType.mid(i1+1));
1894 auto dstAl = stringToArgumentList(lang,dstType.mid(i2+1));
1895 return matchArguments2(srcScope,srcFileScope,srcType.left(j1),srcAl.get(),
1896 dstScope,dstFileScope,dstType.left(j2),dstAl.get(),
1897 true,lang);
1898}
std::unique_ptr< ArgumentList > stringToArgumentList(SrcLangExt lang, const QCString &argsString, QCString *extraTypeChars=nullptr)
Definition defargs.l:822
bool matchArguments2(const Definition *srcScope, const FileDef *srcFileScope, const QCString &srcReturnType, const ArgumentList *srcAl, const Definition *dstScope, const FileDef *dstFileScope, const QCString &dstReturnType, const ArgumentList *dstAl, bool checkCV, SrcLangExt lang)
Definition util.cpp:1966

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

2211{
2212 AUTO_TRACE("srcAl={} dstAl={}",argListToString(srcAl),argListToString(dstAl));
2213 if (srcAl.size()!=dstAl.size()) // different number of template parameters -> overload
2214 {
2215 AUTO_TRACE_EXIT("different number of parameters");
2216 return false;
2217 }
2218 auto isUnconstraintTemplate = [](const QCString &type)
2219 {
2220 return type=="typename" || type=="class" || type.startsWith("typename ") || type.startsWith("class ");
2221 };
2222 auto srcIt = srcAl.begin();
2223 auto dstIt = dstAl.begin();
2224 while (srcIt!=srcAl.end() && dstIt!=dstAl.end())
2225 {
2226 const Argument &srcA = *srcIt;
2227 const Argument &dstA = *dstIt;
2228 if ((!isUnconstraintTemplate(srcA.type) || !isUnconstraintTemplate(dstA.type)) && srcA.type!=dstA.type) // different constraints -> overload
2229 {
2230 AUTO_TRACE_EXIT("different constraints");
2231 return false;
2232 }
2233 ++srcIt;
2234 ++dstIt;
2235 }
2236 AUTO_TRACE_EXIT("same");
2237 // no overload with respect to the template parameters
2238 return true;
2239}

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

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

6799{
6800 if (Config_getBool(CALL_GRAPH) !=md1->hasCallGraph()) md2->overrideCallGraph(md1->hasCallGraph());
6801 if (Config_getBool(CALLER_GRAPH)!=md1->hasCallerGraph()) md2->overrideCallerGraph(md1->hasCallerGraph());
6802 if (Config_getBool(CALL_GRAPH) !=md2->hasCallGraph()) md1->overrideCallGraph( md2->hasCallGraph());
6803 if (Config_getBool(CALLER_GRAPH)!=md2->hasCallerGraph()) md1->overrideCallerGraph(md2->hasCallerGraph());
6804
6805 if (Config_getBool(SHOW_ENUM_VALUES) !=md1->hasEnumValues()) md2->overrideEnumValues(md1->hasEnumValues());
6806 if (Config_getBool(SHOW_ENUM_VALUES) !=md2->hasEnumValues()) md1->overrideEnumValues( md2->hasEnumValues());
6807
6808 if (Config_getBool(REFERENCED_BY_RELATION)!=md1->hasReferencedByRelation()) md2->overrideReferencedByRelation(md1->hasReferencedByRelation());
6809 if (Config_getBool(REFERENCES_RELATION) !=md1->hasReferencesRelation()) md2->overrideReferencesRelation(md1->hasReferencesRelation());
6810 if (Config_getBool(REFERENCED_BY_RELATION)!=md2->hasReferencedByRelation()) md1->overrideReferencedByRelation(md2->hasReferencedByRelation());
6811 if (Config_getBool(REFERENCES_RELATION) !=md2->hasReferencesRelation()) md1->overrideReferencesRelation(md2->hasReferencesRelation());
6812
6813 if (Config_getBool(INLINE_SOURCES)!=md1->hasInlineSource()) md2->overrideInlineSource(md1->hasInlineSource());
6814 if (Config_getBool(INLINE_SOURCES)!=md2->hasInlineSource()) md1->overrideInlineSource(md2->hasInlineSource());
6815}
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 4531 of file util.cpp.

4532{
4533 AUTO_TRACE("leftScope='{}' rightScope='{}'",leftScope,rightScope);
4534 // case leftScope=="A" rightScope=="A::B" => result = "A::B"
4535 if (leftScopeMatch(leftScope,rightScope))
4536 {
4537 AUTO_TRACE_EXIT("case1={}",rightScope);
4538 return rightScope;
4539 }
4540 QCString result;
4541 int i=0,p=static_cast<int>(leftScope.length());
4542
4543 // case leftScope=="A::B" rightScope=="B::C" => result = "A::B::C"
4544 // case leftScope=="A::B" rightScope=="B" => result = "A::B"
4545 bool found=FALSE;
4546 while ((i=leftScope.findRev("::",p))>0)
4547 {
4548 if (leftScopeMatch(rightScope,leftScope.right(leftScope.length()-i-2)))
4549 {
4550 result = leftScope.left(i+2)+rightScope;
4551 found=TRUE;
4552 }
4553 p=i-1;
4554 }
4555 if (found)
4556 {
4557 AUTO_TRACE_EXIT("case2={}",result);
4558 return result;
4559 }
4560
4561 // case leftScope=="A" rightScope=="B" => result = "A::B"
4562 result=leftScope;
4563 if (!result.isEmpty() && !rightScope.isEmpty()) result+="::";
4564 result+=rightScope;
4565 AUTO_TRACE_EXIT("case3={}",result);
4566 return result;
4567}
bool leftScopeMatch(const QCString &scope, const QCString &name)
Definition util.cpp:883

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

5249{
5250 if (startPos>=len) return len;
5251 uint8_t c = static_cast<uint8_t>(utf8Str[startPos]);
5252 int bytes=getUTF8CharNumBytes(c);
5253 if (c=='&') // skip over character entities
5254 {
5255 bytes=1;
5256 int (*matcher)(int) = nullptr;
5257 c = static_cast<uint8_t>(utf8Str[startPos+bytes]);
5258 if (c=='#') // numerical entity?
5259 {
5260 bytes++;
5261 c = static_cast<uint8_t>(utf8Str[startPos+bytes]);
5262 if (c=='x') // hexadecimal entity?
5263 {
5264 bytes++;
5265 matcher = std::isxdigit;
5266 }
5267 else // decimal entity
5268 {
5269 matcher = std::isdigit;
5270 }
5271 }
5272 else if (std::isalnum(c)) // named entity?
5273 {
5274 bytes++;
5275 matcher = std::isalnum;
5276 }
5277 if (matcher)
5278 {
5279 while ((c = static_cast<uint8_t>(utf8Str[startPos+bytes]))!=0 && matcher(c))
5280 {
5281 bytes++;
5282 }
5283 }
5284 if (c!=';')
5285 {
5286 bytes=1; // not a valid entity, reset bytes counter
5287 }
5288 }
5289 return startPos+bytes;
5290}

References getUTF8CharNumBytes().

Referenced by parseCommentAsText().

◆ normalizeNonTemplateArgumentsInString()

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

Definition at line 4237 of file util.cpp.

4241{
4242 // skip until <
4243 int p=name.find('<');
4244 if (p==-1) return name;
4245 p++;
4246 QCString result = name.left(p);
4247
4248 std::string s = name.mid(p).str();
4249 static const reg::Ex re(R"([\a:][\w:]*)");
4250 reg::Iterator it(s,re);
4252 size_t pi=0;
4253 // for each identifier in the template part (e.g. B<T> -> T)
4254 for (; it!=end ; ++it)
4255 {
4256 const auto &match = *it;
4257 size_t i = match.position();
4258 size_t l = match.length();
4259 result += s.substr(pi,i-pi);
4260 QCString n(match.str());
4261 bool found=FALSE;
4262 for (const Argument &formArg : formalArgs)
4263 {
4264 if (formArg.name == n)
4265 {
4266 found=TRUE;
4267 break;
4268 }
4269 }
4270 if (!found)
4271 {
4272 // try to resolve the type
4273 SymbolResolver resolver;
4274 const ClassDef *cd = resolver.resolveClass(context,n);
4275 if (cd)
4276 {
4277 result+=cd->name();
4278 }
4279 else
4280 {
4281 result+=n;
4282 }
4283 }
4284 else
4285 {
4286 result+=n;
4287 }
4288 pi=i+l;
4289 }
4290 result+=s.substr(pi);
4291 //printf("normalizeNonTemplateArgumentInString(%s)=%s\n",qPrint(name),qPrint(result));
4292 return removeRedundantWhiteSpace(result);
4293}
const ClassDef * resolveClass(const Definition *scope, const QCString &name, bool maybeUnlinkable=false, bool mayBeHidden=false)
Find the class definition matching name within the scope set.

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

Referenced by findUsedClassesForClass().

◆ openOutputFile()

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

Definition at line 6233 of file util.cpp.

6234{
6235 assert(!f.is_open());
6236 bool fileOpened=FALSE;
6237 bool writeToStdout=outFile=="-";
6238 if (writeToStdout) // write to stdout
6239 {
6240 f.basic_ios<char>::rdbuf(std::cout.rdbuf());
6241 fileOpened = true;
6242 }
6243 else // write to file
6244 {
6245 FileInfo fi(outFile.str());
6246 if (fi.exists()) // create a backup
6247 {
6248 Dir dir;
6249 FileInfo backup(fi.filePath()+".bak");
6250 if (backup.exists()) // remove existing backup
6251 dir.remove(backup.filePath());
6252 dir.rename(fi.filePath(),fi.filePath()+".bak");
6253 }
6254 f = Portable::openOutputStream(outFile);
6255 fileOpened = f.is_open();
6256 }
6257 return fileOpened;
6258}
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:649

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

5349{
5350 std::lock_guard lock(g_docCacheMutex);
5351 auto it = g_docCache.find(doc.str());
5352 if (it != g_docCache.end())
5353 {
5354 //printf("Cache: [%s]->[%s]\n",qPrint(doc),qPrint(it->second));
5355 return it->second;
5356 }
5357 auto parser { createDocParser() };
5358 auto ast { validatingParseTitle(*parser.get(),fileName,lineNr,doc) };
5359 auto astImpl = dynamic_cast<const DocNodeAST*>(ast.get());
5360 QCString result;
5361 if (astImpl)
5362 {
5363 TextStream t;
5364 OutputCodeList codeList;
5365 codeList.add<HtmlCodeGenerator>(&t);
5366 HtmlDocVisitor visitor(t,codeList,scope,fileName);
5367 std::visit(visitor,astImpl->root);
5368 result = t.str();
5369 }
5370 else // fallback, should not happen
5371 {
5372 result = filterTitle(doc);
5373 }
5374 //printf("Conversion: [%s]->[%s]\n",qPrint(doc),qPrint(result));
5375 g_docCache.insert(std::make_pair(doc.str(),result));
5376 return result;
5377}
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:165
void add(OutputCodeIntfPtr &&p)
Definition outputlist.h:195
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:5346
QCString filterTitle(const QCString &title)
Definition util.cpp:5553
static std::mutex g_docCacheMutex
Definition util.cpp:5345

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

5294{
5295 if (doc.isEmpty()) return "";
5296 //printf("parseCommentAsText(%s)\n",qPrint(doc));
5297 TextStream t;
5298 auto parser { createDocParser() };
5299 auto ast { validatingParseDoc(*parser.get(),
5300 fileName,
5301 lineNr,
5302 scope,
5303 md,
5304 doc,
5305 DocOptions()
5306 .setAutolinkSupport(false))
5307 };
5308 auto astImpl = dynamic_cast<const DocNodeAST*>(ast.get());
5309 if (astImpl)
5310 {
5311 TextDocVisitor visitor(t);
5312 std::visit(visitor,astImpl->root);
5313 }
5315 int i=0;
5316 int charCnt=0;
5317 int l=static_cast<int>(result.length());
5318 while ((i=nextUTF8CharPosition(result,l,i))<l)
5319 {
5320 charCnt++;
5321 if (charCnt>=80) break;
5322 }
5323 if (charCnt>=80) // try to truncate the string
5324 {
5325 while ((i=nextUTF8CharPosition(result,l,i))<l && charCnt<100)
5326 {
5327 charCnt++;
5328 if (result.at(i)==',' ||
5329 result.at(i)=='.' ||
5330 result.at(i)=='!' ||
5331 result.at(i)=='?' ||
5332 result.at(i)=='}') // good for UTF-16 characters and } otherwise also a good point to stop the string
5333 {
5334 i++; // we want to be "behind" last inspected character
5335 break;
5336 }
5337 }
5338 }
5339 if ( i < l) result=result.left(i)+"...";
5340 return result.data();
5341}
Concrete visitor implementation for TEXT output.
IDocNodeASTPtr validatingParseDoc(IDocParser &parserIntf, const QCString &fileName, int startLine, const Definition *ctx, const MemberDef *md, const QCString &input, const DocOptions &options)
static int nextUTF8CharPosition(const QCString &utf8Str, uint32_t len, uint32_t startPos)
Definition util.cpp:5248

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

5628{
5629 std::string elem;
5630 auto getter = [](std::string s) -> QCString { return s; };
5631 return genericPatternMatch(fi,patList,elem,getter);
5632}

References genericPatternMatch().

Referenced by checkAndOpenFile(), and readDir().

◆ projectLogoFile()

QCString projectLogoFile ( )

Definition at line 3083 of file util.cpp.

3084{
3085 QCString projectLogo = Config_getString(PROJECT_LOGO);
3086 if (!projectLogo.isEmpty())
3087 {
3088 // check for optional width= and height= specifier
3089 int wi = projectLogo.find(" width=");
3090 if (wi!=-1) // and strip them
3091 {
3092 projectLogo = projectLogo.left(wi);
3093 }
3094 int hi = projectLogo.find(" height=");
3095 if (hi!=-1)
3096 {
3097 projectLogo = projectLogo.left(hi);
3098 }
3099 }
3100 //printf("projectlogo='%s'\n",qPrint(projectLogo));
3101 return projectLogo;
3102}

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

Referenced by copyLogo(), and substituteKeywords().

◆ projectLogoSize()

QCString projectLogoSize ( )
static

Definition at line 3104 of file util.cpp.

3105{
3106 QCString sizeVal;
3107 QCString projectLogo = Config_getString(PROJECT_LOGO);
3108 if (!projectLogo.isEmpty())
3109 {
3110 auto extractDimension = [&projectLogo](const char *startMarker,size_t startPos,size_t endPos) -> QCString
3111 {
3112 QCString result = projectLogo.mid(startPos,endPos-startPos).stripWhiteSpace().quoted();
3113 if (result.length()>=2 && result.at(0)!='"' && result.at(result.length()-1)!='"')
3114 {
3115 result="\""+result+"\"";
3116 }
3117 result.prepend(startMarker);
3118 return result;
3119 };
3120 // check for optional width= and height= specifier
3121 int wi = projectLogo.find(" width=");
3122 int hi = projectLogo.find(" height=");
3123 if (wi!=-1 && hi!=-1)
3124 {
3125 if (wi<hi) // "... width=x height=y..."
3126 {
3127 sizeVal = extractDimension(" width=", wi+7, hi) + " "
3128 + extractDimension(" height=", hi+8, projectLogo.length());
3129 }
3130 else // "... height=y width=x..."
3131 {
3132 sizeVal = extractDimension(" height=", hi+8, wi) + " "
3133 + extractDimension(" width=", wi+7, projectLogo.length());
3134 }
3135 }
3136 else if (wi!=-1) // ... width=x..."
3137 {
3138 sizeVal = extractDimension(" width=", wi+7, projectLogo.length());
3139 }
3140 else if (hi!=-1) // ... height=x..."
3141 {
3142 sizeVal = extractDimension(" height=", hi+8, projectLogo.length());
3143 }
3144 }
3145 //printf("projectsize='%s'\n",qPrint(sizeVal));
3146 return sizeVal;
3147}
QCString quoted() const
Definition qcstring.h:275

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

5877{
5878 bool extractPrivate = Config_getBool(EXTRACT_PRIVATE);
5879 bool extractPackage = Config_getBool(EXTRACT_PACKAGE);
5880
5881 return (prot!=Protection::Private && prot!=Protection::Package) ||
5882 (prot==Protection::Private && extractPrivate) ||
5883 (prot==Protection::Package && extractPackage);
5884}

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

5474{
5475 // try to open file
5476 FileInfo fi(fileName.str());
5477 if (!fi.exists()) return FALSE;
5478 QCString filterName = getFileFilter(fileName,isSourceCode);
5479 if (filterName.isEmpty() || !filter)
5480 {
5481 std::ifstream f = Portable::openInputStream(fileName,true);
5482 if (!f.is_open())
5483 {
5484 err("could not open file {}\n",fileName);
5485 return FALSE;
5486 }
5487 // read the file
5488 auto fileSize = fi.size();
5489 contents.resize(fileSize);
5490 f.read(contents.data(),fileSize);
5491 if (f.fail())
5492 {
5493 err("problems while reading file {}\n",fileName);
5494 return FALSE;
5495 }
5496 }
5497 else
5498 {
5499 QCString cmd=filterName+" \""+fileName+"\"";
5500 Debug::print(Debug::ExtCmd,0,"Executing popen(`{}`)\n",cmd);
5501 FILE *f=Portable::popen(cmd,"r");
5502 if (!f)
5503 {
5504 err("could not execute filter {}\n",filterName);
5505 return FALSE;
5506 }
5507 const int bufSize=4096;
5508 char buf[bufSize];
5509 int numRead = 0;
5510 while ((numRead=static_cast<int>(fread(buf,1,bufSize,f)))>0)
5511 {
5512 //printf(">>>>>>>>Reading %d bytes\n",numRead);
5513 contents.append(buf,numRead);
5514 }
5516 Debug::print(Debug::FilterOutput, 0, "Filter output\n");
5517 Debug::print(Debug::FilterOutput,0,"-------------\n{}\n-------------\n",contents);
5518 }
5519
5520 if (contents.size()>=2 &&
5521 static_cast<uint8_t>(contents[0])==0xFF &&
5522 static_cast<uint8_t>(contents[1])==0xFE // Little endian BOM
5523 ) // UCS-2LE encoded file
5524 {
5525 transcodeCharacterBuffer(fileName,contents,"UCS-2LE","UTF-8");
5526 }
5527 else if (contents.size()>=2 &&
5528 static_cast<uint8_t>(contents[0])==0xFE &&
5529 static_cast<uint8_t>(contents[1])==0xFF // big endian BOM
5530 ) // UCS-2BE encoded file
5531 {
5532 transcodeCharacterBuffer(fileName,contents,"UCS-2BE","UTF-8");
5533 }
5534 else if (contents.size()>=3 &&
5535 static_cast<uint8_t>(contents[0])==0xEF &&
5536 static_cast<uint8_t>(contents[1])==0xBB &&
5537 static_cast<uint8_t>(contents[2])==0xBF
5538 ) // UTF-8 encoded file
5539 {
5540 contents.erase(0,3); // remove UTF-8 BOM: no translation needed
5541 }
5542 else // transcode according to the INPUT_ENCODING setting
5543 {
5544 // do character transcoding if needed.
5545 transcodeCharacterBuffer(fileName,contents,getEncoding(fi),"UTF-8");
5546 }
5547
5548 filterCRLF(contents);
5549 return true;
5550}
@ 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:660
FILE * popen(const QCString &name, const QCString &type)
Definition portable.cpp:480
int pclose(FILE *stream)
Definition portable.cpp:489
static void filterCRLF(std::string &contents)
Definition util.cpp:1300
static void transcodeCharacterBuffer(const QCString &fileName, std::string &contents, const QCString &inputEncoding, const QCString &outputEncoding)
Definition util.cpp:5437
QCString getEncoding(const FileInfo &fi)
Definition util.cpp:5634
QCString getFileFilter(const QCString &name, bool isSourceCode)
Definition util.cpp:1367

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

6281{
6282 int column=0;
6283 bool skipLine=FALSE;
6284
6285 if (format == FortranFormat::Fixed) return TRUE;
6286 if (format == FortranFormat::Free) return FALSE;
6287
6288 int tabSize=Config_getInt(TAB_SIZE);
6289 size_t sizCont = contents.length();
6290 for (size_t i=0;i<sizCont;i++)
6291 {
6292 column++;
6293
6294 switch(contents.at(i))
6295 {
6296 case '\n':
6297 column=0;
6298 skipLine=FALSE;
6299 break;
6300 case '\t':
6301 column += tabSize-1;
6302 break;
6303 case ' ':
6304 break;
6305 case '\000':
6306 return FALSE;
6307 case '#':
6308 skipLine=TRUE;
6309 break;
6310 case 'C':
6311 case 'c':
6312 if (column==1)
6313 {
6314 return !keyWordsFortranC(contents.data()+i);
6315 }
6316 // fallthrough
6317 case '*':
6318 if (column==1) return TRUE;
6319 if (skipLine) break;
6320 return FALSE;
6321 case '!':
6322 if (column!=6) skipLine=TRUE;
6323 break;
6324 default:
6325 if (skipLine) break;
6326 if (column>=7) return TRUE;
6327 return FALSE;
6328 }
6329 }
6330 return FALSE;
6331}
static bool keyWordsFortranC(const char *contents)
Definition util.cpp:6260

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

4802{
4803 ModuleDef *mod = root ? findModuleDef(d) : nullptr;
4804 if (!d->partOfGroups().empty() || mod!=nullptr) // write list of group to which this definition belongs
4805 {
4806 if (root)
4807 {
4808 ol.pushGeneratorState();
4810 ol.writeString("<div class=\"ingroups\">");
4811 }
4812 bool first=true;
4813 for (const auto &gd : d->partOfGroups())
4814 {
4815 if (!first) { ol.writeString(" &#124; "); } else first=false;
4817 {
4818 ol.writeString(" &raquo; ");
4819 }
4820 ol.writeObjectLink(gd->getReference(),gd->getOutputFileBase(),QCString(),gd->groupTitle());
4821 }
4822 if (root)
4823 {
4824 // add module as a group to the file as well
4825 if (mod)
4826 {
4827 if (!first) { ol.writeString(" &#124; "); } else first=false;
4828 ol.writeString(theTranslator->trModule(false,true)+" ");
4830 mod->displayName());
4831 }
4832 ol.writeString("</div>");
4833 ol.popGeneratorState();
4834 }
4835 return true;
4836 }
4837 return false;
4838}
virtual const GroupList & partOfGroups() const =0
virtual QCString displayName(bool includeScope=TRUE) const =0
void writeString(const QCString &text)
Definition outputlist.h:411
void pushGeneratorState()
void disableAllBut(OutputType o)
void popGeneratorState()
static ModuleDef * findModuleDef(const Definition *d)
Definition util.cpp:4772

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

3517{
3518 QCString result;
3519 if (Config_getBool(CREATE_SUBDIRS))
3520 {
3521 if (name.isEmpty())
3522 {
3523 return REL_PATH_TO_ROOT;
3524 }
3525 else
3526 {
3527 int i = name.findRev('/');
3528 if (i!=-1)
3529 {
3530 result=REL_PATH_TO_ROOT;
3531 }
3532 }
3533 }
3534 return result;
3535}
#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 163 of file util.cpp.

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

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

6524{
6525 std::string out;
6526 out.reserve(s.length());
6527 const char *p=s.data();
6528 if (p)
6529 {
6530 char c = 0;
6531 while ((c=*p++))
6532 {
6533 if (c=='\n')
6534 {
6535 const char *e = p;
6536 while (*e==' ' || *e=='\t') e++;
6537 if (*e=='\n')
6538 {
6539 p=e;
6540 }
6541 else out+=c;
6542 }
6543 else
6544 {
6545 out+=c;
6546 }
6547 }
6548 }
6549 //printf("removeEmptyLines(%s)=%s\n",qPrint(s),qPrint(out));
6550 return out;
6551}

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

Referenced by substituteHtmlKeywords(), and substituteLatexKeywords().

◆ removeLongPathMarker()

QCString removeLongPathMarker ( QCString path)

Definition at line 289 of file util.cpp.

290{
291#if defined(_WIN32)
292 if (path.startsWith("//?/")) // strip leading "\\?\" part from path
293 {
294 path=path.mid(4);
295 }
296#endif
297 return path;
298}

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

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

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(), ArgumentList::finishTrailingReturnType(), 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 220 of file util.cpp.

221{
222 if (s.isEmpty()) return s;
223 static const reg::Ex marker(R"(@\d+)");
224 std::string result = reg::replace(s.str(),marker,
225 !replacement.isEmpty() ? replacement.data() : "__anonymous__");
226 //printf("replaceAnonymousScopes('%s')='%s'\n",qPrint(s),qPrint(result));
227 return result;
228}
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:864

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

5746{
5747 if (str.isEmpty()) return QCString();
5748 std::string result;
5749 std::string s=str.str();
5750 static const reg::Ex re(R"(##[0-9A-Fa-f][0-9A-Fa-f])");
5751 reg::Iterator it(s,re);
5753 int hue = Config_getInt(HTML_COLORSTYLE_HUE);
5754 int sat = Config_getInt(HTML_COLORSTYLE_SAT);
5755 int gamma = Config_getInt(HTML_COLORSTYLE_GAMMA);
5756 size_t sl=s.length();
5757 size_t p=0;
5758 for (; it!=end ; ++it)
5759 {
5760 const auto &match = *it;
5761 size_t i = match.position();
5762 size_t l = match.length();
5763 if (i>p) result+=s.substr(p,i-p);
5764 std::string lumStr = match.str().substr(2);
5765#define HEXTONUM(x) (((x)>='0' && (x)<='9') ? ((x)-'0') : \
5766 ((x)>='a' && (x)<='f') ? ((x)-'a'+10) : \
5767 ((x)>='A' && (x)<='F') ? ((x)-'A'+10) : 0)
5768
5769 double r = 0,g = 0,b = 0;
5770 int level = HEXTONUM(lumStr[0])*16+HEXTONUM(lumStr[1]);
5771 ColoredImage::hsl2rgb(hue/360.0,sat/255.0,
5772 pow(level/255.0,gamma/100.0),&r,&g,&b);
5773 int red = static_cast<int>(r*255.0);
5774 int green = static_cast<int>(g*255.0);
5775 int blue = static_cast<int>(b*255.0);
5776 char colStr[8];
5777 colStr[0]='#';
5778 colStr[1]=hex[red>>4];
5779 colStr[2]=hex[red&0xf];
5780 colStr[3]=hex[green>>4];
5781 colStr[4]=hex[green&0xf];
5782 colStr[5]=hex[blue>>4];
5783 colStr[6]=hex[blue&0xf];
5784 colStr[7]=0;
5785 //printf("replacing %s->%s (level=%d)\n",qPrint(lumStr),colStr,level);
5786 result+=colStr;
5787 p=i+l;
5788 }
5789 if (p<sl) result+=s.substr(p);
5790 return result;
5791}
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 2669 of file util.cpp.

2677{
2678 *resContext=nullptr;
2679
2680 QCString linkRef=lr;
2681 if (lang==SrcLangExt::CSharp)
2682 {
2683 linkRef = mangleCSharpGenericName(linkRef);
2684 }
2685 QCString linkRefWithoutTemplates = stripTemplateSpecifiersFromScope(linkRef,FALSE);
2686 AUTO_TRACE("scName='{}',ref='{}'",scName,lr);
2687 const FileDef *fd = nullptr;
2688 const GroupDef *gd = nullptr;
2689 const PageDef *pd = nullptr;
2690 const ClassDef *cd = nullptr;
2691 const DirDef *dir = nullptr;
2692 const ConceptDef *cnd = nullptr;
2693 const ModuleDef *modd = nullptr;
2694 const NamespaceDef *nd = nullptr;
2695 const SectionInfo *si = nullptr;
2696 bool ambig = false;
2697 if (linkRef.isEmpty()) // no reference name!
2698 {
2699 AUTO_TRACE_EXIT("no_ref");
2700 return FALSE;
2701 }
2702 else if ((pd=Doxygen::pageLinkedMap->find(linkRef))) // link to a page
2703 {
2704 gd = pd->getGroupDef();
2705 if (gd)
2706 {
2707 if (!pd->name().isEmpty()) si=SectionManager::instance().find(pd->name());
2708 *resContext=gd;
2709 if (si) resAnchor = si->label();
2710 }
2711 else
2712 {
2713 *resContext=pd;
2714 }
2715 AUTO_TRACE_EXIT("page");
2716 return TRUE;
2717 }
2718 else if ((si=SectionManager::instance().find(prefix+linkRef)))
2719 {
2720 *resContext=si->definition();
2721 resAnchor = si->label();
2722 AUTO_TRACE_EXIT("section");
2723 return TRUE;
2724 }
2725 else if ((si=SectionManager::instance().find(linkRef)))
2726 {
2727 *resContext=si->definition();
2728 resAnchor = si->label();
2729 AUTO_TRACE_EXIT("section");
2730 return TRUE;
2731 }
2732 else if ((pd=Doxygen::exampleLinkedMap->find(linkRef))) // link to an example
2733 {
2734 *resContext=pd;
2735 AUTO_TRACE_EXIT("example");
2736 return TRUE;
2737 }
2738 else if ((gd=Doxygen::groupLinkedMap->find(linkRef))) // link to a group
2739 {
2740 *resContext=gd;
2741 AUTO_TRACE_EXIT("group");
2742 return TRUE;
2743 }
2744 else if ((fd=findFileDef(Doxygen::inputNameLinkedMap,linkRef,ambig)) // file link
2745 && fd->isLinkable())
2746 {
2747 *resContext=fd;
2748 AUTO_TRACE_EXIT("file");
2749 return TRUE;
2750 }
2751 else if ((cd=getClass(linkRef))) // class link
2752 {
2753 *resContext=cd;
2754 resAnchor=cd->anchor();
2755 AUTO_TRACE_EXIT("class");
2756 return TRUE;
2757 }
2758 else if (lang==SrcLangExt::Java &&
2759 (cd=getClass(linkRefWithoutTemplates))) // Java generic class link
2760 {
2761 *resContext=cd;
2762 resAnchor=cd->anchor();
2763 AUTO_TRACE_EXIT("generic");
2764 return TRUE;
2765 }
2766 else if ((cd=getClass(linkRef+"-p"))) // Obj-C protocol link
2767 {
2768 *resContext=cd;
2769 resAnchor=cd->anchor();
2770 AUTO_TRACE_EXIT("protocol");
2771 return TRUE;
2772 }
2773 else if ((cnd=getConcept(linkRef))) // C++20 concept definition
2774 {
2775 *resContext=cnd;
2776 resAnchor=cnd->anchor();
2777 AUTO_TRACE_EXIT("concept");
2778 return TRUE;
2779 }
2780 else if ((modd=ModuleManager::instance().modules().find(linkRef)))
2781 {
2782 *resContext=modd;
2783 resAnchor=modd->anchor();
2784 AUTO_TRACE_EXIT("module");
2785 return TRUE;
2786 }
2787 else if ((nd=Doxygen::namespaceLinkedMap->find(linkRef)))
2788 {
2789 *resContext=nd;
2790 AUTO_TRACE_EXIT("namespace");
2791 return TRUE;
2792 }
2793 else if ((dir=Doxygen::dirLinkedMap->find(FileInfo(linkRef.str()).absFilePath()+"/"))
2794 && dir->isLinkable()) // TODO: make this location independent like filedefs
2795 {
2796 *resContext=dir;
2797 AUTO_TRACE_EXIT("directory");
2798 return TRUE;
2799 }
2800 else // probably a member reference
2801 {
2802 const MemberDef *md = nullptr;
2803 bool res = resolveRef(scName,lr,TRUE,resContext,&md,lang);
2804 if (md) resAnchor=md->anchor();
2805 AUTO_TRACE_EXIT("member? res={}",res);
2806 return res;
2807 }
2808}
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
A model of a group of symbols.
Definition groupdef.h:52
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:2387
QCString mangleCSharpGenericName(const QCString &name)
Definition util.cpp:6850

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

2397{
2398 AUTO_TRACE("scope={} name={} inSeeBlock={} lang={} lookForSpecialization={} currentFile={} checkScope={}",
2399 scName,name,inSeeBlock,lang,lookForSpecialization,currentFile ? currentFile->name() : "", checkScope);
2400 //printf("resolveRef(scope=%s,name=%s,inSeeBlock=%d)\n",qPrint(scName),qPrint(name),inSeeBlock);
2401 QCString tsName = name;
2402 //bool memberScopeFirst = tsName.find('#')!=-1;
2403 QCString fullName = substitute(tsName,"#","::");
2404 if (fullName.find("anonymous_namespace{")==-1)
2405 {
2406 fullName = removeRedundantWhiteSpace(substitute(fullName,".","::",3));
2407 }
2408 else
2409 {
2410 fullName = removeRedundantWhiteSpace(fullName);
2411 }
2412
2413 int templStartPos;
2414 if (lang==SrcLangExt::CSharp && (templStartPos=fullName.find('<'))!=-1)
2415 {
2416 int templEndPos = fullName.findRev('>');
2417 if (templEndPos!=-1)
2418 {
2419 fullName = mangleCSharpGenericName(fullName.left(templEndPos+1))+fullName.mid(templEndPos+1);
2420 AUTO_TRACE_ADD("C# mangled name='{}'",fullName);
2421 }
2422 }
2423
2424 int bracePos=findParameterList(fullName);
2425 int endNamePos=bracePos!=-1 ? bracePos : static_cast<int>(fullName.length());
2426 int scopePos=fullName.findRev("::",endNamePos);
2427 bool explicitScope = fullName.startsWith("::") && // ::scope or #scope
2428 (scopePos>2 || // ::N::A
2429 tsName.startsWith("::") || // ::foo in local scope
2430 scName==nullptr // #foo in global scope
2431 );
2432 bool allowTypeOnly=false;
2433
2434 // default result values
2435 *resContext=nullptr;
2436 *resMember=nullptr;
2437
2438 if (bracePos==-1) // simple name
2439 {
2440 // the following if() was commented out for releases in the range
2441 // 1.5.2 to 1.6.1, but has been restored as a result of bug report 594787.
2442 if (!inSeeBlock && scopePos==-1 && isLowerCase(tsName))
2443 { // link to lower case only name => do not try to autolink
2444 AUTO_TRACE_ADD("false");
2445 return FALSE;
2446 }
2447
2448 ClassDef *cd=nullptr;
2449 NamespaceDef *nd=nullptr;
2450 ConceptDef *cnd=nullptr;
2451 ModuleDef *modd=nullptr;
2452
2453 //printf("scName=%s fullName=%s\n",qPrint(scName),qPrint(fullName));
2454
2455 // check if this is a class or namespace reference
2456 if (scName!=fullName && getScopeDefs(scName,fullName,cd,cnd,nd,modd))
2457 {
2458 //printf("found scopeDef\n");
2459 if (cd) // scope matches that of a class
2460 {
2461 *resContext = cd;
2462 }
2463 else if (cnd)
2464 {
2465 *resContext = cnd;
2466 }
2467 else if (modd)
2468 {
2469 *resContext = modd;
2470 }
2471 else // scope matches that of a namespace
2472 {
2473 ASSERT(nd!=nullptr);
2474 *resContext = nd;
2475 }
2476 AUTO_TRACE_ADD("true");
2477 return TRUE;
2478 }
2479 else if (scName==fullName || (!inSeeBlock && scopePos==-1))
2480 // nothing to link => output plain text
2481 {
2482 //printf("found scName=%s fullName=%s scName==fullName=%d "
2483 // "inSeeBlock=%d scopePos=%d!\n",
2484 // qPrint(scName),qPrint(fullName),scName==fullName,inSeeBlock,scopePos);
2485
2486 // at this point we have a bare word that is not a class or namespace
2487 // we should also allow typedefs or enums to be linked, but not for instance member
2488 // functions, otherwise 'Foo' would always link to the 'Foo()' constructor instead of the
2489 // 'Foo' class. So we use this flag as a filter.
2490 allowTypeOnly=true;
2491 }
2492
2493 // continue search...
2494 }
2495
2496 // extract userscope+name
2497 QCString nameStr=fullName.left(endNamePos);
2498 if (explicitScope) nameStr=nameStr.mid(2);
2499
2500
2501 // extract arguments
2502 QCString argsStr;
2503 if (bracePos!=-1) argsStr=fullName.right(fullName.length()-bracePos);
2504
2505 // strip template specifier
2506 // TODO: match against the correct partial template instantiation
2507 int templPos=nameStr.find('<');
2508 bool tryUnspecializedVersion = FALSE;
2509 if (templPos!=-1 && nameStr.find("operator")==-1)
2510 {
2511 int endTemplPos=nameStr.findRev('>');
2512 if (endTemplPos!=-1)
2513 {
2514 if (!lookForSpecialization)
2515 {
2516 nameStr=nameStr.left(templPos)+nameStr.right(nameStr.length()-endTemplPos-1);
2517 }
2518 else
2519 {
2520 tryUnspecializedVersion = TRUE;
2521 }
2522 }
2523 }
2524
2525 QCString scopeStr=scName;
2526 if (!explicitScope && nameStr.length()>scopeStr.length() && leftScopeMatch(scopeStr,nameStr))
2527 {
2528 nameStr=nameStr.mid(scopeStr.length()+2);
2529 }
2530
2531 const GroupDef *gd = nullptr;
2532 const ConceptDef *cnd = nullptr;
2533 const ModuleDef *modd = nullptr;
2534
2535 // check if nameStr is a member or global.
2536 //printf("getDefs(scope=%s,name=%s,args=%s checkScope=%d)\n",
2537 // qPrint(scopeStr), qPrint(nameStr), qPrint(argsStr),checkScope);
2538 GetDefInput input(scopeStr,nameStr,argsStr);
2539 input.forceEmptyScope = explicitScope;
2540 input.currentFile = currentFile;
2541 input.checkCV = true;
2542 GetDefResult result = getDefs(input);
2543 if (result.found)
2544 {
2545 //printf("after getDefs checkScope=%d nameStr=%s\n",checkScope,qPrint(nameStr));
2546 if (checkScope && result.md && result.md->getOuterScope()==Doxygen::globalScope &&
2547 !result.md->isStrongEnumValue() &&
2548 (!scopeStr.isEmpty() || nameStr.find("::")>0))
2549 {
2550 // we did find a member, but it is a global one while we were explicitly
2551 // looking for a scoped variable. See bug 616387 for an example why this check is needed.
2552 // note we do need to support autolinking to "::symbol" hence the >0
2553 //printf("not global member!\n");
2554 *resContext=nullptr;
2555 *resMember=nullptr;
2556 AUTO_TRACE_ADD("false");
2557 return FALSE;
2558 }
2559 //printf("after getDefs md=%p cd=%p fd=%p nd=%p gd=%p\n",md,cd,fd,nd,gd);
2560 if (result.md)
2561 {
2562 if (!allowTypeOnly || result.md->isTypedef() || result.md->isEnumerate())
2563 {
2564 *resMember=result.md;
2565 *resContext=result.md;
2566 }
2567 else // md is not a type, but we explicitly expect one
2568 {
2569 *resContext=nullptr;
2570 *resMember=nullptr;
2571 AUTO_TRACE_ADD("false");
2572 return FALSE;
2573 }
2574 }
2575 else if (result.cd) *resContext=result.cd;
2576 else if (result.nd) *resContext=result.nd;
2577 else if (result.fd) *resContext=result.fd;
2578 else if (result.gd) *resContext=result.gd;
2579 else if (result.cnd) *resContext=result.cnd;
2580 else if (result.modd) *resContext=result.modd;
2581 else
2582 {
2583 *resContext=nullptr; *resMember=nullptr;
2584 AUTO_TRACE_ADD("false");
2585 return FALSE;
2586 }
2587 //printf("member=%s (md=%p) anchor=%s linkable()=%d context=%s\n",
2588 // qPrint(md->name()), md, qPrint(md->anchor()), md->isLinkable(), qPrint((*resContext)->name()));
2589 AUTO_TRACE_ADD("true");
2590 return TRUE;
2591 }
2592 else if (inSeeBlock && !nameStr.isEmpty() && (gd=Doxygen::groupLinkedMap->find(nameStr)))
2593 { // group link
2594 *resContext=gd;
2595 AUTO_TRACE_ADD("true");
2596 return TRUE;
2597 }
2598 else if ((cnd=Doxygen::conceptLinkedMap->find(nameStr)))
2599 {
2600 *resContext=cnd;
2601 AUTO_TRACE_ADD("true");
2602 return TRUE;
2603 }
2604 else if ((modd=ModuleManager::instance().modules().find(nameStr)))
2605 {
2606 *resContext=modd;
2607 AUTO_TRACE_ADD("true");
2608 return TRUE;
2609 }
2610 else if (tsName.find('.')!=-1) // maybe a link to a file
2611 {
2612 bool ambig = false;
2613 const FileDef *fd=findFileDef(Doxygen::inputNameLinkedMap,tsName,ambig);
2614 if (fd && !ambig)
2615 {
2616 *resContext=fd;
2617 AUTO_TRACE_ADD("true");
2618 return TRUE;
2619 }
2620 }
2621
2622 if (tryUnspecializedVersion)
2623 {
2624 bool b = resolveRef(scName,name,inSeeBlock,resContext,resMember,lang,FALSE,nullptr,checkScope);
2625 AUTO_TRACE_ADD("{}",b);
2626 return b;
2627 }
2628 if (bracePos!=-1) // Try without parameters as well, could be a constructor invocation
2629 {
2630 *resContext=getClass(fullName.left(bracePos));
2631 if (*resContext)
2632 {
2633 AUTO_TRACE_ADD("true");
2634 return TRUE;
2635 }
2636 }
2637 //printf("resolveRef: %s not found!\n",qPrint(name));
2638
2639 AUTO_TRACE_ADD("false");
2640 return FALSE;
2641}
virtual bool isStrongEnumValue() const =0
static bool isLowerCase(QCString &s)
Definition util.cpp:2375
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:827
static bool getScopeDefs(const QCString &docScope, const QCString &scope, ClassDef *&cd, ConceptDef *&cnd, NamespaceDef *&nd, ModuleDef *&modd)
Definition util.cpp:2313

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

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

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

873{
874 size_t sl=scope.length();
875 size_t nl=name.length();
876 return (name==scope || // equal
877 (scope.right(nl)==name && // substring
878 sl>1+nl && scope.at(sl-nl-1)==':' && scope.at(sl-nl-2)==':' // scope
879 )
880 );
881}

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

Referenced by addMemberFunction(), findScopeFromQualifiedName(), 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 6346 of file util.cpp.

6347{
6348 if (s.isEmpty()) return s;
6349
6350 // helper to find the end of a block
6351 auto skipBlock = [&markerInfo](const char *p,const SelectionBlock &blk)
6352 {
6353 char c = 0;
6354 while ((c=*p))
6355 {
6356 if (c==markerInfo.markerChar && qstrncmp(p,markerInfo.endStr,markerInfo.endLen)==0) // end marker
6357 {
6358 size_t len = markerInfo.endLen;
6359 bool negate = *(p+markerInfo.endLen)=='!';
6360 if (negate) len++;
6361 size_t blkNameLen = qstrlen(blk.name);
6362 if (qstrncmp(p+len,blk.name,blkNameLen)==0 && // matching marker name
6363 qstrncmp(p+len+blkNameLen,markerInfo.closeStr,markerInfo.closeLen)==0) // matching marker closing
6364 {
6365 //printf("Found end marker %s enabled=%d negate=%d\n",blk.name,blk.enabled,negate);
6366 return p+len+blkNameLen+markerInfo.closeLen;
6367 }
6368 else // not the right marker id
6369 {
6370 p++;
6371 }
6372 }
6373 else // not and end marker
6374 {
6375 p++;
6376 }
6377 }
6378 return p;
6379 };
6380
6381 QCString result;
6382 result.reserve(s.length());
6383 const char *p = s.data();
6384 char c = 0;
6385 while ((c=*p))
6386 {
6387 if (c==markerInfo.markerChar) // potential start of marker
6388 {
6389 if (qstrncmp(p,markerInfo.beginStr,markerInfo.beginLen)==0) // start of begin marker
6390 {
6391 bool found = false;
6392 size_t len = markerInfo.beginLen;
6393 bool negate = *(p+len)=='!';
6394 if (negate) len++;
6395 for (const auto &blk : blockList)
6396 {
6397 size_t blkNameLen = qstrlen(blk.name);
6398 if (qstrncmp(p+len,blk.name,blkNameLen)==0 && // matching marker name
6399 qstrncmp(p+len+blkNameLen,markerInfo.closeStr,markerInfo.closeLen)==0) // matching marker closing
6400 {
6401 bool blockEnabled = blk.enabled!=negate;
6402 //printf("Found start marker %s enabled=%d negate=%d\n",blk.name,blk.enabled,negate);
6403 p+=len+blkNameLen+markerInfo.closeLen;
6404 if (!blockEnabled) // skip until the end of the block
6405 {
6406 //printf("skipping block\n");
6407 p=skipBlock(p,blk);
6408 }
6409 found=true;
6410 break;
6411 }
6412 }
6413 if (!found) // unknown marker id
6414 {
6415 result+=c;
6416 p++;
6417 }
6418 }
6419 else if (qstrncmp(p,markerInfo.endStr,markerInfo.endLen)==0) // start of end marker
6420 {
6421 bool found = false;
6422 size_t len = markerInfo.endLen;
6423 bool negate = *(p+len)=='!';
6424 if (negate) len++;
6425 for (const auto &blk : blockList)
6426 {
6427 size_t blkNameLen = qstrlen(blk.name);
6428 if (qstrncmp(p+len,blk.name,blkNameLen)==0 && // matching marker name
6429 qstrncmp(p+len+blkNameLen,markerInfo.closeStr,markerInfo.closeLen)==0) // matching marker closing
6430 {
6431 //printf("Found end marker %s enabled=%d negate=%d\n",blk.name,blk.enabled,negate);
6432 p+=len+blkNameLen+markerInfo.closeLen;
6433 found=true;
6434 break;
6435 }
6436 }
6437 if (!found) // unknown marker id
6438 {
6439 result+=c;
6440 p++;
6441 }
6442 }
6443 else // not a start or end marker
6444 {
6445 result+=c;
6446 p++;
6447 }
6448 }
6449 else // not a marker character
6450 {
6451 result+=c;
6452 p++;
6453 }
6454 }
6455 //printf("====\n%s\n-----\n%s\n~~~~\n",qPrint(s),qPrint(result));
6456 return result;
6457}
void reserve(size_t size)
Reserve space for size bytes without changing the string contents.
Definition qcstring.h:185
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 3070 of file util.cpp.

3071{
3072 // get the current date and time
3073 std::tm dat{};
3074 int specFormat=0;
3075 QCString specDate = "";
3076 QCString err = dateTimeFromString(specDate,dat,specFormat);
3077
3078 // do the conversion
3079 int usedFormat=0;
3080 return formatDateTime(fmt,dat,usedFormat);
3081}
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 2967 of file util.cpp.

2968{
2969 QCString result;
2970 QCString name=n;
2971 QCString path;
2972 int slashPos=std::max(name.findRev('/'),name.findRev('\\'));
2973 if (slashPos!=-1)
2974 {
2975 path=name.left(slashPos+1);
2976 name=name.right(name.length()-slashPos-1);
2977 }
2978 const FileName *fn=fnMap->find(name);
2979 if (fn)
2980 {
2981 bool first = true;
2982 for (const auto &fd : *fn)
2983 {
2984 if (path.isEmpty() || fd->getPath().right(path.length())==path)
2985 {
2986 if (!first) result += "\n";
2987 else first = false;
2988 result+=" "+fd->absFilePath();
2989 }
2990 }
2991 }
2992 return result;
2993}

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

6573{
6574 StringVector result;
6575 reg::Iterator iter(s, delimiter);
6577 size_t p=0;
6578 for ( ; iter != end; ++iter)
6579 {
6580 const auto &match = *iter;
6581 size_t i=match.position();
6582 size_t l=match.length();
6583 if (i>p) result.push_back(s.substr(p,i-p));
6584 p=i+l;
6585 }
6586 if (p<s.length()) result.push_back(s.substr(p));
6587 return result;
6588}

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

6556{
6557 StringVector result;
6558 size_t prev = 0, pos = 0, len = s.length();
6559 do
6560 {
6561 pos = s.find(delimiter, prev);
6562 if (pos == std::string::npos) pos = len;
6563 if (pos>prev) result.push_back(s.substr(prev,pos-prev));
6564 prev = pos + delimiter.length();
6565 }
6566 while (pos<len && prev<len);
6567 return result;
6568}

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

5410{
5411#ifdef TRACINGSUPPORT
5412 void *backtraceFrames[128];
5413 int frameCount = backtrace(backtraceFrames, 128);
5414 const size_t cmdLen = 40960;
5415 static char cmd[cmdLen];
5416 char *p = cmd;
5417 p += qsnprintf(p,cmdLen,"/usr/bin/atos -p %d ", (int)getpid());
5418 for (int x = 0; x < frameCount; x++)
5419 {
5420 p += qsnprintf(p,cmdLen,"%p ", backtraceFrames[x]);
5421 }
5422 fprintf(stderr,"========== STACKTRACE START ==============\n");
5423 if (FILE *fp = Portable::popen(cmd, "r"))
5424 {
5425 char resBuf[512];
5426 while (size_t len = fread(resBuf, 1, sizeof(resBuf), fp))
5427 {
5428 fwrite(resBuf, 1, len, stderr);
5429 }
5430 Portable::pclose(fp);
5431 }
5432 fprintf(stderr,"============ STACKTRACE END ==============\n");
5433 //fprintf(stderr,"%s\n", frameStrings[x]);
5434#endif
5435}

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

◆ stripAnonymousNamespaceScope()

QCString stripAnonymousNamespaceScope ( const QCString & s)

Definition at line 232 of file util.cpp.

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

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

1569{
1570 int i=s.find(" class ");
1571 if (i!=-1) return s.left(i)+s.mid(i+6);
1572 i=s.find(" typename ");
1573 if (i!=-1) return s.left(i)+s.mid(i+9);
1574 i=s.find(" union ");
1575 if (i!=-1) return s.left(i)+s.mid(i+6);
1576 i=s.find(" struct ");
1577 if (i!=-1) return s.left(i)+s.mid(i+7);
1578 return s;
1579}

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

Referenced by getCanonicalTypeForIdentifier().

◆ stripExtension()

QCString stripExtension ( const QCString & fName)

Definition at line 4872 of file util.cpp.

4873{
4875}
QCString stripExtensionGeneral(const QCString &fName, const QCString &ext)
Definition util.cpp:4862

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

332{
333 return stripFromPath(path,Config_getList(STRIP_FROM_INC_PATH));
334}

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

301{
302 // look at all the strings in the list and strip the longest match
303 QCString potential;
305 size_t length = 0;
306 for (const auto &s : l)
307 {
308 QCString prefix = s;
309 if (prefix.length() > length &&
310 qstricmp(path.left(prefix.length()),prefix)==0) // case insensitive compare
311 {
312 length = prefix.length();
313 potential = path.right(path.length()-prefix.length());
314 }
315 }
316 if (length>0) return potential;
317 return path;
318}
int qstricmp(const char *s1, const char *s2)
Definition qcstring.cpp:447

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

324{
325 return stripFromPath(path,Config_getList(STRIP_FROM_PATH));
326}

References Config_getList, and stripFromPath().

◆ stripIndentation()

QCString stripIndentation ( const QCString & s,
bool skipFirstLine )

Definition at line 5888 of file util.cpp.

5889{
5890 if (s.isEmpty()) return s; // empty string -> we're done
5891
5892 //printf("stripIndentation:\n%s\n------\n",qPrint(s));
5893 // compute minimum indentation over all lines
5894 const char *p=s.data();
5895 char c=0;
5896 int indent=0;
5897 int minIndent=1000000; // "infinite"
5898 bool searchIndent=true;
5899 int tabSize=Config_getInt(TAB_SIZE);
5900 bool skipFirst = skipFirstLine;
5901 while ((c=*p++))
5902 {
5903 if (c=='\t') indent+=tabSize - (indent%tabSize);
5904 else if (c=='\n') indent=0,searchIndent=true,skipFirst=false;
5905 else if (c==' ') indent++;
5906 else if (searchIndent && !skipFirst)
5907 {
5908 searchIndent=false;
5909 if (indent<minIndent) minIndent=indent;
5910 }
5911 }
5912
5913 // no indent to remove -> we're done
5914 if (minIndent==0) return substitute(s,"@ilinebr","\\ilinebr");
5915
5916 // remove minimum indentation for each line
5917 TextStream result;
5918 p=s.data();
5919 indent=0;
5920 skipFirst=skipFirstLine;
5921 while ((c=*p++))
5922 {
5923 if (c=='\n') // start of new line
5924 {
5925 indent=0;
5926 result << c;
5927 skipFirst=false;
5928 }
5929 else if (indent<minIndent && !skipFirst) // skip until we reach minIndent
5930 {
5931 if (c=='\t')
5932 {
5933 int newIndent = indent+tabSize-(indent%tabSize);
5934 int i=newIndent;
5935 while (i>minIndent) // if a tab crosses the minIndent boundary fill the rest with spaces
5936 {
5937 result << ' ';
5938 i--;
5939 }
5940 indent=newIndent;
5941 }
5942 else // space
5943 {
5944 indent++;
5945 }
5946 }
5947 else if (c=='\\' && literal_at(p,"ilinebr "))
5948 // we also need to remove the indentation after a \ilinebr command at the end of a line
5949 {
5950 result << "\\ilinebr ";
5951 p+=8;
5952 int skipAmount=0;
5953 for (int j=0;j<minIndent;j++) if (*(p+j)==' ') skipAmount++; // test to see if we have the indent
5954 if (skipAmount==minIndent)
5955 {
5956 p+=skipAmount; // remove the indent
5957 }
5958 }
5959 else if (c=='@' && literal_at(p,"ilinebr"))
5960 {
5961 result << "\\ilinebr";
5962 p+=7;
5963 }
5964 else // copy anything until the end of the line
5965 {
5966 result << c;
5967 }
5968 }
5969
5970 //printf("stripIndentation: result=\n%s\n------\n",qPrint(result.str()));
5971
5972 return result.str();
5973}

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

5977{
5978 //printf("stripIndentationVerbatim(level=%d):\n%s\n------\n",indentationLevel,qPrint(doc));
5979 if (indentationLevel <= 0 || doc.isEmpty()) return; // nothing to strip
5980
5981 // by stripping content the string will only become shorter so we write the results
5982 // back into the input string and then resize it at the end.
5983 char c = 0;
5984 const char *src = doc.data();
5985 char *dst = doc.rawData();
5986 bool insideIndent = false; // skip the initial line from stripping
5987 int cnt = 0;
5988 while ((c=*src++))
5989 {
5990 // invariant: dst<=src
5991 switch(c)
5992 {
5993 case '\n':
5994 *dst++ = c;
5995 insideIndent = true;
5996 cnt = indentationLevel;
5997 break;
5998 case ' ':
5999 if (insideIndent)
6000 {
6001 if (cnt>0) // count down the spacing until the end of the indent
6002 {
6003 cnt--;
6004 }
6005 else // reached the end of the indent, start of the part of the line to keep
6006 {
6007 insideIndent = false;
6008 *dst++ = c;
6009 }
6010 }
6011 else // part after indent, copy to the output
6012 {
6013 *dst++ = c;
6014 }
6015 break;
6016 default:
6017 insideIndent = false;
6018 *dst++ = c;
6019 break;
6020 }
6021 }
6022 doc.resize(static_cast<uint32_t>(dst-doc.data()));
6023 //printf("stripIndentationVerbatim: result=\n%s\n------\n",qPrint(doc));
6024}
char * rawData()
Returns a writable pointer to the data.
Definition qcstring.h:178
void resize(size_t newlen)
Definition qcstring.h:180

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

◆ stripIrrelevantConstVolatile()

void stripIrrelevantConstVolatile ( QCString & s,
bool insideTemplate )

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

1559{
1560 //printf("stripIrrelevantConstVolatile(%s)=",qPrint(s));
1561 stripIrrelevantString(s,"const",insideTemplate);
1562 stripIrrelevantString(s,"volatile",insideTemplate);
1563 stripIrrelevantString(s,"final",insideTemplate);
1564 //printf("%s\n",qPrint(s));
1565}
static void stripIrrelevantString(QCString &target, const QCString &str, bool insideTemplate)
Definition util.cpp:1498

References stripIrrelevantString().

Referenced by extractCanonicalType(), and matchArgument2().

◆ stripIrrelevantString()

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

Definition at line 1498 of file util.cpp.

1499{
1500 AUTO_TRACE("target='{}' str='{}'",target,str);
1501 if (target==str) { target.clear(); return; }
1502 int i=0,p=0;
1503 int l=static_cast<int>(str.length());
1504 bool changed=false;
1505 int sharpCount=0;
1506 while ((i=target.find(str,p))!=-1)
1507 {
1508 for (int q=p;q<i;q++)
1509 {
1510 if (target[q]=='<') sharpCount++;
1511 else if (target[q]=='>' && sharpCount>0) sharpCount--;
1512 }
1513 bool isMatch = (i==0 || !isId(target.at(i-1))) && // not a character before str
1514 (i+l==static_cast<int>(target.length()) || !isId(target.at(i+l))) && // not a character after str
1515 !insideTemplate && sharpCount==0; // not inside template, because e.g. <const A> is different than <A>, see issue #11663
1516 if (isMatch)
1517 {
1518 int i1=target.find('*',i+l);
1519 int i2=target.find('&',i+l);
1520 if (i1==-1 && i2==-1)
1521 {
1522 // strip str from target at index i
1523 target=target.left(i)+target.right(target.length()-i-l);
1524 changed=true;
1525 i-=l;
1526 }
1527 else if ((i1!=-1 && i<i1) || (i2!=-1 && i<i2)) // str before * or &
1528 {
1529 // move str to front
1530 target=str+" "+target.left(i)+target.right(target.length()-i-l);
1531 changed=true;
1532 i++;
1533 }
1534 }
1535 p = i+l;
1536 }
1537 if (changed) target=target.stripWhiteSpace();
1538 AUTO_TRACE_EXIT("target='{}'",target,str);
1539}

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

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

4954{
4955 if (s.isEmpty()) return QCString();
4956 const char *p = s.data();
4957
4958 // search for leading empty lines
4959 int i=0,li=-1,l=static_cast<int>(s.length());
4960 char c = 0;
4961 while ((c=*p))
4962 {
4963 if (c==' ' || c=='\t' || c=='\r') i++,p++;
4964 else if (c=='\\' && literal_at(p,"\\ilinebr")) i+=8,li=i,p+=8;
4965 else if (c=='\n') i++,li=i,docLine++,p++;
4966 else break;
4967 }
4968
4969 // search for trailing empty lines
4970 int b=l-1,bi=-1;
4971 p=s.data()+b;
4972 while (b>=0)
4973 {
4974 c=*p;
4975 if (c==' ' || c=='\t' || c=='\r') b--,p--;
4976 else if (c=='r' && b>=7 && literal_at(p-7,"\\ilinebr")) bi=b-7,b-=8,p-=8;
4977 else if (c=='>' && b>=11 && literal_at(p-11,"\\ilinebr<br>")) bi=b-11,b-=12,p-=12;
4978 else if (c=='\n') bi=b,b--,p--;
4979 else break;
4980 }
4981
4982 // return whole string if no leading or trailing lines where found
4983 if (li==-1 && bi==-1) return s;
4984
4985 // return substring
4986 if (bi==-1) bi=l;
4987 if (li==-1) li=0;
4988 if (bi<=li) return QCString(); // only empty lines
4989 //printf("docLine='%s' len=%d li=%d bi=%d\n",qPrint(s),s.length(),li,bi);
4990 return s.mid(li,bi-li);
4991}

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

4878{
4879 QCString result=s;
4880 int i=result.findRev('/');
4881 if (i!=-1)
4882 {
4883 result=result.mid(i+1);
4884 }
4885 i=result.findRev('\\');
4886 if (i!=-1)
4887 {
4888 result=result.mid(i+1);
4889 }
4890 return result;
4891}

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

3717{
3718 QCString result = name;
3719 int l = static_cast<int>(result.length());
3720 int p = 0;
3721 bool done = FALSE;
3722 bool skipBracket=FALSE; // if brackets do not match properly, ignore them altogether
3723 int count=0;
3724 int round=0;
3725
3726 do
3727 {
3728 p=l-1; // start at the end of the string
3729 while (p>=0 && count>=0)
3730 {
3731 char c=result.at(p);
3732 switch (c)
3733 {
3734 case ':':
3735 // only exit in the case of ::
3736 //printf("stripScope(%s)=%s\n",name,qPrint(result.right(l-p-1)));
3737 if (p>0 && result.at(p-1)==':' && (count==0 || skipBracket))
3738 {
3739 return result.right(l-p-1);
3740 }
3741 p--;
3742 break;
3743 case '>':
3744 if (skipBracket) // we don't care about brackets
3745 {
3746 p--;
3747 }
3748 else // count open/close brackets
3749 {
3750 if (p>0 && result.at(p-1)=='>') // skip >> operator
3751 {
3752 p-=2;
3753 break;
3754 }
3755 count=1;
3756 //printf("pos < = %d\n",p);
3757 p--;
3758 bool foundMatch=false;
3759 while (p>=0 && !foundMatch)
3760 {
3761 c=result.at(p--);
3762 switch (c)
3763 {
3764 case ')':
3765 round++;
3766 break;
3767 case '(':
3768 round--;
3769 break;
3770 case '>': // ignore > inside (...) to support e.g. (sizeof(T)>0) inside template parameters
3771 if (round==0) count++;
3772 break;
3773 case '<':
3774 if (round==0)
3775 {
3776 if (p>0)
3777 {
3778 if (result.at(p-1) == '<') // skip << operator
3779 {
3780 p--;
3781 break;
3782 }
3783 }
3784 count--;
3785 foundMatch = count==0;
3786 }
3787 break;
3788 default:
3789 //printf("c=%c count=%d\n",c,count);
3790 break;
3791 }
3792 }
3793 }
3794 //printf("pos > = %d\n",p+1);
3795 break;
3796 default:
3797 p--;
3798 }
3799 }
3800 done = count==0 || skipBracket; // reparse if brackets do not match
3801 skipBracket=TRUE;
3802 }
3803 while (!done); // if < > unbalanced repeat ignoring them
3804 //printf("stripScope(%s)=%s\n",name,name);
3805 return name;
3806}

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

4469{
4470 //printf("stripTemplateSpecifiersFromScope(name=%s,scopeName=%s)\n",qPrint(fullName),qPrint(scopeName));
4471 int i=fullName.find('<');
4472 if (i==-1) return fullName;
4473 QCString result;
4474 int p=0;
4475 int l=static_cast<int>(fullName.length());
4476 while (i!=-1)
4477 {
4478 //printf("1:result+=%s\n",qPrint(fullName.mid(p,i-p)));
4479 int e=i+1;
4480 int count=1;
4481 int round=0;
4482 while (e<l && count>0)
4483 {
4484 char c=fullName.at(e++);
4485 switch (c)
4486 {
4487 case '(': round++; break;
4488 case ')': if (round>0) round--; break;
4489 case '<': if (round==0) count++; break;
4490 case '>': if (round==0) count--; break;
4491 default:
4492 break;
4493 }
4494 }
4495 int si= fullName.find("::",e);
4496
4497 if (parentOnly && si==-1) break;
4498 // we only do the parent scope, so we stop here if needed
4499
4500 result+=fullName.mid(p,i-p);
4501 //printf(" trying %s\n",qPrint(mergeScopes(scopeName,result+fullName.mid(i,e-i))));
4502 ClassDef *cd = getClass(mergeScopes(scopeName,result+fullName.mid(i,e-i)));
4503 if (cd!=nullptr && (allowArtificial || !cd->isArtificial()))
4504 {
4505 result+=fullName.mid(i,e-i);
4506 //printf(" 2:result+=%s\n",qPrint(fullName.mid(i,e-i-1)));
4507 }
4508 else if (pLastScopeStripped)
4509 {
4510 //printf(" last stripped scope '%s'\n",qPrint(fullName.mid(i,e-i)));
4511 *pLastScopeStripped=fullName.mid(i,e-i);
4512 }
4513 p=e;
4514 i=fullName.find('<',p);
4515 }
4516 result+=fullName.right(l-p);
4517 //printf("3:result+=%s\n",qPrint(fullName.right(l-p)));
4518 //printf("end result=%s\n",qPrint(result));
4519 return result;
4520}
virtual bool isArtificial() const =0
QCString mergeScopes(const QCString &leftScope, const QCString &rightScope)
Definition util.cpp:4531

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

2998{
2999 std::string substRes;
3000 int line = 1;
3001 const char *p = s.data();
3002 if (p)
3003 {
3004 // reserve some room for expansion
3005 substRes.reserve(s.length()+1024);
3006 char c = 0;
3007 while ((c=*p))
3008 {
3009 bool found = false;
3010 if (c=='$')
3011 {
3012 for (const auto &kw : keywords)
3013 {
3014 size_t keyLen = qstrlen(kw.keyword);
3015 if (qstrncmp(p,kw.keyword,keyLen)==0)
3016 {
3017 const char *startArg = p+keyLen;
3018 bool expectParam = std::holds_alternative<KeywordSubstitution::GetValueWithParam>(kw.getValueVariant);
3019 //printf("%s: expectParam=%d *startArg=%c\n",kw.keyword,expectParam,*startArg);
3020 if (expectParam && *startArg=='(') // $key(value)
3021 {
3022 size_t j=1;
3023 const char *endArg = nullptr;
3024 while ((c=*(startArg+j)) && c!=')' && c!='\n' && c!=0) j++;
3025 if (c==')') endArg=startArg+j;
3026 if (endArg)
3027 {
3028 QCString value = QCString(startArg+1).left(endArg-startArg-1);
3029 auto &&getValue = std::get<KeywordSubstitution::GetValueWithParam>(kw.getValueVariant);
3030 substRes+=getValue(value).str();
3031 p=endArg+1;
3032 //printf("found '%s'->'%s'\n",kw.keyword,qPrint(getValue(value)));
3033 }
3034 else
3035 {
3036 //printf("missing argument\n");
3037 warn(file,line,"Missing argument for '{}'",kw.keyword);
3038 p+=keyLen;
3039 }
3040 }
3041 else if (!expectParam) // $key
3042 {
3043 auto &&getValue = std::get<KeywordSubstitution::GetValue>(kw.getValueVariant);
3044 substRes+=getValue().str();
3045 //printf("found '%s'->'%s'\n",kw.keyword,qPrint(getValue()));
3046 p+=keyLen;
3047 }
3048 else
3049 {
3050 //printf("%s %d Expected arguments, none specified '%s'\n",qPrint(file), line, qPrint(kw.keyword));
3051 warn(file,line,"Expected arguments for '{}' but none were specified",kw.keyword);
3052 p+=keyLen;
3053 }
3054 found = true;
3055 break;
3056 }
3057 }
3058 }
3059 if (!found) // copy
3060 {
3061 if (c=='\n') line++;
3062 substRes+=c;
3063 p++;
3064 }
3065 }
3066 }
3067 return substRes;
3068}

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

3151{
3152 return substituteKeywords(file,s,
3153 {
3154 // keyword value getter
3155 { "$title", [&]() { return !title.isEmpty() ? title : projName; } },
3156 { "$doxygenversion", [&]() { return getDoxygenVersion(); } },
3157 { "$projectname", [&]() { return projName; } },
3158 { "$projectnumber", [&]() { return projNum; } },
3159 { "$projectbrief", [&]() { return projBrief; } },
3160 { "$projectlogo", [&]() { return stripPath(projectLogoFile()); } },
3161 { "$logosize", [&]() { return projectLogoSize(); } },
3162 { "$projecticon", [&]() { return stripPath(Config_getString(PROJECT_ICON)); } },
3163 { "$langISO", [&]() { return theTranslator->trISOLang(); } },
3164 { "$showdate", [&](const QCString &fmt) { return showDate(fmt); } }
3165 });
3166}
QCString stripPath(const QCString &s)
Definition util.cpp:4877
QCString substituteKeywords(const QCString &file, const QCString &s, const KeywordSubstitutionList &keywords)
Definition util.cpp:2997
QCString projectLogoFile()
Definition util.cpp:3083
static QCString projectLogoSize()
Definition util.cpp:3104
static QCString showDate(const QCString &fmt)
Definition util.cpp:3070

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

4306{
4307 AUTO_TRACE("name={} formalArgs={} actualArgs={}",nm,argListToString(formalArgs),actualArgs ? argListToString(*actualArgs) : QCString());
4308 if (formalArgs.empty()) return nm;
4309 QCString result;
4310
4311 static const reg::Ex re(R"(\a\w*)");
4312 std::string name = nm.str();
4313 reg::Iterator it(name,re);
4315 size_t p=0;
4316
4317 for (; it!=end ; ++it)
4318 {
4319 const auto &match = *it;
4320 size_t i = match.position();
4321 size_t l = match.length();
4322 if (i>p) result += name.substr(p,i-p);
4323 QCString n(match.str());
4325 if (actualArgs)
4326 {
4327 actIt = actualArgs->begin();
4328 }
4329 //printf(": name=%s\n",qPrint(name));
4330
4331 // if n is a template argument, then we substitute it
4332 // for its template instance argument.
4333 bool found=FALSE;
4334 for (auto formIt = formalArgs.begin();
4335 formIt!=formalArgs.end() && !found;
4336 ++formIt
4337 )
4338 {
4339 Argument formArg = *formIt;
4340 Argument actArg;
4341 if (actualArgs && actIt!=actualArgs->end())
4342 {
4343 actArg = *actIt;
4344 }
4345 if (formArg.type.startsWith("class ") && formArg.name.isEmpty())
4346 {
4347 formArg.name = formArg.type.mid(6);
4348 formArg.type = "class";
4349 }
4350 else if (formArg.type.startsWith("typename ") && formArg.name.isEmpty())
4351 {
4352 formArg.name = formArg.type.mid(9);
4353 formArg.type = "typename";
4354 }
4355 else if (formArg.type.startsWith("class...")) // match 'class... name' to 'name...'
4356 {
4357 formArg.name += "...";
4358 formArg.type = formArg.type.left(5)+formArg.type.mid(8);
4359 }
4360 else if (formArg.type.startsWith("typename...")) // match 'typename... name' to 'name...'
4361 {
4362 formArg.name += "...";
4363 formArg.type = formArg.type.left(8)+formArg.type.mid(11);
4364 }
4365 //printf(": n=%s formArg->type='%s' formArg->name='%s' formArg->defval='%s' actArg->type='%s' actArg->name='%s' \n",
4366 // qPrint(n),qPrint(formArg.type),qPrint(formArg.name),qPrint(formArg.defval),qPrint(actArg.type),qPrint(actArg.name));
4367 if (formArg.type=="class" || formArg.type=="typename" || formArg.type.startsWith("template"))
4368 {
4369 if (formArg.name==n && actualArgs && actIt!=actualArgs->end() && !actArg.type.isEmpty()) // base class is a template argument
4370 {
4371 static constexpr auto hasRecursion = [](const QCString &prefix,const QCString &nameArg,const QCString &subst) -> bool
4372 {
4373 int ii=0;
4374 int pp=0;
4375
4376 ii = subst.find('<');
4377 //printf("prefix='%s' subst='%s'\n",qPrint(prefix.mid(prefix.length()-ii-2,ii+1)),qPrint(subst.left(ii+1)));
4378 if (ii!=-1 && static_cast<int>(prefix.length())>=ii+2 && prefix.mid(prefix.length()-ii-2,ii+1)==subst.left(ii+1))
4379 {
4380 return true; // don't replace 'A< ' with 'A< A<...', see issue #10951
4381 }
4382
4383 while ((ii=subst.find(nameArg,pp))!=-1)
4384 {
4385 bool beforeNonWord = ii==0 || !isId(subst.at(ii-1));
4386 bool afterNonWord = subst.length()==ii+nameArg.length() || !isId(subst.at(ii+nameArg.length()));
4387 if (beforeNonWord && afterNonWord)
4388 {
4389 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
4390 }
4391 pp=ii+static_cast<int>(nameArg.length());
4392 }
4393 return false;
4394 };
4395 // replace formal argument with the actual argument of the instance
4396 AUTO_TRACE_ADD("result={} n={} type={} hasRecursion={}",result,n,actArg.type,hasRecursion(result,n,actArg.type));
4397 if (!hasRecursion(result,n,actArg.type))
4398 // the scope guard is to prevent recursive lockup for
4399 // template<class A> class C : public<A::T>,
4400 // where A::T would become A::T::T here,
4401 // since n==A and actArg->type==A::T
4402 // see bug595833 for an example
4403 //
4404 // Also prevent recursive substitution if n is part of actArg.type, i.e.
4405 // n='A' in argType='S< A >' would produce 'S< S< A > >'
4406 {
4407 if (actArg.name.isEmpty())
4408 {
4409 result += actArg.type;
4410 }
4411 else
4412 // for case where the actual arg is something like "unsigned int"
4413 // the "int" part is in actArg->name.
4414 {
4415 result += actArg.type+" "+actArg.name;
4416 }
4417 found=TRUE;
4418 }
4419 }
4420 else if (formArg.name==n &&
4421 (actualArgs==nullptr || actIt==actualArgs->end()) &&
4422 !formArg.defval.isEmpty() &&
4423 formArg.defval!=nm /* to prevent recursion */
4424 )
4425 {
4426 result += substituteTemplateArgumentsInString(formArg.defval,formalArgs,actualArgs);
4427 found=TRUE;
4428 }
4429 }
4430 else if (formArg.name==n &&
4431 (actualArgs==nullptr || actIt==actualArgs->end()) &&
4432 !formArg.defval.isEmpty() &&
4433 formArg.defval!=nm /* to prevent recursion */
4434 )
4435 {
4436 result += substituteTemplateArgumentsInString(formArg.defval,formalArgs,actualArgs);
4437 found=TRUE;
4438 }
4439 if (actualArgs && actIt!=actualArgs->end())
4440 {
4441 actIt++;
4442 }
4443 }
4444 if (!found)
4445 {
4446 result += n;
4447 }
4448 p=i+l;
4449 }
4450 result+=name.substr(p);
4451 result=result.simplifyWhiteSpace();
4452 AUTO_TRACE_EXIT("result={}",result);
4453 return result.stripWhiteSpace();
4454}
typename Vec::const_iterator const_iterator
Definition arguments.h:69
QCString substituteTemplateArgumentsInString(const QCString &nm, const ArgumentList &formalArgs, const ArgumentList *actualArgs)
Definition util.cpp:4302

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

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

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

5439{
5440 if (inputEncoding.isEmpty() || outputEncoding.isEmpty()) return; // no encoding specified
5441 if (qstricmp(inputEncoding,outputEncoding)==0) return; // input encoding same as output encoding
5442 void *cd = portable_iconv_open(outputEncoding.data(),inputEncoding.data());
5443 if (cd==reinterpret_cast<void *>(-1))
5444 {
5445 term("unsupported character conversion: '{}'->'{}': {}\n"
5446 "Check the INPUT_ENCODING setting in the config file!\n",
5447 inputEncoding,outputEncoding,strerror(errno));
5448 }
5449 size_t iLeft = contents.size();
5450 const char *srcPtr = contents.data();
5451 size_t tmpBufSize = contents.size()*4+1;
5452 size_t oLeft = tmpBufSize;
5453 std::string tmpBuf;
5454 tmpBuf.resize(tmpBufSize);
5455 char *dstPtr = tmpBuf.data();
5456 size_t newSize=0;
5457 if (!portable_iconv(cd, &srcPtr, &iLeft, &dstPtr, &oLeft))
5458 {
5459 newSize = tmpBufSize-oLeft;
5460 tmpBuf.resize(newSize);
5461 std::swap(contents,tmpBuf);
5462 //printf("iconv: input size=%d output size=%d\n[%s]\n",size,newSize,qPrint(srcBuf));
5463 }
5464 else
5465 {
5466 term("{}: failed to translate characters from {} to {}: check INPUT_ENCODING\n",
5467 fileName,inputEncoding,outputEncoding);
5468 }
5470}
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 1401 of file util.cpp.

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

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

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

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

3355{
3356 if (s.isEmpty()) return s;
3357 bool caseSenseNames = getCaseSenseNames();
3358 QCString result;
3359 const char *p = s.data();
3360 if (p)
3361 {
3362 char c = 0;
3363 while ((c=*p++))
3364 {
3365 if (c=='_') // 2 or 3 character escape
3366 {
3367 switch (*p)
3368 {
3369 case '_': result+=c; p++; break; // __ -> '_'
3370 case '1': result+=':'; p++; break; // _1 -> ':'
3371 case '2': result+='/'; p++; break; // _2 -> '/'
3372 case '3': result+='<'; p++; break; // _3 -> '<'
3373 case '4': result+='>'; p++; break; // _4 -> '>'
3374 case '5': result+='*'; p++; break; // _5 -> '*'
3375 case '6': result+='&'; p++; break; // _6 -> '&'
3376 case '7': result+='|'; p++; break; // _7 -> '|'
3377 case '8': result+='.'; p++; break; // _8 -> '.'
3378 case '9': result+='!'; p++; break; // _9 -> '!'
3379 case '0': // 3 character escape
3380 switch (*(p+1))
3381 {
3382 case '0': result+=','; p+=2; break; // _00 -> ','
3383 case '1': result+=' '; p+=2; break; // _01 -> ' '
3384 case '2': result+='{'; p+=2; break; // _02 -> '{'
3385 case '3': result+='}'; p+=2; break; // _03 -> '}'
3386 case '4': result+='?'; p+=2; break; // _04 -> '?'
3387 case '5': result+='^'; p+=2; break; // _05 -> '^'
3388 case '6': result+='%'; p+=2; break; // _06 -> '%'
3389 case '7': result+='('; p+=2; break; // _07 -> '('
3390 case '8': result+=')'; p+=2; break; // _08 -> ')'
3391 case '9': result+='+'; p+=2; break; // _09 -> '+'
3392 case 'a': result+='='; p+=2; break; // _0a -> '='
3393 case 'b': result+='$'; p+=2; break; // _0b -> '$'
3394 case 'c': result+='\\'; p+=2; break;// _0c -> '\'
3395 case 'd': result+='@'; p+=2; break; // _0d -> '@'
3396 case 'e': result+=']'; p+=2; break; // _0e -> ']'
3397 case 'f': result+='['; p+=2; break; // _0f -> '['
3398 case 'g': result+='#'; p+=2; break; // _0g -> '#'
3399 case 'h': result+='"'; p+=2; break; // _0h -> '"'
3400 case 'i': result+='~'; p+=2; break; // _0i -> '~'
3401 case 'j': result+='\''; p+=2; break;// _0j -> '\'
3402 case 'k': result+=';'; p+=2; break; // _0k -> ';'
3403 case 'l': result+='`'; p+=2; break; // _0l -> '`'
3404 default: // unknown escape, just pass underscore character as-is
3405 result+=c;
3406 break;
3407 }
3408 break;
3409 default:
3410 if (!caseSenseNames && c>='a' && c<='z') // lower to upper case escape, _a -> 'A'
3411 {
3412 result+=static_cast<char>(toupper(*p));
3413 p++;
3414 }
3415 else // unknown escape, pass underscore character as-is
3416 {
3417 result+=c;
3418 }
3419 break;
3420 }
3421 }
3422 else // normal character; pass as is
3423 {
3424 result+=c;
3425 }
3426 }
3427 }
3428 return result;
3429}

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

◆ updateColumnCount()

size_t updateColumnCount ( const char * s,
size_t col )

Definition at line 6817 of file util.cpp.

6818{
6819 if (s)
6820 {
6821 const int tabSize = Config_getInt(TAB_SIZE);
6822 char c;
6823 while ((c=*s++))
6824 {
6825 switch(c)
6826 {
6827 case '\t': col+=tabSize - (col%tabSize);
6828 break;
6829 case '\n': col=0;
6830 break;
6831 default:
6832 col++;
6833 if (c<0) // multi-byte character
6834 {
6835 int numBytes = getUTF8CharNumBytes(c);
6836 for (int i=0;i<numBytes-1 && (c=*s++);i++) {} // skip over extra chars
6837 if (c==0) return col; // end of string half way a multibyte char
6838 }
6839 break;
6840 }
6841 }
6842 }
6843 return col;
6844}

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

5030{
5031 QCString langName = language.lower();
5032 auto it1 = std::find_if(g_lang2extMap.begin(),g_lang2extMap.end(),
5033 [&langName](const auto &info) { return info.langName==langName; });
5034 if (it1 == g_lang2extMap.end()) return false;
5035
5036 // found the language
5037 SrcLangExt parserId = it1->parserId;
5038 QCString extName = extension.lower();
5039 if (extName.isEmpty()) return FALSE;
5040 if (extName.at(0)!='.') extName.prepend(".");
5041 auto it2 = g_extLookup.find(extName.str());
5042 if (it2!=g_extLookup.end())
5043 {
5044 g_extLookup.erase(it2); // language was already register for this ext
5045 }
5046 //printf("registering extension %s\n",qPrint(extName));
5047 g_extLookup.emplace(extName.str(),parserId);
5048 if (!Doxygen::parserManager->registerExtension(extName,it1->parserName))
5049 {
5050 err("Failed to assign extension {} to parser {} for language {}\n",
5051 extName.data(),it1->parserName,language);
5052 }
5053 else
5054 {
5055 //msg("Registered extension {} to language parser {}...\n",
5056 // extName,language);
5057 }
5058 return TRUE;
5059}
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 5721 of file util.cpp.

5722{
5723 int hue = Config_getInt(HTML_COLORSTYLE_HUE);
5724 int sat = Config_getInt(HTML_COLORSTYLE_SAT);
5725 int gamma = Config_getInt(HTML_COLORSTYLE_GAMMA);
5726 while (data->name)
5727 {
5728 QCString fileName = dir+"/"+data->name;
5729 ColoredImage img(data->width,data->height,data->content,data->alpha,
5730 sat,hue,gamma);
5731 if (!img.save(fileName))
5732 {
5733 fprintf(stderr,"Warning: Cannot open file %s for writing\n",data->name);
5734 }
5735 Doxygen::indexList->addImageFile(data->name);
5736 data++;
5737 }
5738}
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:418
unsigned short height
Definition util.h:417
const unsigned char * alpha
Definition util.h:419
unsigned short width
Definition util.h:416
const char * name
Definition util.h:415

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

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

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

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

5383{
5384 if (al.empty()) return;
5385 ol.startConstraintList(theTranslator->trTypeConstraints());
5386 for (const Argument &a : al)
5387 {
5389 ol.parseText(a.name);
5390 ol.endConstraintParam();
5392 linkifyText(TextGeneratorOLImpl(ol),d,nullptr,nullptr,a.type);
5393 ol.endConstraintType();
5395 ol.generateDoc(d->docFile(),
5396 d->docLine(),
5397 d,
5398 nullptr,
5399 a.docs,
5400 DocOptions()
5401 .setIndexWords(true));
5402 ol.endConstraintDocs();
5403 }
5404 ol.endConstraintList();
5405}
virtual int docLine() const =0
void endConstraintType()
Definition outputlist.h:714
void endConstraintList()
Definition outputlist.h:720
void startConstraintParam()
Definition outputlist.h:708
void generateDoc(const QCString &fileName, int startLine, const Definition *ctx, const MemberDef *md, const QCString &docStr, const DocOptions &options)
void startConstraintDocs()
Definition outputlist.h:716
void startConstraintType()
Definition outputlist.h:712
void endConstraintDocs()
Definition outputlist.h:718
void endConstraintParam()
Definition outputlist.h:710
void startConstraintList(const QCString &header)
Definition outputlist.h:706
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:895

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

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

Variable Documentation

◆ constScope

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

Definition at line 522 of file util.cpp.

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

Referenced by removeRedundantWhiteSpace().

◆ g_charAroundSpace

CharAroundSpace g_charAroundSpace
static

Definition at line 566 of file util.cpp.

Referenced by removeRedundantWhiteSpace().

◆ g_docCache

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

Definition at line 5346 of file util.cpp.

Referenced by parseCommentAsHtml().

◆ g_docCacheMutex

std::mutex g_docCacheMutex
static

Definition at line 5345 of file util.cpp.

Referenced by parseCommentAsHtml().

◆ g_extLookup

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

Definition at line 4995 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 2837 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 5005 of file util.cpp.

5006{
5007// language parser parser option
5008 { "idl", "c", SrcLangExt::IDL, ".idl" },
5009 { "java", "c", SrcLangExt::Java, ".java"},
5010 { "javascript", "c", SrcLangExt::JS, ".js" },
5011 { "csharp", "c", SrcLangExt::CSharp, ".cs" },
5012 { "d", "c", SrcLangExt::D, ".d" },
5013 { "php", "c", SrcLangExt::PHP, ".php" },
5014 { "objective-c", "c", SrcLangExt::ObjC, ".m" },
5015 { "c", "c", SrcLangExt::Cpp, ".c" },
5016 { "c++", "c", SrcLangExt::Cpp, ".cpp" },
5017 { "slice", "c", SrcLangExt::Slice, ".ice" },
5018 { "python", "python", SrcLangExt::Python, ".py" },
5019 { "fortran", "fortran", SrcLangExt::Fortran, ".f" },
5020 { "fortranfree", "fortranfree", SrcLangExt::Fortran, ".f90" },
5021 { "fortranfixed", "fortranfixed", SrcLangExt::Fortran, ".f" },
5022 { "vhdl", "vhdl", SrcLangExt::VHDL, ".vhdl"},
5023 { "xml", "xml", SrcLangExt::XML, ".xml" },
5024 { "sql", "sql", SrcLangExt::SQL, ".sql" },
5025 { "md", "md", SrcLangExt::Markdown, ".md" },
5026 { "lex", "lex", SrcLangExt::Lex, ".l" },
5027};

Referenced by getLanguageFromCodeLang(), and updateLanguageMapping().

◆ g_matchArgsMutex

std::mutex g_matchArgsMutex
static

Definition at line 1858 of file util.cpp.

Referenced by matchArgument2().

◆ g_usedNames

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

Definition at line 3431 of file util.cpp.

Referenced by convertNameToFile().

◆ g_usedNamesCount

int g_usedNamesCount =1
static

Definition at line 3433 of file util.cpp.

Referenced by convertNameToFile().

◆ g_usedNamesMutex

std::mutex g_usedNamesMutex
static

Definition at line 3432 of file util.cpp.

Referenced by convertNameToFile().

◆ hex

const char* hex = "0123456789ABCDEF"
static

Definition at line 98 of file util.cpp.

◆ operatorScope

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

Definition at line 525 of file util.cpp.

525{ '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 524 of file util.cpp.

524{ '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 523 of file util.cpp.

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

Referenced by removeRedundantWhiteSpace().