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

Go to the source code of this file.

Classes

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

Macros

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

Functions

QCString removeAnonymousScopes (const QCString &str)
QCString replaceAnonymousScopes (const QCString &s, const QCString &replacement)
QCString stripAnonymousNamespaceScope (const QCString &s)
void writePageRef (OutputList &ol, const QCString &cn, const QCString &mn)
QCString generateMarker (int id)
QCString removeLongPathMarker (QCString path)
static QCString stripFromPath (const QCString &p, const StringVector &l)
QCString stripFromPath (const QCString &path)
QCString stripFromIncludePath (const QCString &path)
EntryType guessSection (const QCString &name)
QCString resolveTypeDef (const Definition *context, const QCString &qualifiedName, const Definition **typedefContext)
QCString removeRedundantWhiteSpace (const QCString &s)
int findParameterList (const QCString &name)
 Returns the position in the string where a function parameter list begins, or -1 if one is not found.
bool rightScopeMatch (const QCString &scope, const QCString &name)
bool leftScopeMatch (const QCString &scope, const QCString &name)
void linkifyText (const TextGeneratorIntf &out, const Definition *scope, const FileDef *fileScope, const Definition *self, const QCString &text, bool autoBreak, bool external, bool keepSpaces, int indentLevel)
void writeMarkerList (OutputList &ol, const std::string &markerText, size_t numMarkers, std::function< void(size_t)> replaceFunc)
void writeExamples (OutputList &ol, const ExampleList &list)
QCString inlineArgListToDoc (const ArgumentList &al)
QCString inlineTemplateArgListToDoc (const ArgumentList &al)
QCString argListToString (const ArgumentList &al, bool useCanonicalType, bool showDefVals)
QCString tempArgListToString (const ArgumentList &al, SrcLangExt lang, bool includeDefault)
static void filterCRLF (std::string &contents)
static QCString getFilterFromList (const QCString &name, const StringVector &filterList, bool &found)
QCString getFileFilter (const QCString &name, bool isSourceCode)
bool transcodeCharacterStringToUTF8 (std::string &input, const char *inputEncoding)
QCString fileToString (const QCString &name, bool filter, bool isSourceCode)
void trimBaseClassScope (const BaseClassList &bcl, QCString &s, int level=0)
static void stripIrrelevantString (QCString &target, const QCString &str, 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 ArgumentList *srcAl, const Definition *dstScope, const FileDef *dstFileScope, const ArgumentList *dstAl, bool checkCV, SrcLangExt lang)
void mergeArguments (ArgumentList &srcAl, ArgumentList &dstAl, bool forceNameOverwrite)
bool matchTemplateArguments (const ArgumentList &srcAl, const ArgumentList &dstAl)
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

Definition at line 1854 of file util.cpp.

Referenced by matchArgument2(), and matchArguments2().

◆ NOMATCH

#define NOMATCH

Definition at line 1855 of file util.cpp.

Referenced by matchArgument2(), and matchArguments2().

◆ REL_PATH_TO_ROOT

#define REL_PATH_TO_ROOT   "../../"

Definition at line 96 of file util.cpp.

Referenced by relativePathToRoot().

Function Documentation

◆ addCodeOnlyMappings()

void addCodeOnlyMappings ( )

Definition at line 5115 of file util.cpp.

5116{
5117 updateLanguageMapping(".xml", "xml");
5118 updateLanguageMapping(".sql", "sql");
5119}
bool updateLanguageMapping(const QCString &extension, const QCString &language)
Definition util.cpp:5016

References updateLanguageMapping().

Referenced by generateOutput().

◆ addGroupListToTitle()

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

◆ addHtmlExtensionIfMissing()

void addHtmlExtensionIfMissing ( QCString & fName)

Definition at line 4837 of file util.cpp.

4838{
4839 if (fName.isEmpty()) return;
4840 int i_fs = fName.findRev('/');
4841 int i_bs = fName.findRev('\\');
4842 int i = fName.find('.',std::max({ i_fs, i_bs ,0})); // search for . after path part
4843 if (i==-1)
4844 {
4846 }
4847}
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 4021 of file util.cpp.

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

4743{
4744 //printf("addRefItem(sli=%d,key=%s,prefix=%s,name=%s,title=%s,args=%s)\n",(int)sli.size(),key,prefix,name,title,args);
4745 if (!key.isEmpty() && key[0]!='@') // check for @ to skip anonymous stuff (see bug427012)
4746 {
4747 for (RefItem *item : sli)
4748 {
4749 item->setPrefix(prefix);
4750 item->setScope(scope);
4751 item->setName(name);
4752 item->setTitle(title);
4753 item->setArgs(args);
4754 item->setGroup(key);
4755 }
4756 }
4757}
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 4610 of file util.cpp.

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

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

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

6447{
6448 if (s.isEmpty()) return;
6449
6450 const char *p = s.data();
6451 char c = 0;
6452 while ((c=*p))
6453 {
6454 if (c==markerInfo.markerChar) // potential start of marker
6455 {
6456 if (qstrncmp(p,markerInfo.beginStr,markerInfo.beginLen)==0) // start of begin marker
6457 {
6458 size_t len = markerInfo.beginLen;
6459 bool negate = *(p+len)=='!';
6460 if (negate) len++;
6461 p += len;
6462 QCString marker;
6463 while (*p)
6464 {
6465 if (markerInfo.closeLen==0 && *p=='\n') // matching end of line
6466 {
6467 warn(fileName,-1,"Remaining begin replacement with marker '{}'",marker);
6468 break;
6469 }
6470 else if (markerInfo.closeLen!= 0 && qstrncmp(p,markerInfo.closeStr,markerInfo.closeLen)==0) // matching marker closing
6471 {
6472 p += markerInfo.closeLen;
6473 warn(fileName,-1,"Remaining begin replacement with marker '{}'",marker);
6474 break;
6475 }
6476 marker += *p;
6477 p++;
6478 }
6479 }
6480 else if (qstrncmp(p,markerInfo.endStr,markerInfo.endLen)==0) // start of end marker
6481 {
6482 size_t len = markerInfo.endLen;
6483 bool negate = *(p+len)=='!';
6484 if (negate) len++;
6485 p += len;
6486 QCString marker;
6487 while (*p)
6488 {
6489 if (markerInfo.closeLen==0 && *p=='\n') // matching end of line
6490 {
6491 warn(fileName,-1,"Remaining end replacement with marker '{}'",marker);
6492 break;
6493 }
6494 else if (markerInfo.closeLen!= 0 && qstrncmp(p,markerInfo.closeStr,markerInfo.closeLen)==0) // matching marker closing
6495 {
6496 p += markerInfo.closeLen;
6497 warn(fileName,-1,"Remaining end replacement with marker '{}'",marker);
6498 break;
6499 }
6500 marker += *p;
6501 p++;
6502 }
6503 }
6504 }
6505 p++;
6506 }
6507}
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 4832 of file util.cpp.

4833{
4834 return fName.right(ext.length())==ext;
4835}

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

5226{
5227 MemberDef *bestMatch = getMemberFromSymbol(scope,fileScope,n);
5228
5229 if (bestMatch && bestMatch->isTypedef())
5230 return TRUE; // closest matching symbol is a typedef
5231 else
5232 return FALSE;
5233}
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:5173

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

Referenced by isVarWithConstructor().

◆ clearSubDirs()

void clearSubDirs ( const Dir & d)

Definition at line 3591 of file util.cpp.

3592{
3593 if (Config_getBool(CREATE_SUBDIRS))
3594 {
3595 // remove empty subdirectories
3596 int createSubdirsLevelPow2 = 1 << Config_getInt(CREATE_SUBDIRS_LEVEL);
3597 for (int l1=0;l1<16;l1++)
3598 {
3599 QCString subdir;
3600 subdir.sprintf("d%x",l1);
3601 for (int l2=0; l2 < createSubdirsLevelPow2; l2++)
3602 {
3603 QCString subsubdir;
3604 subsubdir.sprintf("d%x/d%02x",l1,l2);
3605 if (d.exists(subsubdir.str()) && d.isEmpty(subsubdir.str()))
3606 {
3607 d.rmdir(subsubdir.str());
3608 }
3609 }
3610 if (d.exists(subdir.str()) && d.isEmpty(subdir.str()))
3611 {
3612 d.rmdir(subdir.str());
3613 }
3614 }
3615 }
3616}
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 6748 of file util.cpp.

6749{
6750 int l = static_cast<int>(name.length());
6751 int lastSepPos = -1;
6752 const char *p = name.data();
6753 int i=l-2;
6754 int sharpCount=0;
6755 // --- begin optimized version of ts=name.findRev(">::");
6756 int ts = -1;
6757 while (i>=0)
6758 {
6759 if (p[i]=='>')
6760 {
6761 if (sharpCount==0 && p[i+1]==':' && p[i+2]==':')
6762 {
6763 ts=i;
6764 break;
6765 }
6766 sharpCount++;
6767 }
6768 else if (p[i]=='<')
6769 {
6770 sharpCount--;
6771 }
6772 i--;
6773 }
6774 // --- end optimized version
6775 if (ts==-1) ts=0; else p+=++ts;
6776 for (i=ts;i<l-1;i++)
6777 {
6778 char c=*p++;
6779 if (c==':' && *p==':') lastSepPos=i;
6780 if (c=='<') break;
6781 }
6782 return lastSepPos;
6783}

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

4882{
4883 if (str.isEmpty() || word==nullptr) return false;
4884 static const reg::Ex re(R"(\a+)");
4885 std::string s = str.str();
4886 for (reg::Iterator it(s,re) ; it!=reg::Iterator() ; ++it)
4887 {
4888 if (it->str()==word) return true;
4889 }
4890 return false;
4891}
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 3971 of file util.cpp.

3972{
3973 if (str.isEmpty()) return QCString();
3974
3975 std::string s = str.data();
3976 static const reg::Ex re(R"(&\a\w*;)");
3977 reg::Iterator it(s,re);
3979
3980 GrowBuf growBuf;
3981 size_t p=0, i=0, l=0;
3982 for (; it!=end ; ++it)
3983 {
3984 const auto &match = *it;
3985 p = match.position();
3986 l = match.length();
3987 if (p>i)
3988 {
3989 growBuf.addStr(s.substr(i,p-i));
3990 }
3991 QCString entity(match.str());
3993 const char *code=nullptr;
3994 if (symType!=HtmlEntityMapper::Sym_Unknown && (code=HtmlEntityMapper::instance().utf8(symType)))
3995 {
3996 growBuf.addStr(code);
3997 }
3998 else
3999 {
4000 growBuf.addStr(entity);
4001 }
4002 i=p+l;
4003 }
4004 growBuf.addStr(s.substr(i));
4005 growBuf.addChar(0);
4006 //printf("convertCharEntitiesToUTF8(%s)->%s\n",qPrint(s),growBuf.get());
4007 return growBuf.get();
4008}
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 6320 of file util.cpp.

6321{
6323 QCString parserName = Doxygen::parserManager->getParserName(ext);
6324
6325 if (parserName == "fortranfixed") return FortranFormat::Fixed;
6326 else if (parserName == "fortranfree") return FortranFormat::Free;
6327
6329}
static ParserManager * parserManager
Definition doxygen.h:131
QCString getFileNameExtension(const QCString &fn)
Definition util.cpp:5163

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

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

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

6159{
6160 bool extractPrivate = Config_getBool(EXTRACT_PRIVATE);
6161
6162 // default representing 1-1 mapping
6163 *outListType1=inListType;
6164 *outListType2=MemberListType::Invalid();
6165
6166 if (inProt==Protection::Public)
6167 {
6168 if (inListType.isPrivate())
6169 {
6170 *outListType1=MemberListType::Invalid();
6171 }
6172 }
6173 else if (inProt==Protection::Protected)
6174 {
6175 if (inListType.isPrivate() || inListType.isPublic())
6176 {
6177 *outListType1=MemberListType::Invalid();
6178 }
6179 else if (inListType.isProtected())
6180 {
6181 *outListType2=inListType.toPublic();
6182 }
6183 }
6184 else if (inProt==Protection::Private)
6185 {
6186 if (inListType.isPublic() || inListType.isProtected())
6187 {
6188 *outListType1=MemberListType::Invalid();
6189 }
6190 else if (inListType.isPrivate())
6191 {
6192 if (extractPrivate)
6193 {
6194 *outListType1=inListType.toPublic();
6195 *outListType2=inListType.toProtected();
6196 }
6197 else
6198 {
6199 *outListType1=MemberListType::Invalid();
6200 }
6201 }
6202 }
6203
6204 //printf("convertProtectionLevel(type=%s prot=%d): %s,%s\n",
6205 // qPrint(inListType.to_string()),inProt,qPrint(outListType1->to_string()),qPrint(outListType2->to_string()));
6206}
constexpr bool isProtected() const
Definition types.h:380
MemberListType toProtected() const
Definition types.h:438
MemberListType toPublic() const
Definition types.h:426
static MemberListType Invalid()
Definition types.h:371
constexpr bool isPrivate() const
Definition types.h:382
ML_TYPES constexpr bool isPublic() const
Definition types.h:378

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

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

◆ convertToHtml()

QCString convertToHtml ( const QCString & s,
bool keepEntities )

Converts a string to a HTML-encoded string

Definition at line 3887 of file util.cpp.

3888{
3889 if (s.isEmpty()) return s;
3890 GrowBuf growBuf;
3891 const char *p=s.data();
3892 char c = 0;
3893 while ((c=*p++))
3894 {
3895 switch (c)
3896 {
3897 case '<': growBuf.addStr("&lt;"); break;
3898 case '>': growBuf.addStr("&gt;"); break;
3899 case '&': if (keepEntities)
3900 {
3901 const char *e=p;
3902 char ce = 0;
3903 while ((ce=*e++))
3904 {
3905 if (ce==';' || (!(isId(ce) || ce=='#'))) break;
3906 }
3907 if (ce==';') // found end of an entity
3908 {
3909 // copy entry verbatim
3910 growBuf.addChar(c);
3911 while (p<e) growBuf.addChar(*p++);
3912 }
3913 else
3914 {
3915 growBuf.addStr("&amp;");
3916 }
3917 }
3918 else
3919 {
3920 growBuf.addStr("&amp;");
3921 }
3922 break;
3923 case '\'': growBuf.addStr("&#39;"); break;
3924 case '"': growBuf.addStr("&quot;"); break;
3925 default:
3926 {
3927 uint8_t uc = static_cast<uint8_t>(c);
3928 if (uc<32 && !isspace(c))
3929 {
3930 growBuf.addStr("&#x24");
3931 growBuf.addChar(hex[uc>>4]);
3932 growBuf.addChar(hex[uc&0xF]);
3933 growBuf.addChar(';');
3934 }
3935 else
3936 {
3937 growBuf.addChar(c);
3938 }
3939 }
3940 break;
3941 }
3942 }
3943 growBuf.addChar(0);
3944 return growBuf.get();
3945}
static constexpr auto hex
bool isId(int c)
Definition util.h:208

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

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

◆ convertToId()

QCString convertToId ( const QCString & s)

Converts a string to a HTML id string

Definition at line 3796 of file util.cpp.

3797{
3798 if (s.isEmpty()) return s;
3799 GrowBuf growBuf;
3800 const char *p = s.data();
3801 char c = 0;
3802 bool first = true;
3803 while ((c=*p++))
3804 {
3805 char encChar[4];
3806 if ((c>='0' && c<='9') || (c>='a' && c<='z') || (c>='A' && c<='Z') || c=='-')
3807 { // any permissive character except _
3808 if (first && c>='0' && c<='9') growBuf.addChar('a'); // don't start with a digit
3809 growBuf.addChar(c);
3810 }
3811 else
3812 {
3813 encChar[0]='_';
3814 encChar[1]=hex[static_cast<unsigned char>(c)>>4];
3815 encChar[2]=hex[static_cast<unsigned char>(c)&0xF];
3816 encChar[3]=0;
3817 growBuf.addStr(encChar);
3818 }
3819 first=FALSE;
3820 }
3821 growBuf.addChar(0);
3822 return growBuf.get();
3823}

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

3948{
3949 if (s.isEmpty()) return s;
3950 GrowBuf growBuf;
3951 const char *p=s.data();
3952 char c = 0;
3953 while ((c=*p++))
3954 {
3955 switch (c)
3956 {
3957 case '"': if (!singleQuotes) growBuf.addStr("\\\""); else growBuf.addChar(c);
3958 break;
3959 case '\'': if (singleQuotes) growBuf.addStr("\\\'"); else growBuf.addChar(c);
3960 break;
3961 case '\\': if (*p=='u' && *(p+1)=='{') growBuf.addStr("\\"); // keep \u{..} unicode escapes
3962 else growBuf.addStr("\\\\");
3963 break;
3964 default: growBuf.addChar(c); break;
3965 }
3966 }
3967 growBuf.addChar(0);
3968 return keepEntities ? growBuf.get() : convertCharEntitiesToUTF8(growBuf.get());
3969}
QCString convertCharEntitiesToUTF8(const QCString &str)
Definition util.cpp:3971

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

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

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

3830{
3831 if (s.isEmpty()) return s;
3832 return "a" + s;
3833}

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

5852{
5853 QCString result = url;
5854 if (!relPath.isEmpty() && !isURL(url))
5855 {
5856 result.prepend(relPath);
5857 }
5858 return result;
5859}
bool isURL(const QCString &url)
Checks whether the given url starts with a supported protocol.
Definition util.cpp:5839

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

5652{
5653 QCString url;
5654 if (!ref.isEmpty())
5655 {
5656 url = externalRef(relPath,ref,href);
5657 }
5658 if (!targetFileName.isEmpty())
5659 {
5660 QCString fn = targetFileName;
5661 if (ref.isEmpty())
5662 {
5663 if (!anchor.isEmpty() && isLocalFile)
5664 {
5665 fn=""; // omit file name for local links
5666 }
5667 else
5668 {
5669 url = relPath;
5670 }
5671 }
5672 url+=fn;
5673 }
5674 if (!anchor.isEmpty()) url+="#"+anchor;
5675 //printf("createHtmlUrl(relPath=%s,local=%d,target=%s,anchor=%s)=%s\n",qPrint(relPath),isLocalFile,qPrint(targetFileName),qPrint(anchor),qPrint(url));
5676 return url;
5677}
QCString externalRef(const QCString &relPath, const QCString &ref, bool href)
Definition util.cpp:5679

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

3565{
3566 if (Config_getBool(CREATE_SUBDIRS))
3567 {
3568 // create up to 4096 subdirectories
3569 int createSubdirsLevelPow2 = 1 << Config_getInt(CREATE_SUBDIRS_LEVEL);
3570 for (int l1=0; l1<16; l1++)
3571 {
3572 QCString subdir;
3573 subdir.sprintf("d%x",l1);
3574 if (!d.exists(subdir.str()) && !d.mkdir(subdir.str()))
3575 {
3576 term("Failed to create output directory '{}'\n",subdir);
3577 }
3578 for (int l2=0; l2<createSubdirsLevelPow2; l2++)
3579 {
3580 QCString subsubdir;
3581 subsubdir.sprintf("d%x/d%02x",l1,l2);
3582 if (!d.exists(subsubdir.str()) && !d.mkdir(subsubdir.str()))
3583 {
3584 term("Failed to create output directory '{}'\n",subsubdir);
3585 }
3586 }
3587 }
3588 }
3589}
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 6847 of file util.cpp.

6848{
6849 QCString result=name;
6850 if (result.endsWith("-g"))
6851 {
6852 int idx = result.find('-');
6853 result = result.left(idx)+templArgs;
6854 }
6855 return result;
6856}

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

Referenced by ClassDefImpl::className().

◆ detab()

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

Definition at line 6644 of file util.cpp.

6645{
6646 int tabSize = Config_getInt(TAB_SIZE);
6647 size_t size = s.length();
6648 GrowBuf out(size);
6649 const char *data = s.data();
6650 size_t i=0;
6651 int col=0;
6652 constexpr auto doxy_nbsp = "&_doxy_nbsp;"; // doxygen escape command for UTF-8 nbsp
6653 const int maxIndent=1000000; // value representing infinity
6654 int minIndent=maxIndent;
6655 bool skip = false;
6656 while (i<size)
6657 {
6658 char c = data[i++];
6659 switch(c)
6660 {
6661 case '\t': // expand tab
6662 {
6663 int stop = tabSize - (col%tabSize);
6664 //printf("expand at %d stop=%d\n",col,stop);
6665 col+=stop;
6666 while (stop--) out.addChar(' ');
6667 }
6668 break;
6669 case '\\':
6670 if (data[i] == '\\') // escaped command -> ignore
6671 {
6672 out.addChar(c);
6673 out.addChar(data[i++]);
6674 col+=2;
6675 }
6676 else if (i+5<size && literal_at(data+i,"iskip")) // \iskip command
6677 {
6678 i+=5;
6679 skip = true;
6680 }
6681 else if (i+8<size && literal_at(data+i,"endiskip")) // \endiskip command
6682 {
6683 i+=8;
6684 skip = false;
6685 }
6686 else // some other command
6687 {
6688 out.addChar(c);
6689 col++;
6690 }
6691 break;
6692 case '\n': // reset column counter
6693 out.addChar(c);
6694 col=0;
6695 break;
6696 case ' ': // increment column counter
6697 out.addChar(c);
6698 col++;
6699 break;
6700 default: // non-whitespace => update minIndent
6701 if (c<0 && i<size) // multibyte sequence
6702 {
6703 // special handling of the UTF-8 nbsp character 0xC2 0xA0
6704 int nb = isUTF8NonBreakableSpace(data);
6705 if (nb>0)
6706 {
6707 out.addStr(doxy_nbsp);
6708 i+=nb-1;
6709 }
6710 else
6711 {
6712 int bytes = getUTF8CharNumBytes(c);
6713 for (int j=0;j<bytes-1 && c;j++)
6714 {
6715 out.addChar(c);
6716 c = data[i++];
6717 }
6718 out.addChar(c);
6719 }
6720 }
6721 else
6722 {
6723 out.addChar(c);
6724 }
6725 if (!skip && col<minIndent) minIndent=col;
6726 col++;
6727 }
6728 }
6729 if (minIndent!=maxIndent) refIndent=minIndent; else refIndent=0;
6730 out.addChar(0);
6731 //printf("detab(\n%s\n)=[\n%s\n]\n",qPrint(s),qPrint(out.get()));
6732 return out.get();
6733}
bool literal_at(const char *data, const char(&str)[N])
returns TRUE iff data points to a substring that matches string literal str
Definition stringutil.h:98
int isUTF8NonBreakableSpace(const char *input)
Check if the first character pointed at by input is a non-breakable whitespace character.
Definition utf8.cpp:228
uint8_t getUTF8CharNumBytes(char c)
Returns the number of bytes making up a single UTF8 character given the first byte in the sequence.
Definition utf8.cpp:23

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

Referenced by Markdown::process().

◆ determineAbsoluteIncludeName()

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

Definition at line 3524 of file util.cpp.

3525{
3526 bool searchIncludes = Config_getBool(SEARCH_INCLUDES);
3527 QCString absIncFileName = incFileName;
3528 FileInfo fi(curFile.str());
3529 if (fi.exists())
3530 {
3531 QCString absName = fi.dirPath(TRUE)+"/"+incFileName;
3532 FileInfo fi2(absName.str());
3533 if (fi2.exists())
3534 {
3535 absIncFileName=fi2.absFilePath();
3536 }
3537 else if (searchIncludes) // search in INCLUDE_PATH as well
3538 {
3539 const StringVector &includePath = Config_getList(INCLUDE_PATH);
3540 for (const auto &incPath : includePath)
3541 {
3542 FileInfo fi3(incPath);
3543 if (fi3.exists() && fi3.isDir())
3544 {
3545 absName = fi3.absFilePath()+"/"+incFileName;
3546 //printf("trying absName=%s\n",qPrint(absName));
3547 FileInfo fi4(absName.str());
3548 if (fi4.exists())
3549 {
3550 absIncFileName=fi4.absFilePath();
3551 break;
3552 }
3553 //printf( "absIncFileName = %s\n", qPrint(absIncFileName) );
3554 }
3555 }
3556 }
3557 //printf( "absIncFileName = %s\n", qPrint(absIncFileName) );
3558 }
3559 return absIncFileName;
3560}
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 3254 of file util.cpp.

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

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

5636{
5637 bool extLinksInWindow = Config_getBool(EXT_LINKS_IN_WINDOW);
5638 if (extLinksInWindow)
5639 return "target=\"_blank\" ";
5640 else if (parent)
5641 return "target=\"_parent\" ";
5642 else
5643 return "";
5644}
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 5679 of file util.cpp.

5680{
5681 QCString result;
5682 if (!ref.isEmpty())
5683 {
5684 auto it = Doxygen::tagDestinationMap.find(ref.str());
5686 {
5687 result = it->second;
5688 size_t l = result.length();
5689 if (!relPath.isEmpty() && l>0 && result.at(0)=='.')
5690 { // relative path -> prepend relPath.
5691 result.prepend(relPath);
5692 l+=relPath.length();
5693 }
5694 if (l>0 && result.at(l-1)!='/') result+='/';
5695 if (!href) result.append("\" ");
5696 }
5697 }
5698 else
5699 {
5700 result = relPath;
5701 }
5702 return result;
5703}
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 6858 of file util.cpp.

6859{
6860 QCString text=rawStart;
6861 int i = text.find('"');
6862 assert(i!=-1);
6863 return text.mid(i+1,text.length()-i-2); // text=...R"xyz( -> delimiter=xyz
6864}

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

◆ extractCanonicalArgType()

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

Definition at line 1828 of file util.cpp.

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

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

Referenced by matchArgument2().

◆ extractCanonicalType()

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

Definition at line 1752 of file util.cpp.

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

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

4140{
4141 AUTO_TRACE("type='{}' name='{}' lang={}",type,name,lang);
4142 static const reg::Ex re_norm(R"(\a[\w:]*)");
4143 static const reg::Ex re_fortran(R"(\a[\w:()=]*)");
4144 const reg::Ex *re = &re_norm;
4145
4146 name.clear();
4147 templSpec.clear();
4148 if (type.isEmpty())
4149 {
4150 AUTO_TRACE_EXIT("empty type");
4151 return -1;
4152 }
4153 size_t typeLen=type.length();
4154 if (typeLen>0)
4155 {
4156 if (lang == SrcLangExt::Fortran)
4157 {
4158 if (type[pos]==',')
4159 {
4160 AUTO_TRACE_EXIT("comma");
4161 return -1;
4162 }
4163 if (!type.lower().startsWith("type"))
4164 {
4165 re = &re_fortran;
4166 }
4167 }
4168 std::string s = type.str();
4169 reg::Iterator it(s,*re,static_cast<int>(pos));
4171
4172 if (it!=end)
4173 {
4174 const auto &match = *it;
4175 size_t i = match.position();
4176 size_t l = match.length();
4177 size_t ts = i+l;
4178 size_t te = ts;
4179 size_t tl = 0;
4180
4181 while (ts<typeLen && type[static_cast<uint32_t>(ts)]==' ') ts++,tl++; // skip any whitespace
4182 if (ts<typeLen && type[static_cast<uint32_t>(ts)]=='<') // assume template instance
4183 {
4184 // locate end of template
4185 te=ts+1;
4186 int brCount=1;
4187 while (te<typeLen && brCount!=0)
4188 {
4189 if (type[static_cast<uint32_t>(te)]=='<')
4190 {
4191 if (te<typeLen-1 && type[static_cast<uint32_t>(te)+1]=='<') te++; else brCount++;
4192 }
4193 if (type[static_cast<uint32_t>(te)]=='>')
4194 {
4195 if (te<typeLen-1 && type[static_cast<uint32_t>(te)+1]=='>') te++; else brCount--;
4196 }
4197 te++;
4198 }
4199 }
4200 name = match.str();
4201 if (te>ts)
4202 {
4203 templSpec = QCString(type).mid(ts,te-ts);
4204 tl+=te-ts;
4205 pos=static_cast<int>(i+l+tl);
4206 }
4207 else // no template part
4208 {
4209 pos=static_cast<int>(i+l);
4210 }
4211 //printf("extractClassNameFromType([in] type=%s,[out] pos=%d,[out] name=%s,[out] templ=%s)=TRUE i=%d\n",
4212 // qPrint(type),pos,qPrint(name),qPrint(templSpec),i);
4213 AUTO_TRACE_EXIT("pos={} templSpec='{}' return={}",pos,templSpec,i);
4214 return static_cast<int>(i);
4215 }
4216 }
4217 pos = static_cast<int>(typeLen);
4218 //printf("extractClassNameFromType([in] type=%s,[out] pos=%d,[out] name=%s,[out] templ=%s)=FALSE\n",
4219 // qPrint(type),pos,qPrint(name),qPrint(templSpec));
4220 AUTO_TRACE_EXIT("not found");
4221 return -1;
4222}
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 6102 of file util.cpp.

6103{
6104 std::string s = docs.str();
6105 static const reg::Ex re(R"(\‍[([ inout,]+)\‍])");
6106 reg::Iterator it(s,re);
6108 if (it!=end)
6109 {
6110 const auto &match = *it;
6111 size_t p = match.position();
6112 size_t l = match.length();
6113 if (p==0 && l>2)
6114 {
6115 // make dir the part inside [...] without separators
6116 std::string dir = match[1].str();
6117 // strip , and ' ' from dir
6118 dir.erase(std::remove_if(dir.begin(),dir.end(),
6119 [](const char c) { return c==' ' || c==','; }
6120 ),dir.end());
6121 unsigned char ioMask=0;
6122 size_t inIndex = dir.find( "in");
6123 if ( inIndex!=std::string::npos) dir.erase( inIndex,2),ioMask|=(1<<0);
6124 size_t outIndex = dir.find("out");
6125 if (outIndex!=std::string::npos) dir.erase(outIndex,3),ioMask|=(1<<1);
6126 if (dir.empty() && ioMask!=0) // only in and/or out attributes found
6127 {
6128 docs = s.substr(l); // strip attributes
6129 if (ioMask==((1<<0)|(1<<1))) return "[in,out]";
6130 else if (ioMask==(1<<0)) return "[in]";
6131 else if (ioMask==(1<<1)) return "[out]";
6132 }
6133 }
6134 }
6135 return "";
6136}

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

Referenced by inlineArgListToDoc().

◆ extractEndRawStringDelimiter()

QCString extractEndRawStringDelimiter ( const char * rawEnd)

Definition at line 6866 of file util.cpp.

6867{
6868 QCString text=rawEnd;
6869 return text.mid(1,text.length()-2); // text=)xyz" -> delimiter=xyz
6870}

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

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

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

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

6014{
6015 bool allExternals = Config_getBool(ALLEXTERNALS);
6016 bool isDocFile = fd->isDocumentationFile();
6017 genSourceFile = !isDocFile && fd->generateSourceFile();
6018 return ( ((allExternals && fd->isLinkable()) ||
6020 ) &&
6021 !isDocFile
6022 );
6023}
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 1293 of file util.cpp.

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

Referenced by readInputFile().

◆ filterTitle()

QCString filterTitle ( const QCString & title)

Definition at line 5540 of file util.cpp.

5541{
5542 std::string tf;
5543 std::string t = title.str();
5544 static const reg::Ex re(R"(%[a-z_A-Z]+)");
5545 reg::Iterator it(t,re);
5547 size_t p = 0;
5548 for (; it!=end ; ++it)
5549 {
5550 const auto &match = *it;
5551 size_t i = match.position();
5552 size_t l = match.length();
5553 if (i>p) tf+=t.substr(p,i-p);
5554 tf+=match.str().substr(1); // skip %
5555 p=i+l;
5556 }
5557 tf+=t.substr(p);
5558 return tf;
5559}

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

4898{
4899 static reg::Ex re(R"(\s*(<\a+>)\s*)");
4900 std::string s = sentence.str();
4901 reg::Iterator it(s,re);
4903 std::string result;
4904 bool found=false;
4905 size_t p=0;
4906 for ( ; it!=end ; ++it)
4907 {
4908 const auto match = *it;
4909 std::string part = match[1].str();
4910 if (part!=word)
4911 {
4912 size_t i = match.position();
4913 size_t l = match.length();
4914 result+=s.substr(p,i-p);
4915 result+=match.str();
4916 p=i+l;
4917 }
4918 else
4919 {
4920 found=true;
4921 size_t i = match[1].position();
4922 size_t l = match[1].length();
4923 result+=s.substr(p,i-p);
4924 p=i+l;
4925 }
4926 }
4927 result+=s.substr(p);
4928 sentence = QCString(result).simplifyWhiteSpace();
4929 return found;
4930}
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 2826 of file util.cpp.

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

2912{
2913 ambig=false;
2914 QCString result;
2915 bool found=false;
2916 if (!found)
2917 {
2918 FileInfo fi(file.str());
2919 if (fi.exists())
2920 {
2921 result=fi.absFilePath();
2922 found=true;
2923 }
2924 }
2925 if (!found)
2926 {
2927 const StringVector &examplePathList = Config_getList(EXAMPLE_PATH);
2928 for (const auto &s : examplePathList)
2929 {
2930 std::string absFileName = s+(Portable::pathSeparator()+file).str();
2931 FileInfo fi(absFileName);
2932 if (fi.exists())
2933 {
2934 result=fi.absFilePath();
2935 found=true;
2936 }
2937 }
2938 }
2939
2940 if (!found)
2941 {
2942 // as a fallback we also look in the exampleNameDict
2944 if (fd && !ambig)
2945 {
2946 result=fd->absFilePath();
2947 }
2948 }
2949 return result;
2950}
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:2826

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

6587{
6589 return reg::search(s,match,re) ? static_cast<int>(match.position()) : -1;
6590}
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 6578 of file util.cpp.

6579{
6580 auto it = std::find(sv.begin(),sv.end(),s);
6581 return it!=sv.end() ? static_cast<int>(it-sv.begin()) : -1;
6582}

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

◆ findModuleDef()

ModuleDef * findModuleDef ( const Definition * d)
static

Definition at line 4759 of file util.cpp.

4760{
4761 ModuleDef *mod = nullptr;
4763 {
4764 const FileDef *fd = toFileDef(d);
4765 if (fd) mod = fd->getModuleDef();
4766 }
4768 {
4769 const ClassDef *cd = toClassDef(d);
4770 if (cd)
4771 {
4772 const FileDef *fd = cd->getFileDef();
4773 if (fd) mod = fd->getModuleDef();
4774 }
4775 }
4777 {
4778 const ConceptDef *cd = toConceptDef(d);
4779 if (cd)
4780 {
4781 const FileDef *fd = cd->getFileDef();
4782 if (fd) mod = fd->getModuleDef();
4783 }
4784 }
4785 return mod;
4786}
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:1954

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

3483{
3484 QCString fn = stripFromPath(fileName)+":"+QCString().setNum(count);
3485 const int sig_size=16;
3486 uint8_t md5_sig[sig_size];
3487 MD5Buffer(fn.data(),static_cast<unsigned int>(fn.length()),md5_sig);
3488 char result[sig_size*3+2];
3489 char *p = result;
3490 *p++='@';
3491 for (int i=0;i<sig_size;i++)
3492 {
3493 static const char oct[]="01234567";
3494 uint8_t byte = md5_sig[i];
3495 *p++=oct[(byte>>6)&7];
3496 *p++=oct[(byte>>3)&7];
3497 *p++=oct[(byte>>0)&7];
3498 }
3499 *p='\0';
3500 return result;
3501}
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 2798 of file util.cpp.

2799{
2800 //printf("generateFileRef(%s,%s)\n",name,text);
2801 QCString linkText = text.isEmpty() ? text : name;
2802 //FileInfo *fi;
2803 bool ambig = false;
2805 if (fd && fd->isLinkable())
2806 // link to documented input file
2807 ol.writeObjectLink(fd->getReference(),fd->getOutputFileBase(),QCString(),linkText);
2808 else
2809 ol.docify(linkText);
2810}
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 5564 of file util.cpp.

5568{
5569 bool caseSenseNames = getCaseSenseNames();
5570 bool found = FALSE;
5571
5572 if (!patList.empty())
5573 {
5574 std::string fn = fi.fileName();
5575 std::string fp = fi.filePath();
5576 std::string afp= fi.absFilePath();
5577
5578 for (const auto &li : patList)
5579 {
5580 std::string pattern = getter(li).str();
5581 if (!pattern.empty())
5582 {
5583 size_t i=pattern.find('=');
5584 if (i!=std::string::npos) pattern=pattern.substr(0,i); // strip of the extension specific filter name
5585
5586 if (!caseSenseNames)
5587 {
5588 pattern = QCString(pattern).lower().str();
5589 fn = QCString(fn).lower().str();
5590 fp = QCString(fp).lower().str();
5591 afp = QCString(afp).lower().str();
5592 }
5593 reg::Ex re(pattern,reg::Ex::Mode::Wildcard);
5594 found = re.isValid() && (reg::match(fn,re) ||
5595 (fn!=fp && reg::match(fp,re)) ||
5596 (fn!=afp && fp!=afp && reg::match(afp,re)));
5597 if (found)
5598 {
5599 elem = li;
5600 break;
5601 }
5602 //printf("Matching '%s' against pattern '%s' found=%d\n",
5603 // qPrint(fi->fileName()),qPrint(pattern),found);
5604 }
5605 }
5606 }
5607 return found;
5608}
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 1577 of file util.cpp.

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

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

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

3246{
3247 auto caseSenseNames = Config_getEnum(CASE_SENSE_NAMES);
3248
3249 if (caseSenseNames == CASE_SENSE_NAMES_t::YES) return true;
3250 else if (caseSenseNames == CASE_SENSE_NAMES_t::NO) return false;
3252}
#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 2230 of file util.cpp.

2231{
2232 GetDefResult result;
2233 if (input.memberName.isEmpty()) return result;
2234 AUTO_TRACE("scopeName={},memberName={},forceEmptyScope={}",
2235 input.scopeName,input.memberName,input.forceEmptyScope);
2236
2237 //printf("@@ --- getDefsNew(%s,%s)-----------\n",qPrint(scName),qPrint(mbName));
2238 const Definition *scope = Doxygen::globalScope;
2239 SymbolResolver resolver;
2240 if (input.currentFile) resolver.setFileScope(input.currentFile);
2241 if (!input.scopeName.isEmpty() && !input.forceEmptyScope)
2242 {
2243 scope = resolver.resolveSymbol(scope,input.scopeName);
2244 }
2245 if (scope==Doxygen::globalScope)
2246 {
2247 scope = input.currentFile;
2248 }
2249 //printf("@@ -> found scope scope=%s member=%s out=%s\n",qPrint(input.scopeName),qPrint(input.memberName),qPrint(scope?scope->name():""));
2250 //
2251 const Definition *symbol = resolver.resolveSymbol(scope,input.memberName,input.args,input.checkCV,input.insideCode,true);
2252 //printf("@@ -> found symbol in=%s out=%s\n",qPrint(input.memberName),qPrint(symbol?symbol->qualifiedName():QCString()));
2253 if (symbol && symbol->definitionType()==Definition::TypeMember)
2254 {
2255 result.md = toMemberDef(symbol);
2256 result.cd = result.md->getClassDef();
2257 if (result.cd==nullptr) result.nd = result.md->getNamespaceDef();
2258 if (result.cd==nullptr && result.nd==nullptr) result.fd = result.md->getFileDef();
2259 result.gd = result.md->getGroupDef();
2260 result.found = true;
2261 }
2262 else if (symbol && symbol->definitionType()==Definition::TypeClass)
2263 {
2264 result.cd = toClassDef(symbol);
2265 result.found = true;
2266 }
2267 else if (symbol && symbol->definitionType()==Definition::TypeNamespace)
2268 {
2269 result.nd = toNamespaceDef(symbol);
2270 result.found = true;
2271 }
2272 else if (symbol && symbol->definitionType()==Definition::TypeConcept)
2273 {
2274 result.cnd = toConceptDef(symbol);
2275 result.found = true;
2276 }
2277 else if (symbol && symbol->definitionType()==Definition::TypeModule)
2278 {
2279 result.modd = toModuleDef(symbol);
2280 result.found = true;
2281 }
2282 return result;
2283}
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 6213 of file util.cpp.

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

5622{
5623 InputFileEncoding elem;
5624 auto getter = [](const InputFileEncoding &e) -> QCString { return e.pattern; };
5625 if (genericPatternMatch(fi,Doxygen::inputFileEncodingList,elem,getter)) // check for file specific encoding
5626 {
5627 return elem.encoding;
5628 }
5629 else // fall back to default encoding
5630 {
5631 return Config_getString(INPUT_ENCODING);
5632 }
5633}
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:5564

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

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

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

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

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

5140{
5141 // try the extension
5142 auto lang = getLanguageFromFileName(fileName, SrcLangExt::Unknown);
5143 if (lang == SrcLangExt::Unknown)
5144 {
5145 // try the language names
5146 QCString langName = fileName.lower();
5147 if (langName.at(0)=='.') langName = langName.mid(1);
5148 auto it = std::find_if(g_lang2extMap.begin(),g_lang2extMap.end(),
5149 [&langName](const auto &info) { return info.langName==langName; });
5150 if (it != g_lang2extMap.end())
5151 {
5152 lang = it->parserId;
5153 fileName = it->defExt;
5154 }
5155 else // default to C++
5156 {
5157 return SrcLangExt::Cpp;
5158 }
5159 }
5160 return lang;
5161}
SrcLangExt getLanguageFromFileName(const QCString &fileName, SrcLangExt defLang)
Definition util.cpp:5121
static std::vector< Lang2ExtMap > g_lang2extMap
Definition util.cpp:4992

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

5122{
5123 FileInfo fi(fileName.str());
5124 // we need only the part after the last ".", newer implementations of FileInfo have 'suffix()' for this.
5125 QCString extName = QCString(fi.extension(FALSE)).lower();
5126 if (extName.isEmpty()) extName=".no_extension";
5127 if (extName.at(0)!='.') extName.prepend(".");
5128 auto it = g_extLookup.find(extName.str());
5129 if (it!=g_extLookup.end()) // listed extension
5130 {
5131 //printf("getLanguageFromFileName(%s)=%x\n",qPrint(fi.extension()),*pVal);
5132 return it->second;
5133 }
5134 //printf("getLanguageFromFileName(%s) not found!\n",qPrint(fileName));
5135 return defLang; // not listed => assume C-ish language.
5136}
static std::unordered_map< std::string, SrcLangExt > g_extLookup
Definition util.cpp:4982

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

5824{
5825 if (lang==SrcLangExt::Java || lang==SrcLangExt::CSharp || lang==SrcLangExt::VHDL || lang==SrcLangExt::Python)
5826 {
5827 return ".";
5828 }
5829 else if (lang==SrcLangExt::PHP && !classScope)
5830 {
5831 return "\\";
5832 }
5833 else
5834 {
5835 return "::";
5836 }
5837}

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

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

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

4014{
4015 return theTranslator->trOverloadText();
4016 //"This is an overloaded member function, "
4017 // "provided for convenience. It differs from the above "
4018 // "function only in what argument(s) it accepts.";
4019}
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 3161 of file util.cpp.

3162{
3163 if (name.isEmpty()) return 0;
3164 const StringVector &sl = Config_getList(IGNORE_PREFIX);
3165 for (const auto &s : sl)
3166 {
3167 const char *ps=s.c_str();
3168 const char *pd=name.data();
3169 int i=0;
3170 while (*ps!=0 && *pd!=0 && *ps==*pd) ps++,pd++,i++;
3171 if (*ps==0 && *pd!=0)
3172 {
3173 return i;
3174 }
3175 }
3176 return 0;
3177}

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

6736{
6737 QCString projectCookie = Config_getString(HTML_PROJECT_COOKIE);
6738 if (projectCookie.isEmpty()) return QCString();
6739 uint8_t md5_sig[16];
6740 char sigStr[34];
6741 MD5Buffer(projectCookie.data(),static_cast<unsigned int>(projectCookie.length()),md5_sig);
6742 MD5SigToString(md5_sig,sigStr);
6743 sigStr[32]='_'; sigStr[33]=0;
6744 return sigStr;
6745}

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

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

4564{
4565 int sl=static_cast<int>(s.length());
4566 int sp=p;
4567 int count=0;
4568 bool done=false;
4569 if (sp>=sl) return -1;
4570 while (sp<sl)
4571 {
4572 char c=s.at(sp);
4573 if (c==':') sp++,p++; else break;
4574 }
4575 while (sp<sl)
4576 {
4577 char c=s.at(sp);
4578 switch (c)
4579 {
4580 case ':': // found next part
4581 goto found;
4582 case '<': // skip template specifier
4583 count=1;sp++;
4584 done=false;
4585 while (sp<sl && !done)
4586 {
4587 // TODO: deal with << and >> operators!
4588 c=s.at(sp++);
4589 switch(c)
4590 {
4591 case '<': count++; break;
4592 case '>': count--; if (count==0) done=true; break;
4593 default: break;
4594 }
4595 }
4596 break;
4597 default:
4598 sp++;
4599 break;
4600 }
4601 }
4602found:
4603 *l=sp-p;
4604 //printf("getScopeFragment(%s,%d)=%s\n",qPrint(s),p,qPrint(s.mid(p,*l)));
4605 return p;
4606}

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

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

References updateLanguageMapping().

Referenced by initDoxygen().

◆ inlineArgListToDoc()

QCString inlineArgListToDoc ( const ArgumentList & al)

Definition at line 1147 of file util.cpp.

1148{
1149 QCString paramDocs;
1150 if (al.hasDocumentation())
1151 {
1152 for (const Argument &a : al)
1153 {
1154 if (a.hasDocumentation())
1155 {
1156 QCString docsWithoutDir = a.docs;
1157 QCString direction = extractDirection(docsWithoutDir);
1158 paramDocs+=" \\ilinebr @param"+direction+" "+a.name+" "+docsWithoutDir;
1159 }
1160 }
1161 }
1162 return paramDocs;
1163}
bool hasDocumentation() const
Definition arguments.cpp:21
QCString extractDirection(QCString &docs)
Strip the direction part from docs and return it as a string in canonical form The input docs string ...
Definition util.cpp:6102

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

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

◆ inlineTemplateArgListToDoc()

QCString inlineTemplateArgListToDoc ( const ArgumentList & al)

Definition at line 1165 of file util.cpp.

1166{
1167 QCString paramDocs;
1168 if (al.hasTemplateDocumentation())
1169 {
1170 for (const Argument &a : al)
1171 {
1172 if (!a.docs.isEmpty())
1173 {
1174 if (!a.name.isEmpty())
1175 {
1176 paramDocs+=" \\ilinebr @tparam "+a.name+" "+a.docs;
1177 }
1178 else if (!a.type.isEmpty())
1179 {
1180 QCString type = a.type;
1181 type.stripPrefix("class ");
1182 type.stripPrefix("typename ");
1183 type = type.stripWhiteSpace();
1184 paramDocs+=" \\ilinebr @tparam "+type+" "+a.docs;
1185 }
1186 }
1187 }
1188 }
1189 return paramDocs;
1190}
bool hasTemplateDocumentation() const
Definition arguments.cpp:29

References ArgumentList::hasTemplateDocumentation(), QCString::stripPrefix(), and QCString::stripWhiteSpace().

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

◆ insertTemplateSpecifierInScope()

QCString insertTemplateSpecifierInScope ( const QCString & scope,
const QCString & templ )

Definition at line 3670 of file util.cpp.

3671{
3672 QCString result=scope;
3673 if (!templ.isEmpty() && scope.find('<')==-1)
3674 {
3675 int si=0, pi=0;
3676 ClassDef *cd=nullptr;
3677 while (
3678 (si=scope.find("::",pi))!=-1 && !getClass(scope.left(si)+templ) &&
3679 ((cd=getClass(scope.left(si)))==nullptr || cd->templateArguments().empty())
3680 )
3681 {
3682 //printf("Tried '%s'\n",qPrint((scope.left(si)+templ)));
3683 pi=si+2;
3684 }
3685 if (si==-1) // not nested => append template specifier
3686 {
3687 result+=templ;
3688 }
3689 else // nested => insert template specifier before after first class name
3690 {
3691 result=scope.left(si) + templ + scope.right(scope.length()-si);
3692 }
3693 }
3694 //printf("insertTemplateSpecifierInScope('%s','%s')=%s\n",
3695 // qPrint(scope),qPrint(templ),qPrint(result));
3696 return result;
3697}
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 6606 of file util.cpp.

6607{
6608 QCString result;
6609 int residual = n;
6610
6611 char modVal[2];
6612 modVal[1] = 0;
6613 while (residual > 0)
6614 {
6615 modVal[0] = (upper ? 'A': 'a') + (residual-1)%26;
6616 result = modVal + result;
6617 residual = (residual-1) / 26;
6618 }
6619 return result;
6620}

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

◆ integerToRoman()

QCString integerToRoman ( int n,
bool upper )

Definition at line 6622 of file util.cpp.

6623{
6624 static const char *str_romans_upper[] = { "M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I" };
6625 static const char *str_romans_lower[] = { "m", "cm", "d", "cd", "c", "xc", "l", "xl", "x", "ix", "v", "iv", "i" };
6626 static const int values[] = { 1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1 };
6627 static const char **str_romans = upper ? str_romans_upper : str_romans_lower;
6628
6629 QCString result;
6630 int residual = n;
6631
6632 for (int i = 0; i < 13; ++i)
6633 {
6634 while (residual - values[i] >= 0)
6635 {
6636 result += str_romans[i];
6637 residual -= values[i];
6638 }
6639 }
6640
6641 return result;
6642}

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

◆ isLowerCase()

bool isLowerCase ( QCString & s)
static

Definition at line 2362 of file util.cpp.

2363{
2364 if (s.isEmpty()) return true;
2365 const char *p=s.data();
2366 int c=0;
2367 while ((c=static_cast<uint8_t>(*p++))) if (!islower(c)) return false;
2368 return true;
2369}

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

5840{
5841 static const std::unordered_set<std::string> schemes = {
5842 "http", "https", "ftp", "ftps", "sftp", "file", "news", "irc", "ircs"
5843 };
5844 QCString loc_url = url.stripWhiteSpace();
5845 int colonPos = loc_url.find(':');
5846 return colonPos!=-1 && schemes.find(loc_url.left(colonPos).str())!=schemes.end();
5847}

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

6594{
6595 std::string result;
6596 bool first=true;
6597 for (const auto &s : sv)
6598 {
6599 if (!first) result+=delimiter;
6600 first=false;
6601 result+=s;
6602 }
6603 return result;
6604}

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

◆ keyWordsFortranC()

bool keyWordsFortranC ( const char * contents)
static

Definition at line 6247 of file util.cpp.

6248{
6249 static const std::unordered_set<std::string> fortran_C_keywords = {
6250 "character", "call", "close", "common", "continue",
6251 "case", "contains", "cycle", "class", "codimension",
6252 "concurrent", "contiguous", "critical"
6253 };
6254
6255 if (*contents != 'c' && *contents != 'C') return false;
6256
6257 const char *c = contents;
6258 QCString keyword;
6259 while (*c && *c != ' ') {keyword += *c; c++;}
6260 keyword = keyword.lower();
6261
6262 return (fortran_C_keywords.find(keyword.str()) != fortran_C_keywords.end());
6263}

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

Referenced by recognizeFixedForm().

◆ langToString()

QCString langToString ( SrcLangExt lang)

Returns a string representation of lang.

Definition at line 5817 of file util.cpp.

5818{
5819 return to_string(lang);
5820}
static const char * to_string(Protection prot)
Definition types.h:38

References to_string().

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

◆ leftScopeMatch()

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

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

5797{
5798 int result = 1;
5799
5800 // find the character positions of the first marker
5801 int m1 = text.find(marker);
5802 if (m1==-1) return result;
5803
5804 // find start line positions for the markers
5805 bool found=false;
5806 int p=0, i=0;
5807 while (!found && (i=text.find('\n',p))!=-1)
5808 {
5809 found = (p<=m1 && m1<i); // found the line with the start marker
5810 p=i+1;
5811 result++;
5812 }
5813 return result;
5814}

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

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

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

◆ linkToText()

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

Definition at line 2630 of file util.cpp.

2631{
2632 //bool optimizeOutputJava = Config_getBool(OPTIMIZE_OUTPUT_JAVA);
2633 QCString result=link;
2634 if (!result.isEmpty())
2635 {
2636 // replace # by ::
2637 result=substitute(result,"#","::");
2638 // replace . by ::
2639 if (!isFileName && result.find('<')==-1) result=substitute(result,".","::",3);
2640 // strip leading :: prefix if present
2641 if (result.at(0)==':' && result.at(1)==':')
2642 {
2643 result=result.right(result.length()-2);
2644 }
2646 if (sep!="::")
2647 {
2648 result=substitute(result,"::",sep);
2649 }
2650 }
2651 //printf("linkToText(%s,lang=%d)=%s\n",qPrint(link),lang,qPrint(result));
2652 return result;
2653}
QCString getLanguageSpecificSeparator(SrcLangExt lang, bool classScope)
Returns the scope separator to use given the programming language lang.
Definition util.cpp:5823

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

6209{
6210 return Doxygen::mainPage!=nullptr && Doxygen::mainPage->hasTitle();
6211}
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 6837 of file util.cpp.

6838{
6839 int idx = name.find('<');
6840 if (idx!=-1)
6841 {
6842 return name.left(idx)+"-"+QCString().setNum(name.contains(",")+1)+"-g";
6843 }
6844 return name;
6845}
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 1893 of file util.cpp.

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

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

Referenced by matchArguments2().

◆ matchArguments2()

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

Definition at line 1959 of file util.cpp.

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

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

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

◆ matchCanonicalTypes()

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

Definition at line 1861 of file util.cpp.

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

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

Referenced by matchArgument2().

◆ matchTemplateArguments()

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

Definition at line 2197 of file util.cpp.

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

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

Referenced by buildFunctionList().

◆ mergeArguments()

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

Definition at line 2053 of file util.cpp.

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

6786{
6787 if (Config_getBool(CALL_GRAPH) !=md1->hasCallGraph()) md2->overrideCallGraph(md1->hasCallGraph());
6788 if (Config_getBool(CALLER_GRAPH)!=md1->hasCallerGraph()) md2->overrideCallerGraph(md1->hasCallerGraph());
6789 if (Config_getBool(CALL_GRAPH) !=md2->hasCallGraph()) md1->overrideCallGraph( md2->hasCallGraph());
6790 if (Config_getBool(CALLER_GRAPH)!=md2->hasCallerGraph()) md1->overrideCallerGraph(md2->hasCallerGraph());
6791
6792 if (Config_getBool(SHOW_ENUM_VALUES) !=md1->hasEnumValues()) md2->overrideEnumValues(md1->hasEnumValues());
6793 if (Config_getBool(SHOW_ENUM_VALUES) !=md2->hasEnumValues()) md1->overrideEnumValues( md2->hasEnumValues());
6794
6795 if (Config_getBool(REFERENCED_BY_RELATION)!=md1->hasReferencedByRelation()) md2->overrideReferencedByRelation(md1->hasReferencedByRelation());
6796 if (Config_getBool(REFERENCES_RELATION) !=md1->hasReferencesRelation()) md2->overrideReferencesRelation(md1->hasReferencesRelation());
6797 if (Config_getBool(REFERENCED_BY_RELATION)!=md2->hasReferencedByRelation()) md1->overrideReferencedByRelation(md2->hasReferencedByRelation());
6798 if (Config_getBool(REFERENCES_RELATION) !=md2->hasReferencesRelation()) md1->overrideReferencesRelation(md2->hasReferencesRelation());
6799
6800 if (Config_getBool(INLINE_SOURCES)!=md1->hasInlineSource()) md2->overrideInlineSource(md1->hasInlineSource());
6801 if (Config_getBool(INLINE_SOURCES)!=md2->hasInlineSource()) md1->overrideInlineSource(md2->hasInlineSource());
6802}
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 4518 of file util.cpp.

4519{
4520 AUTO_TRACE("leftScope='{}' rightScope='{}'",leftScope,rightScope);
4521 // case leftScope=="A" rightScope=="A::B" => result = "A::B"
4522 if (leftScopeMatch(leftScope,rightScope))
4523 {
4524 AUTO_TRACE_EXIT("case1={}",rightScope);
4525 return rightScope;
4526 }
4527 QCString result;
4528 int i=0,p=static_cast<int>(leftScope.length());
4529
4530 // case leftScope=="A::B" rightScope=="B::C" => result = "A::B::C"
4531 // case leftScope=="A::B" rightScope=="B" => result = "A::B"
4532 bool found=FALSE;
4533 while ((i=leftScope.findRev("::",p))>0)
4534 {
4535 if (leftScopeMatch(rightScope,leftScope.right(leftScope.length()-i-2)))
4536 {
4537 result = leftScope.left(i+2)+rightScope;
4538 found=TRUE;
4539 }
4540 p=i-1;
4541 }
4542 if (found)
4543 {
4544 AUTO_TRACE_EXIT("case2={}",result);
4545 return result;
4546 }
4547
4548 // case leftScope=="A" rightScope=="B" => result = "A::B"
4549 result=leftScope;
4550 if (!result.isEmpty() && !rightScope.isEmpty()) result+="::";
4551 result+=rightScope;
4552 AUTO_TRACE_EXIT("case3={}",result);
4553 return result;
4554}
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 5235 of file util.cpp.

5236{
5237 if (startPos>=len) return len;
5238 uint8_t c = static_cast<uint8_t>(utf8Str[startPos]);
5239 int bytes=getUTF8CharNumBytes(c);
5240 if (c=='&') // skip over character entities
5241 {
5242 bytes=1;
5243 int (*matcher)(int) = nullptr;
5244 c = static_cast<uint8_t>(utf8Str[startPos+bytes]);
5245 if (c=='#') // numerical entity?
5246 {
5247 bytes++;
5248 c = static_cast<uint8_t>(utf8Str[startPos+bytes]);
5249 if (c=='x') // hexadecimal entity?
5250 {
5251 bytes++;
5252 matcher = std::isxdigit;
5253 }
5254 else // decimal entity
5255 {
5256 matcher = std::isdigit;
5257 }
5258 }
5259 else if (std::isalnum(c)) // named entity?
5260 {
5261 bytes++;
5262 matcher = std::isalnum;
5263 }
5264 if (matcher)
5265 {
5266 while ((c = static_cast<uint8_t>(utf8Str[startPos+bytes]))!=0 && matcher(c))
5267 {
5268 bytes++;
5269 }
5270 }
5271 if (c!=';')
5272 {
5273 bytes=1; // not a valid entity, reset bytes counter
5274 }
5275 }
5276 return startPos+bytes;
5277}

References getUTF8CharNumBytes().

Referenced by parseCommentAsText().

◆ normalizeNonTemplateArgumentsInString()

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

Definition at line 4224 of file util.cpp.

4228{
4229 // skip until <
4230 int p=name.find('<');
4231 if (p==-1) return name;
4232 p++;
4233 QCString result = name.left(p);
4234
4235 std::string s = name.mid(p).str();
4236 static const reg::Ex re(R"([\a:][\w:]*)");
4237 reg::Iterator it(s,re);
4239 size_t pi=0;
4240 // for each identifier in the template part (e.g. B<T> -> T)
4241 for (; it!=end ; ++it)
4242 {
4243 const auto &match = *it;
4244 size_t i = match.position();
4245 size_t l = match.length();
4246 result += s.substr(pi,i-pi);
4247 QCString n(match.str());
4248 bool found=FALSE;
4249 for (const Argument &formArg : formalArgs)
4250 {
4251 if (formArg.name == n)
4252 {
4253 found=TRUE;
4254 break;
4255 }
4256 }
4257 if (!found)
4258 {
4259 // try to resolve the type
4260 SymbolResolver resolver;
4261 const ClassDef *cd = resolver.resolveClass(context,n);
4262 if (cd)
4263 {
4264 result+=cd->name();
4265 }
4266 else
4267 {
4268 result+=n;
4269 }
4270 }
4271 else
4272 {
4273 result+=n;
4274 }
4275 pi=i+l;
4276 }
4277 result+=s.substr(pi);
4278 //printf("normalizeNonTemplateArgumentInString(%s)=%s\n",qPrint(name),qPrint(result));
4279 return removeRedundantWhiteSpace(result);
4280}
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 6220 of file util.cpp.

6221{
6222 assert(!f.is_open());
6223 bool fileOpened=FALSE;
6224 bool writeToStdout=outFile=="-";
6225 if (writeToStdout) // write to stdout
6226 {
6227 f.basic_ios<char>::rdbuf(std::cout.rdbuf());
6228 fileOpened = true;
6229 }
6230 else // write to file
6231 {
6232 FileInfo fi(outFile.str());
6233 if (fi.exists()) // create a backup
6234 {
6235 Dir dir;
6236 FileInfo backup(fi.filePath()+".bak");
6237 if (backup.exists()) // remove existing backup
6238 dir.remove(backup.filePath());
6239 dir.rename(fi.filePath(),fi.filePath()+".bak");
6240 }
6241 f = Portable::openOutputStream(outFile);
6242 fileOpened = f.is_open();
6243 }
6244 return fileOpened;
6245}
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 5335 of file util.cpp.

5336{
5337 std::lock_guard lock(g_docCacheMutex);
5338 auto it = g_docCache.find(doc.str());
5339 if (it != g_docCache.end())
5340 {
5341 //printf("Cache: [%s]->[%s]\n",qPrint(doc),qPrint(it->second));
5342 return it->second;
5343 }
5344 auto parser { createDocParser() };
5345 auto ast { validatingParseTitle(*parser.get(),fileName,lineNr,doc) };
5346 auto astImpl = dynamic_cast<const DocNodeAST*>(ast.get());
5347 QCString result;
5348 if (astImpl)
5349 {
5350 TextStream t;
5351 OutputCodeList codeList;
5352 codeList.add<HtmlCodeGenerator>(&t);
5353 HtmlDocVisitor visitor(t,codeList,scope,fileName);
5354 std::visit(visitor,astImpl->root);
5355 result = t.str();
5356 }
5357 else // fallback, should not happen
5358 {
5359 result = filterTitle(doc);
5360 }
5361 //printf("Conversion: [%s]->[%s]\n",qPrint(doc),qPrint(result));
5362 g_docCache.insert(std::make_pair(doc.str(),result));
5363 return result;
5364}
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:5333
QCString filterTitle(const QCString &title)
Definition util.cpp:5540
static std::mutex g_docCacheMutex
Definition util.cpp:5332

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

5281{
5282 if (doc.isEmpty()) return "";
5283 //printf("parseCommentAsText(%s)\n",qPrint(doc));
5284 TextStream t;
5285 auto parser { createDocParser() };
5286 auto ast { validatingParseDoc(*parser.get(),
5287 fileName,
5288 lineNr,
5289 scope,
5290 md,
5291 doc,
5292 DocOptions()
5293 .setAutolinkSupport(false))
5294 };
5295 auto astImpl = dynamic_cast<const DocNodeAST*>(ast.get());
5296 if (astImpl)
5297 {
5298 TextDocVisitor visitor(t);
5299 std::visit(visitor,astImpl->root);
5300 }
5302 int i=0;
5303 int charCnt=0;
5304 int l=static_cast<int>(result.length());
5305 while ((i=nextUTF8CharPosition(result,l,i))<l)
5306 {
5307 charCnt++;
5308 if (charCnt>=80) break;
5309 }
5310 if (charCnt>=80) // try to truncate the string
5311 {
5312 while ((i=nextUTF8CharPosition(result,l,i))<l && charCnt<100)
5313 {
5314 charCnt++;
5315 if (result.at(i)==',' ||
5316 result.at(i)=='.' ||
5317 result.at(i)=='!' ||
5318 result.at(i)=='?' ||
5319 result.at(i)=='}') // good for UTF-16 characters and } otherwise also a good point to stop the string
5320 {
5321 i++; // we want to be "behind" last inspected character
5322 break;
5323 }
5324 }
5325 }
5326 if ( i < l) result=result.left(i)+"...";
5327 return result.data();
5328}
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:5235

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

5615{
5616 std::string elem;
5617 auto getter = [](std::string s) -> QCString { return s; };
5618 return genericPatternMatch(fi,patList,elem,getter);
5619}

References genericPatternMatch().

Referenced by checkAndOpenFile(), and readDir().

◆ projectLogoFile()

QCString projectLogoFile ( )

Definition at line 3070 of file util.cpp.

3071{
3072 QCString projectLogo = Config_getString(PROJECT_LOGO);
3073 if (!projectLogo.isEmpty())
3074 {
3075 // check for optional width= and height= specifier
3076 int wi = projectLogo.find(" width=");
3077 if (wi!=-1) // and strip them
3078 {
3079 projectLogo = projectLogo.left(wi);
3080 }
3081 int hi = projectLogo.find(" height=");
3082 if (hi!=-1)
3083 {
3084 projectLogo = projectLogo.left(hi);
3085 }
3086 }
3087 //printf("projectlogo='%s'\n",qPrint(projectLogo));
3088 return projectLogo;
3089}

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

Referenced by copyLogo(), and substituteKeywords().

◆ projectLogoSize()

QCString projectLogoSize ( )
static

Definition at line 3091 of file util.cpp.

3092{
3093 QCString sizeVal;
3094 QCString projectLogo = Config_getString(PROJECT_LOGO);
3095 if (!projectLogo.isEmpty())
3096 {
3097 auto extractDimension = [&projectLogo](const char *startMarker,size_t startPos,size_t endPos) -> QCString
3098 {
3099 QCString result = projectLogo.mid(startPos,endPos-startPos).stripWhiteSpace().quoted();
3100 if (result.length()>=2 && result.at(0)!='"' && result.at(result.length()-1)!='"')
3101 {
3102 result="\""+result+"\"";
3103 }
3104 result.prepend(startMarker);
3105 return result;
3106 };
3107 // check for optional width= and height= specifier
3108 int wi = projectLogo.find(" width=");
3109 int hi = projectLogo.find(" height=");
3110 if (wi!=-1 && hi!=-1)
3111 {
3112 if (wi<hi) // "... width=x height=y..."
3113 {
3114 sizeVal = extractDimension(" width=", wi+7, hi) + " "
3115 + extractDimension(" height=", hi+8, projectLogo.length());
3116 }
3117 else // "... height=y width=x..."
3118 {
3119 sizeVal = extractDimension(" height=", hi+8, wi) + " "
3120 + extractDimension(" width=", wi+7, projectLogo.length());
3121 }
3122 }
3123 else if (wi!=-1) // ... width=x..."
3124 {
3125 sizeVal = extractDimension(" width=", wi+7, projectLogo.length());
3126 }
3127 else if (hi!=-1) // ... height=x..."
3128 {
3129 sizeVal = extractDimension(" height=", hi+8, projectLogo.length());
3130 }
3131 }
3132 //printf("projectsize='%s'\n",qPrint(sizeVal));
3133 return sizeVal;
3134}
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 5863 of file util.cpp.

5864{
5865 bool extractPrivate = Config_getBool(EXTRACT_PRIVATE);
5866 bool extractPackage = Config_getBool(EXTRACT_PACKAGE);
5867
5868 return (prot!=Protection::Private && prot!=Protection::Package) ||
5869 (prot==Protection::Private && extractPrivate) ||
5870 (prot==Protection::Package && extractPackage);
5871}

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

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

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

6268{
6269 int column=0;
6270 bool skipLine=FALSE;
6271
6272 if (format == FortranFormat::Fixed) return TRUE;
6273 if (format == FortranFormat::Free) return FALSE;
6274
6275 int tabSize=Config_getInt(TAB_SIZE);
6276 size_t sizCont = contents.length();
6277 for (size_t i=0;i<sizCont;i++)
6278 {
6279 column++;
6280
6281 switch(contents.at(i))
6282 {
6283 case '\n':
6284 column=0;
6285 skipLine=FALSE;
6286 break;
6287 case '\t':
6288 column += tabSize-1;
6289 break;
6290 case ' ':
6291 break;
6292 case '\000':
6293 return FALSE;
6294 case '#':
6295 skipLine=TRUE;
6296 break;
6297 case 'C':
6298 case 'c':
6299 if (column==1)
6300 {
6301 return !keyWordsFortranC(contents.data()+i);
6302 }
6303 // fallthrough
6304 case '*':
6305 if (column==1) return TRUE;
6306 if (skipLine) break;
6307 return FALSE;
6308 case '!':
6309 if (column!=6) skipLine=TRUE;
6310 break;
6311 default:
6312 if (skipLine) break;
6313 if (column>=7) return TRUE;
6314 return FALSE;
6315 }
6316 }
6317 return FALSE;
6318}
static bool keyWordsFortranC(const char *contents)
Definition util.cpp:6247

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

4789{
4790 ModuleDef *mod = root ? findModuleDef(d) : nullptr;
4791 if (!d->partOfGroups().empty() || mod!=nullptr) // write list of group to which this definition belongs
4792 {
4793 if (root)
4794 {
4795 ol.pushGeneratorState();
4797 ol.writeString("<div class=\"ingroups\">");
4798 }
4799 bool first=true;
4800 for (const auto &gd : d->partOfGroups())
4801 {
4802 if (!first) { ol.writeString(" &#124; "); } else first=false;
4804 {
4805 ol.writeString(" &raquo; ");
4806 }
4807 ol.writeObjectLink(gd->getReference(),gd->getOutputFileBase(),QCString(),gd->groupTitle());
4808 }
4809 if (root)
4810 {
4811 // add module as a group to the file as well
4812 if (mod)
4813 {
4814 if (!first) { ol.writeString(" &#124; "); } else first=false;
4815 ol.writeString(theTranslator->trModule(false,true)+" ");
4817 mod->displayName());
4818 }
4819 ol.writeString("</div>");
4820 ol.popGeneratorState();
4821 }
4822 return true;
4823 }
4824 return false;
4825}
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:4759

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

3504{
3505 QCString result;
3506 if (Config_getBool(CREATE_SUBDIRS))
3507 {
3508 if (name.isEmpty())
3509 {
3510 return REL_PATH_TO_ROOT;
3511 }
3512 else
3513 {
3514 int i = name.findRev('/');
3515 if (i!=-1)
3516 {
3517 result=REL_PATH_TO_ROOT;
3518 }
3519 }
3520 }
3521 return result;
3522}
#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 6510 of file util.cpp.

6511{
6512 std::string out;
6513 out.reserve(s.length());
6514 const char *p=s.data();
6515 if (p)
6516 {
6517 char c = 0;
6518 while ((c=*p++))
6519 {
6520 if (c=='\n')
6521 {
6522 const char *e = p;
6523 while (*e==' ' || *e=='\t') e++;
6524 if (*e=='\n')
6525 {
6526 p=e;
6527 }
6528 else out+=c;
6529 }
6530 else
6531 {
6532 out+=c;
6533 }
6534 }
6535 }
6536 //printf("removeEmptyLines(%s)=%s\n",qPrint(s),qPrint(out));
6537 return out;
6538}

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

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

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

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

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

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

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

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

3058{
3059 // get the current date and time
3060 std::tm dat{};
3061 int specFormat=0;
3062 QCString specDate = "";
3063 QCString err = dateTimeFromString(specDate,dat,specFormat);
3064
3065 // do the conversion
3066 int usedFormat=0;
3067 return formatDateTime(fmt,dat,usedFormat);
3068}
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 2954 of file util.cpp.

2955{
2956 QCString result;
2957 QCString name=n;
2958 QCString path;
2959 int slashPos=std::max(name.findRev('/'),name.findRev('\\'));
2960 if (slashPos!=-1)
2961 {
2962 path=name.left(slashPos+1);
2963 name=name.right(name.length()-slashPos-1);
2964 }
2965 const FileName *fn=fnMap->find(name);
2966 if (fn)
2967 {
2968 bool first = true;
2969 for (const auto &fd : *fn)
2970 {
2971 if (path.isEmpty() || fd->getPath().right(path.length())==path)
2972 {
2973 if (!first) result += "\n";
2974 else first = false;
2975 result+=" "+fd->absFilePath();
2976 }
2977 }
2978 }
2979 return result;
2980}

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

6560{
6561 StringVector result;
6562 reg::Iterator iter(s, delimiter);
6564 size_t p=0;
6565 for ( ; iter != end; ++iter)
6566 {
6567 const auto &match = *iter;
6568 size_t i=match.position();
6569 size_t l=match.length();
6570 if (i>p) result.push_back(s.substr(p,i-p));
6571 p=i+l;
6572 }
6573 if (p<s.length()) result.push_back(s.substr(p));
6574 return result;
6575}

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

6543{
6544 StringVector result;
6545 size_t prev = 0, pos = 0, len = s.length();
6546 do
6547 {
6548 pos = s.find(delimiter, prev);
6549 if (pos == std::string::npos) pos = len;
6550 if (pos>prev) result.push_back(s.substr(prev,pos-prev));
6551 prev = pos + delimiter.length();
6552 }
6553 while (pos<len && prev<len);
6554 return result;
6555}

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

5397{
5398#ifdef TRACINGSUPPORT
5399 void *backtraceFrames[128];
5400 int frameCount = backtrace(backtraceFrames, 128);
5401 const size_t cmdLen = 40960;
5402 static char cmd[cmdLen];
5403 char *p = cmd;
5404 p += qsnprintf(p,cmdLen,"/usr/bin/atos -p %d ", (int)getpid());
5405 for (int x = 0; x < frameCount; x++)
5406 {
5407 p += qsnprintf(p,cmdLen,"%p ", backtraceFrames[x]);
5408 }
5409 fprintf(stderr,"========== STACKTRACE START ==============\n");
5410 if (FILE *fp = Portable::popen(cmd, "r"))
5411 {
5412 char resBuf[512];
5413 while (size_t len = fread(resBuf, 1, sizeof(resBuf), fp))
5414 {
5415 fwrite(resBuf, 1, len, stderr);
5416 }
5417 Portable::pclose(fp);
5418 }
5419 fprintf(stderr,"============ STACKTRACE END ==============\n");
5420 //fprintf(stderr,"%s\n", frameStrings[x]);
5421#endif
5422}

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

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

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

Referenced by getCanonicalTypeForIdentifier().

◆ stripExtension()

QCString stripExtension ( const QCString & fName)

Definition at line 4859 of file util.cpp.

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

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

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

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

5964{
5965 //printf("stripIndentationVerbatim(level=%d):\n%s\n------\n",indentationLevel,qPrint(doc));
5966 if (indentationLevel <= 0 || doc.isEmpty()) return; // nothing to strip
5967
5968 // by stripping content the string will only become shorter so we write the results
5969 // back into the input string and then resize it at the end.
5970 char c = 0;
5971 const char *src = doc.data();
5972 char *dst = doc.rawData();
5973 bool insideIndent = false; // skip the initial line from stripping
5974 int cnt = 0;
5975 while ((c=*src++))
5976 {
5977 // invariant: dst<=src
5978 switch(c)
5979 {
5980 case '\n':
5981 *dst++ = c;
5982 insideIndent = true;
5983 cnt = indentationLevel;
5984 break;
5985 case ' ':
5986 if (insideIndent)
5987 {
5988 if (cnt>0) // count down the spacing until the end of the indent
5989 {
5990 cnt--;
5991 }
5992 else // reached the end of the indent, start of the part of the line to keep
5993 {
5994 insideIndent = false;
5995 *dst++ = c;
5996 }
5997 }
5998 else // part after indent, copy to the output
5999 {
6000 *dst++ = c;
6001 }
6002 break;
6003 default:
6004 insideIndent = false;
6005 *dst++ = c;
6006 break;
6007 }
6008 }
6009 doc.resize(static_cast<uint32_t>(dst-doc.data()));
6010 //printf("stripIndentationVerbatim: result=\n%s\n------\n",qPrint(doc));
6011}
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 1551 of file util.cpp.

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

References stripIrrelevantString().

Referenced by extractCanonicalType(), and matchArgument2().

◆ stripIrrelevantString()

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

Definition at line 1491 of file util.cpp.

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

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

4941{
4942 if (s.isEmpty()) return QCString();
4943 const char *p = s.data();
4944
4945 // search for leading empty lines
4946 int i=0,li=-1,l=static_cast<int>(s.length());
4947 char c = 0;
4948 while ((c=*p))
4949 {
4950 if (c==' ' || c=='\t' || c=='\r') i++,p++;
4951 else if (c=='\\' && literal_at(p,"\\ilinebr")) i+=8,li=i,p+=8;
4952 else if (c=='\n') i++,li=i,docLine++,p++;
4953 else break;
4954 }
4955
4956 // search for trailing empty lines
4957 int b=l-1,bi=-1;
4958 p=s.data()+b;
4959 while (b>=0)
4960 {
4961 c=*p;
4962 if (c==' ' || c=='\t' || c=='\r') b--,p--;
4963 else if (c=='r' && b>=7 && literal_at(p-7,"\\ilinebr")) bi=b-7,b-=8,p-=8;
4964 else if (c=='>' && b>=11 && literal_at(p-11,"\\ilinebr<br>")) bi=b-11,b-=12,p-=12;
4965 else if (c=='\n') bi=b,b--,p--;
4966 else break;
4967 }
4968
4969 // return whole string if no leading or trailing lines where found
4970 if (li==-1 && bi==-1) return s;
4971
4972 // return substring
4973 if (bi==-1) bi=l;
4974 if (li==-1) li=0;
4975 if (bi<=li) return QCString(); // only empty lines
4976 //printf("docLine='%s' len=%d li=%d bi=%d\n",qPrint(s),s.length(),li,bi);
4977 return s.mid(li,bi-li);
4978}

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

4865{
4866 QCString result=s;
4867 int i=result.findRev('/');
4868 if (i!=-1)
4869 {
4870 result=result.mid(i+1);
4871 }
4872 i=result.findRev('\\');
4873 if (i!=-1)
4874 {
4875 result=result.mid(i+1);
4876 }
4877 return result;
4878}

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

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

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

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

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

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

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

3138{
3139 return substituteKeywords(file,s,
3140 {
3141 // keyword value getter
3142 { "$title", [&]() { return !title.isEmpty() ? title : projName; } },
3143 { "$doxygenversion", [&]() { return getDoxygenVersion(); } },
3144 { "$projectname", [&]() { return projName; } },
3145 { "$projectnumber", [&]() { return projNum; } },
3146 { "$projectbrief", [&]() { return projBrief; } },
3147 { "$projectlogo", [&]() { return stripPath(projectLogoFile()); } },
3148 { "$logosize", [&]() { return projectLogoSize(); } },
3149 { "$projecticon", [&]() { return stripPath(Config_getString(PROJECT_ICON)); } },
3150 { "$langISO", [&]() { return theTranslator->trISOLang(); } },
3151 { "$showdate", [&](const QCString &fmt) { return showDate(fmt); } }
3152 });
3153}
QCString stripPath(const QCString &s)
Definition util.cpp:4864
QCString substituteKeywords(const QCString &file, const QCString &s, const KeywordSubstitutionList &keywords)
Definition util.cpp:2984
QCString projectLogoFile()
Definition util.cpp:3070
static QCString projectLogoSize()
Definition util.cpp:3091
static QCString showDate(const QCString &fmt)
Definition util.cpp:3057

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

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

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

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

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

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

1395{
1396 const char *outputEncoding = "UTF-8";
1397 if (inputEncoding==nullptr || qstricmp(inputEncoding,outputEncoding)==0) return true;
1398 size_t inputSize=input.length();
1399 size_t outputSize=inputSize*4;
1400 QCString output(outputSize, QCString::ExplicitSize);
1401 void *cd = portable_iconv_open(outputEncoding,inputEncoding);
1402 if (cd==reinterpret_cast<void *>(-1))
1403 {
1404 return false;
1405 }
1406 bool ok=true;
1407 size_t iLeft=inputSize;
1408 size_t oLeft=outputSize;
1409 const char *inputPtr = input.data();
1410 char *outputPtr = output.rawData();
1411 if (!portable_iconv(cd, &inputPtr, &iLeft, &outputPtr, &oLeft))
1412 {
1413 outputSize-=static_cast<int>(oLeft);
1414 output.resize(outputSize);
1415 output.at(outputSize)='\0';
1416 // replace input
1417 input=output.str();
1418 //printf("iconv: input size=%d output size=%d\n[%s]\n",size,newSize,qPrint(srcBuf));
1419 }
1420 else
1421 {
1422 ok=false;
1423 }
1425 return ok;
1426}
@ 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 1469 of file util.cpp.

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

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

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

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

◆ updateColumnCount()

size_t updateColumnCount ( const char * s,
size_t col )

Definition at line 6804 of file util.cpp.

6805{
6806 if (s)
6807 {
6808 const int tabSize = Config_getInt(TAB_SIZE);
6809 char c;
6810 while ((c=*s++))
6811 {
6812 switch(c)
6813 {
6814 case '\t': col+=tabSize - (col%tabSize);
6815 break;
6816 case '\n': col=0;
6817 break;
6818 default:
6819 col++;
6820 if (c<0) // multi-byte character
6821 {
6822 int numBytes = getUTF8CharNumBytes(c);
6823 for (int i=0;i<numBytes-1 && (c=*s++);i++) {} // skip over extra chars
6824 if (c==0) return col; // end of string half way a multibyte char
6825 }
6826 break;
6827 }
6828 }
6829 }
6830 return col;
6831}

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

5017{
5018 QCString langName = language.lower();
5019 auto it1 = std::find_if(g_lang2extMap.begin(),g_lang2extMap.end(),
5020 [&langName](const auto &info) { return info.langName==langName; });
5021 if (it1 == g_lang2extMap.end()) return false;
5022
5023 // found the language
5024 SrcLangExt parserId = it1->parserId;
5025 QCString extName = extension.lower();
5026 if (extName.isEmpty()) return FALSE;
5027 if (extName.at(0)!='.') extName.prepend(".");
5028 auto it2 = g_extLookup.find(extName.str());
5029 if (it2!=g_extLookup.end())
5030 {
5031 g_extLookup.erase(it2); // language was already register for this ext
5032 }
5033 //printf("registering extension %s\n",qPrint(extName));
5034 g_extLookup.emplace(extName.str(),parserId);
5035 if (!Doxygen::parserManager->registerExtension(extName,it1->parserName))
5036 {
5037 err("Failed to assign extension {} to parser {} for language {}\n",
5038 extName.data(),it1->parserName,language);
5039 }
5040 else
5041 {
5042 //msg("Registered extension {} to language parser {}...\n",
5043 // extName,language);
5044 }
5045 return TRUE;
5046}
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 5708 of file util.cpp.

5709{
5710 int hue = Config_getInt(HTML_COLORSTYLE_HUE);
5711 int sat = Config_getInt(HTML_COLORSTYLE_SAT);
5712 int gamma = Config_getInt(HTML_COLORSTYLE_GAMMA);
5713 while (data->name)
5714 {
5715 QCString fileName = dir+"/"+data->name;
5716 ColoredImage img(data->width,data->height,data->content,data->alpha,
5717 sat,hue,gamma);
5718 if (!img.save(fileName))
5719 {
5720 fprintf(stderr,"Warning: Cannot open file %s for writing\n",data->name);
5721 }
5722 Doxygen::indexList->addImageFile(data->name);
5723 data++;
5724 }
5725}
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 1118 of file util.cpp.

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

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

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

5370{
5371 if (al.empty()) return;
5372 ol.startConstraintList(theTranslator->trTypeConstraints());
5373 for (const Argument &a : al)
5374 {
5376 ol.parseText(a.name);
5377 ol.endConstraintParam();
5379 linkifyText(TextGeneratorOLImpl(ol),d,nullptr,nullptr,a.type);
5380 ol.endConstraintType();
5382 ol.generateDoc(d->docFile(),
5383 d->docLine(),
5384 d,
5385 nullptr,
5386 a.docs,
5387 DocOptions()
5388 .setIndexWords(true));
5389 ol.endConstraintDocs();
5390 }
5391 ol.endConstraintList();
5392}
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 5333 of file util.cpp.

Referenced by parseCommentAsHtml().

◆ g_docCacheMutex

std::mutex g_docCacheMutex
static

Definition at line 5332 of file util.cpp.

Referenced by parseCommentAsHtml().

◆ g_extLookup

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

Definition at line 4982 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 2824 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 4992 of file util.cpp.

4993{
4994// language parser parser option
4995 { "idl", "c", SrcLangExt::IDL, ".idl" },
4996 { "java", "c", SrcLangExt::Java, ".java"},
4997 { "javascript", "c", SrcLangExt::JS, ".js" },
4998 { "csharp", "c", SrcLangExt::CSharp, ".cs" },
4999 { "d", "c", SrcLangExt::D, ".d" },
5000 { "php", "c", SrcLangExt::PHP, ".php" },
5001 { "objective-c", "c", SrcLangExt::ObjC, ".m" },
5002 { "c", "c", SrcLangExt::Cpp, ".c" },
5003 { "c++", "c", SrcLangExt::Cpp, ".cpp" },
5004 { "slice", "c", SrcLangExt::Slice, ".ice" },
5005 { "python", "python", SrcLangExt::Python, ".py" },
5006 { "fortran", "fortran", SrcLangExt::Fortran, ".f" },
5007 { "fortranfree", "fortranfree", SrcLangExt::Fortran, ".f90" },
5008 { "fortranfixed", "fortranfixed", SrcLangExt::Fortran, ".f" },
5009 { "vhdl", "vhdl", SrcLangExt::VHDL, ".vhdl"},
5010 { "xml", "xml", SrcLangExt::XML, ".xml" },
5011 { "sql", "sql", SrcLangExt::SQL, ".sql" },
5012 { "md", "md", SrcLangExt::Markdown, ".md" },
5013 { "lex", "lex", SrcLangExt::Lex, ".l" },
5014};

Referenced by getLanguageFromCodeLang(), and updateLanguageMapping().

◆ g_matchArgsMutex

std::mutex g_matchArgsMutex
static

Definition at line 1851 of file util.cpp.

Referenced by matchArgument2().

◆ g_usedNames

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

Definition at line 3418 of file util.cpp.

Referenced by convertNameToFile().

◆ g_usedNamesCount

int g_usedNamesCount =1
static

Definition at line 3420 of file util.cpp.

Referenced by convertNameToFile().

◆ g_usedNamesMutex

std::mutex g_usedNamesMutex
static

Definition at line 3419 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().