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

Go to the source code of this file.

Classes

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

Macros

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

Functions

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

Variables

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

Macro Definition Documentation

◆ ENABLE_TRACINGSUPPORT

#define ENABLE_TRACINGSUPPORT   0

Definition at line 81 of file util.cpp.

◆ HEXTONUM

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

Referenced by replaceColorMarkers().

◆ MATCH

#define MATCH

Definition at line 1826 of file util.cpp.

Referenced by matchArgument2(), and matchArguments2().

◆ NOMATCH

#define NOMATCH

Definition at line 1827 of file util.cpp.

Referenced by matchArgument2(), and matchArguments2().

◆ REL_PATH_TO_ROOT

#define REL_PATH_TO_ROOT   "../../"

Definition at line 95 of file util.cpp.

Referenced by relativePathToRoot().

Function Documentation

◆ addCodeOnlyMappings()

void addCodeOnlyMappings ( )

Definition at line 5639 of file util.cpp.

5640{
5641 updateLanguageMapping(".xml", "xml");
5642 updateLanguageMapping(".sql", "sql");
5643}
bool updateLanguageMapping(const QCString &extension, const QCString &language)
Definition util.cpp:5540

References updateLanguageMapping().

Referenced by generateOutput().

◆ addGroupListToTitle()

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

◆ addHtmlExtensionIfMissing()

void addHtmlExtensionIfMissing ( QCString & fName)

Definition at line 5339 of file util.cpp.

5340{
5341 if (fName.isEmpty()) return;
5342 int i_fs = fName.findRev('/');
5343 int i_bs = fName.findRev('\\');
5344 int i = fName.find('.',std::max({ i_fs, i_bs ,0})); // search for . after path part
5345 if (i==-1)
5346 {
5348 }
5349}
static QCString htmlFileExtension
Definition doxygen.h:122
int find(char c, int index=0, bool cs=TRUE) const
Definition qcstring.cpp:43
bool isEmpty() const
Returns TRUE iff the string is empty.
Definition qcstring.h:150
int findRev(char c, int index=-1, bool cs=TRUE) const
Definition qcstring.cpp:91

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

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

◆ addMembersToMemberGroup()

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

Definition at line 4534 of file util.cpp.

4537{
4538 ASSERT(context!=nullptr);
4539 //printf("addMemberToMemberGroup() context=%s\n",qPrint(context->name()));
4540 if (ml==nullptr) return;
4541
4542 struct MoveMemberInfo
4543 {
4544 MoveMemberInfo(MemberDef *md,MemberGroup *mg,const RefItemVector &rv)
4545 : memberDef(md), memberGroup(mg), sli(rv) {}
4546 MemberDef *memberDef;
4547 MemberGroup *memberGroup;
4548 RefItemVector sli;
4549 };
4550 std::vector<MoveMemberInfo> movedMembers;
4551
4552 for (const auto &md : *ml)
4553 {
4554 if (md->isEnumerate()) // insert enum value of this enum into groups
4555 {
4556 for (const auto &fmd : md->enumFieldList())
4557 {
4558 int groupId=fmd->getMemberGroupId();
4559 if (groupId!=-1)
4560 {
4561 auto it = Doxygen::memberGroupInfoMap.find(groupId);
4563 {
4564 const auto &info = it->second;
4565 auto mg_it = std::find_if(pMemberGroups->begin(),
4566 pMemberGroups->end(),
4567 [&groupId](const auto &g)
4568 { return g->groupId()==groupId; }
4569 );
4570 MemberGroup *mg_ptr = nullptr;
4571 if (mg_it==pMemberGroups->end())
4572 {
4573 auto mg = std::make_unique<MemberGroup>(
4574 context,
4575 groupId,
4576 info->header,
4577 info->doc,
4578 info->docFile,
4579 info->docLine,
4580 ml->container());
4581 mg_ptr = mg.get();
4582 pMemberGroups->push_back(std::move(mg));
4583 }
4584 else
4585 {
4586 mg_ptr = (*mg_it).get();
4587 }
4588 mg_ptr->insertMember(fmd); // insert in member group
4590 if (fmdm)
4591 {
4592 fmdm->setMemberGroup(mg_ptr);
4593 }
4594 }
4595 }
4596 }
4597 }
4598 int groupId=md->getMemberGroupId();
4599 if (groupId!=-1)
4600 {
4601 auto it = Doxygen::memberGroupInfoMap.find(groupId);
4603 {
4604 const auto &info = it->second;
4605 auto mg_it = std::find_if(pMemberGroups->begin(),
4606 pMemberGroups->end(),
4607 [&groupId](const auto &g)
4608 { return g->groupId()==groupId; }
4609 );
4610 MemberGroup *mg_ptr = nullptr;
4611 if (mg_it==pMemberGroups->end())
4612 {
4613 auto mg = std::make_unique<MemberGroup>(
4614 context,
4615 groupId,
4616 info->header,
4617 info->doc,
4618 info->docFile,
4619 info->docLine,
4620 ml->container());
4621 mg_ptr = mg.get();
4622 pMemberGroups->push_back(std::move(mg));
4623 }
4624 else
4625 {
4626 mg_ptr = (*mg_it).get();
4627 }
4628 movedMembers.emplace_back(md,mg_ptr,info->m_sli);
4629 }
4630 }
4631 }
4632
4633 // move the members to their group
4634 for (const auto &mmi : movedMembers)
4635 {
4636 ml->remove(mmi.memberDef); // remove from member list
4637 mmi.memberGroup->insertMember(mmi.memberDef->resolveAlias()); // insert in member group
4638 mmi.memberGroup->setRefItems(mmi.sli);
4639 MemberDefMutable *rmdm = toMemberDefMutable(mmi.memberDef);
4640 if (rmdm)
4641 {
4642 rmdm->setMemberGroup(mmi.memberGroup);
4643 }
4644 }
4645}
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 5242 of file util.cpp.

5245{
5246 //printf("addRefItem(sli=%d,key=%s,prefix=%s,name=%s,title=%s,args=%s)\n",(int)sli.size(),key,prefix,name,title,args);
5247 if (!key.isEmpty() && key[0]!='@') // check for @ to skip anonymous stuff (see bug427012)
5248 {
5249 for (RefItem *item : sli)
5250 {
5251 item->setPrefix(prefix);
5252 item->setScope(scope);
5253 item->setName(name);
5254 item->setTitle(title);
5255 item->setArgs(args);
5256 item->setGroup(key);
5257 }
5258 }
5259}
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 5112 of file util.cpp.

5123{
5124 PageDef *pd=nullptr;
5125 //printf("addRelatedPage(name=%s gd=%p)\n",qPrint(name),gd);
5126 QCString title=ptitle.stripWhiteSpace();
5127 bool newPage = true;
5128 if ((pd=Doxygen::pageLinkedMap->find(name)) && !pd->isReference())
5129 {
5130 if (!xref && !title.isEmpty() && pd->title()!=pd->name() && pd->title()!=title)
5131 {
5132 warn(fileName,startLine,"multiple use of page label '{}' with different titles, (other occurrence: {}, line: {})",
5133 name,pd->docFile(),pd->getStartBodyLine());
5134 }
5135 if (!title.isEmpty() && pd->title()==pd->name()) // pd has no real title yet
5136 {
5137 pd->setTitle(title);
5139 if (si)
5140 {
5141 si->setTitle(title);
5142 }
5143 }
5144 // append documentation block to the page.
5145 pd->setDocumentation(doc,fileName,docLine);
5146 //printf("Adding page docs '%s' pi=%p name=%s\n",qPrint(doc),pd,name);
5147 // append (x)refitems to the page.
5148 pd->setRefItems(sli);
5149 newPage = false;
5150 }
5151
5152 if (newPage) // new page
5153 {
5154 QCString baseName=name;
5155 if (baseName.endsWith(".tex"))
5156 baseName=baseName.left(baseName.length()-4);
5157 else if (baseName.right(Doxygen::htmlFileExtension.length())==Doxygen::htmlFileExtension)
5158 baseName=baseName.left(baseName.length()-Doxygen::htmlFileExtension.length());
5159
5160 //printf("Appending page '%s'\n",qPrint(baseName));
5161 if (pd) // replace existing page
5162 {
5163 pd->setDocumentation(doc,fileName,docLine);
5165 pd->setShowLineNo(FALSE);
5166 pd->setNestingLevel(0);
5167 pd->setPageScope(nullptr);
5168 pd->setTitle(title);
5169 pd->setReference(QCString());
5170 }
5171 else // newPage
5172 {
5173 pd = Doxygen::pageLinkedMap->add(baseName,
5174 createPageDef(fileName,docLine,baseName,doc,title));
5175 }
5176 pd->setBodySegment(startLine,startLine,-1);
5177
5178 pd->setRefItems(sli);
5179 pd->setLanguage(lang);
5180
5181 if (tagInfo)
5182 {
5183 pd->setReference(tagInfo->tagName);
5184 pd->setFileName(tagInfo->fileName);
5185 }
5186
5187 if (gd) gd->addPage(pd);
5188
5189 if (pd->hasTitle())
5190 {
5191 //outputList->writeTitle(pi->name,pi->title);
5192
5193 // a page name is a label as well!
5194 QCString file;
5195 QCString orgFile;
5196 int line = -1;
5197 if (gd)
5198 {
5199 file=gd->getOutputFileBase();
5200 orgFile=gd->getOutputFileBase();
5201 }
5202 else
5203 {
5204 file=pd->getOutputFileBase();
5205 orgFile=pd->docFile();
5206 line = pd->getStartBodyLine();
5207 }
5208 const SectionInfo *si = SectionManager::instance().find(pd->name());
5209 if (si)
5210 {
5211 if (!si->ref().isEmpty()) // we are from a tag file
5212 {
5214 file,-1,pd->title(),SectionType::Page,0,pd->getReference());
5215 }
5216 else if (si->lineNr() != -1)
5217 {
5218 warn(orgFile,line,"multiple use of section label '{}', (first occurrence: {}, line {})",pd->name(),si->fileName(),si->lineNr());
5219 }
5220 else
5221 {
5222 warn(orgFile,line,"multiple use of section label '{}', (first occurrence: {})",pd->name(),si->fileName());
5223 }
5224 }
5225 else
5226 {
5228 file,-1,pd->title(),SectionType::Page,0,pd->getReference());
5229 //printf("si->label='%s' si->definition=%s si->fileName='%s'\n",
5230 // qPrint(si->label),si->definition?si->definition->name().data():"<none>",
5231 // qPrint(si->fileName));
5232 //printf(" SectionInfo: sec=%p sec->fileName=%s\n",si,qPrint(si->fileName));
5233 //printf("Adding section key=%s si->fileName=%s\n",qPrint(pageName),qPrint(si->fileName));
5234 }
5235 }
5236 }
5237 return pd;
5238}
virtual QCString docFile() const =0
virtual QCString getReference() const =0
virtual QCString getOutputFileBase() const =0
virtual int getStartBodyLine() const =0
virtual bool isReference() const =0
virtual const QCString & name() const =0
virtual void setBodySegment(int defLine, int bls, int ble)=0
virtual void setDocumentation(const QCString &d, const QCString &docFile, int docLine, bool stripWhiteSpace=TRUE)=0
virtual void setLanguage(SrcLangExt lang)=0
virtual void setReference(const QCString &r)=0
virtual void setRefItems(const RefItemVector &sli)=0
static PageLinkedMap * pageLinkedMap
Definition doxygen.h:100
virtual void addPage(PageDef *def)=0
const T * find(const std::string &key) const
Definition linkedmap.h:47
A model of a page symbol.
Definition pagedef.h:26
virtual void setTitle(const QCString &title)=0
virtual void setNestingLevel(int)=0
virtual bool hasTitle() const =0
virtual void setFileName(const QCString &name)=0
virtual void setShowLineNo(bool)=0
virtual QCString title() const =0
virtual void setPageScope(Definition *)=0
This is an alternative implementation of QCString.
Definition qcstring.h:101
size_t length() const
Returns the length of the string, not counting the 0-terminator.
Definition qcstring.h:153
bool endsWith(const char *s) const
Definition qcstring.h:509
QCString stripWhiteSpace() const
returns a copy of this string with leading and trailing whitespace removed
Definition qcstring.h:245
QCString right(size_t len) const
Definition qcstring.h:219
QCString left(size_t len) const
Definition qcstring.h:214
class that provide information about a section.
Definition section.h:57
QCString ref() const
Definition section.h:71
QCString fileName() const
Definition section.h:73
int lineNr() const
Definition section.h:72
void setTitle(const QCString &t)
Definition section.h:83
SectionInfo * replace(const QCString &label, const QCString &fileName, int lineNr, const QCString &title, SectionType type, int level, const QCString &ref=QCString())
Definition section.h:154
SectionInfo * add(const SectionInfo &si)
Definition section.h:138
static SectionManager & instance()
returns a reference to the singleton
Definition section.h:175
static constexpr int Page
Definition section.h:31
#define warn(file, line, fmt,...)
Definition message.h:97
std::unique_ptr< PageDef > createPageDef(const QCString &f, int l, const QCString &n, const QCString &d, const QCString &t)
Definition pagedef.cpp:79
#define FALSE
Definition qcstring.h:34
QCString fileName
Definition entry.h:105
QCString tagName
Definition entry.h:104
QCString convertNameToFile(const QCString &name, bool allowDots, bool allowUnderscore)
Definition util.cpp:3944

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

1175{
1176 QCString result;
1177 if (!al.hasParameters()) return result;
1178 result+="(";
1179 for (auto it = al.begin() ; it!=al.end() ;)
1180 {
1181 Argument a = *it;
1182 QCString type1 = useCanonicalType && !a.canType.isEmpty() ? a.canType : a.type;
1183 QCString type2;
1184 int i=type1.find(")("); // hack to deal with function pointers
1185 if (i!=-1)
1186 {
1187 type2=type1.mid(i);
1188 type1=type1.left(i);
1189 }
1190 if (!a.attrib.isEmpty())
1191 {
1192 result+=a.attrib+" ";
1193 }
1194 if (!a.name.isEmpty() || !a.array.isEmpty())
1195 {
1196 result+= type1+" "+a.name+type2+a.array;
1197 }
1198 else
1199 {
1200 result+= type1+type2;
1201 }
1202 if (!a.defval.isEmpty() && showDefVals)
1203 {
1204 result+="="+a.defval;
1205 }
1206 ++it;
1207 if (it!=al.end()) result+=", ";
1208 }
1209 result+=")";
1210 if (al.constSpecifier()) result+=" const";
1211 if (al.volatileSpecifier()) result+=" volatile";
1212 if (al.refQualifier()==RefQualifierType::LValue) result+=" &";
1213 else if (al.refQualifier()==RefQualifierType::RValue) result+=" &&";
1214 if (!al.trailingReturnType().isEmpty()) result+=al.trailingReturnType();
1215 if (al.pureSpecifier()) result+=" =0";
1216 return removeRedundantWhiteSpace(result);
1217}
RefQualifierType refQualifier() const
Definition arguments.h:109
bool pureSpecifier() const
Definition arguments.h:106
iterator end()
Definition arguments.h:87
bool hasParameters() const
Definition arguments.h:69
QCString trailingReturnType() const
Definition arguments.h:107
bool constSpecifier() const
Definition arguments.h:104
iterator begin()
Definition arguments.h:86
bool volatileSpecifier() const
Definition arguments.h:105
QCString mid(size_t index, size_t len=static_cast< size_t >(-1)) const
Definition qcstring.h:226
This class contains the information about the argument of a function or template.
Definition arguments.h:27
QCString type
Definition arguments.h:37
QCString name
Definition arguments.h:39
QCString defval
Definition arguments.h:41
QCString array
Definition arguments.h:40
QCString canType
Definition arguments.h:38
QCString attrib
Definition arguments.h:36
QCString removeRedundantWhiteSpace(const QCString &s)
Definition util.cpp:578

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

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

◆ checkBlocks()

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

Definition at line 6946 of file util.cpp.

6947{
6948 if (s.isEmpty()) return;
6949
6950 const char *p = s.data();
6951 char c = 0;
6952 while ((c=*p))
6953 {
6954 if (c==markerInfo.markerChar) // potential start of marker
6955 {
6956 if (qstrncmp(p,markerInfo.beginStr,markerInfo.beginLen)==0) // start of begin marker
6957 {
6958 size_t len = markerInfo.beginLen;
6959 bool negate = *(p+len)=='!';
6960 if (negate) len++;
6961 p += len;
6962 QCString marker;
6963 while (*p)
6964 {
6965 if (markerInfo.closeLen==0 && *p=='\n') // matching end of line
6966 {
6967 warn(fileName,-1,"Remaining begin replacement with marker '{}'",marker);
6968 break;
6969 }
6970 else if (markerInfo.closeLen!= 0 && qstrncmp(p,markerInfo.closeStr,markerInfo.closeLen)==0) // matching marker closing
6971 {
6972 p += markerInfo.closeLen;
6973 warn(fileName,-1,"Remaining begin replacement with marker '{}'",marker);
6974 break;
6975 }
6976 marker += *p;
6977 p++;
6978 }
6979 }
6980 else if (qstrncmp(p,markerInfo.endStr,markerInfo.endLen)==0) // start of end marker
6981 {
6982 size_t len = markerInfo.endLen;
6983 bool negate = *(p+len)=='!';
6984 if (negate) len++;
6985 p += len;
6986 QCString marker;
6987 while (*p)
6988 {
6989 if (markerInfo.closeLen==0 && *p=='\n') // matching end of line
6990 {
6991 warn(fileName,-1,"Remaining end replacement with marker '{}'",marker);
6992 break;
6993 }
6994 else if (markerInfo.closeLen!= 0 && qstrncmp(p,markerInfo.closeStr,markerInfo.closeLen)==0) // matching marker closing
6995 {
6996 p += markerInfo.closeLen;
6997 warn(fileName,-1,"Remaining end replacement with marker '{}'",marker);
6998 break;
6999 }
7000 marker += *p;
7001 p++;
7002 }
7003 }
7004 }
7005 p++;
7006 }
7007}
const char * data() const
Returns a pointer to the contents of the string in the form of a 0-terminated C string.
Definition qcstring.h:159
int qstrncmp(const char *str1, const char *str2, size_t len)
Definition qcstring.h:75
size_t beginLen
Definition util.h:186
const char * closeStr
Definition util.h:189
const char * beginStr
Definition util.h:185
size_t closeLen
Definition util.h:190
const char * endStr
Definition util.h:187

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

5335{
5336 return fName.right(ext.length())==ext;
5337}

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

5750{
5751 MemberDef *bestMatch = getMemberFromSymbol(scope,fileScope,n);
5752
5753 if (bestMatch && bestMatch->isTypedef())
5754 return TRUE; // closest matching symbol is a typedef
5755 else
5756 return FALSE;
5757}
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:5697

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

Referenced by isVarWithConstructor().

◆ clearSubDirs()

void clearSubDirs ( const Dir & d)

Definition at line 4107 of file util.cpp.

4108{
4109 if (Config_getBool(CREATE_SUBDIRS))
4110 {
4111 // remove empty subdirectories
4112 int createSubdirsLevelPow2 = 1 << Config_getInt(CREATE_SUBDIRS_LEVEL);
4113 for (int l1=0;l1<16;l1++)
4114 {
4115 QCString subdir;
4116 subdir.sprintf("d%x",l1);
4117 for (int l2=0; l2 < createSubdirsLevelPow2; l2++)
4118 {
4119 QCString subsubdir;
4120 subsubdir.sprintf("d%x/d%02x",l1,l2);
4121 if (d.exists(subsubdir.str()) && d.isEmpty(subsubdir.str()))
4122 {
4123 d.rmdir(subsubdir.str());
4124 }
4125 }
4126 if (d.exists(subdir.str()) && d.isEmpty(subdir.str()))
4127 {
4128 d.rmdir(subdir.str());
4129 }
4130 }
4131 }
4132}
bool isEmpty(const std::string subdir) const
Definition dir.cpp:263
bool rmdir(const std::string &path, bool acceptsAbsPath=true) const
Definition dir.cpp:309
bool exists() const
Definition dir.cpp:257
const std::string & str() const
Definition qcstring.h:537
QCString & sprintf(const char *format,...)
Definition qcstring.cpp:29
#define Config_getInt(name)
Definition config.h:34
#define Config_getBool(name)
Definition config.h:33

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

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

◆ computeQualifiedIndex()

int computeQualifiedIndex ( const QCString & name)

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

Definition at line 7248 of file util.cpp.

7249{
7250 int l = static_cast<int>(name.length());
7251 int lastSepPos = -1;
7252 const char *p = name.data();
7253 int i=l-2;
7254 int sharpCount=0;
7255 // --- begin optimized version of ts=name.findRev(">::");
7256 int ts = -1;
7257 while (i>=0)
7258 {
7259 if (p[i]=='>')
7260 {
7261 if (sharpCount==0 && p[i+1]==':' && p[i+2]==':')
7262 {
7263 ts=i;
7264 break;
7265 }
7266 sharpCount++;
7267 }
7268 else if (p[i]=='<')
7269 {
7270 sharpCount--;
7271 }
7272 i--;
7273 }
7274 // --- end optimized version
7275 if (ts==-1) ts=0; else p+=++ts;
7276 for (i=ts;i<l-1;i++)
7277 {
7278 char c=*p++;
7279 if (c==':' && *p==':') lastSepPos=i;
7280 if (c=='<') break;
7281 }
7282 return lastSepPos;
7283}

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

5406{
5407 if (str.isEmpty() || word==nullptr) return false;
5408 static const reg::Ex re(R"(\a+)");
5409 std::string s = str.str();
5410 for (reg::Iterator it(s,re) ; it!=reg::Iterator() ; ++it)
5411 {
5412 if (it->str()==word) return true;
5413 }
5414 return false;
5415}
Class representing a regular expression.
Definition regex.h:39
Iterator class to iterator through matches.
Definition regex.h:232
std::string_view word
Definition util.cpp:980

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

◆ convertCharEntitiesToUTF8()

QCString convertCharEntitiesToUTF8 ( const QCString & str)

Definition at line 4484 of file util.cpp.

4485{
4486 if (str.isEmpty()) return QCString();
4487
4488 std::string s = str.data();
4489 static const reg::Ex re(R"(&\a\w*;)");
4490 reg::Iterator it(s,re);
4492
4493 GrowBuf growBuf;
4494 size_t p=0, i=0, l=0;
4495 for (; it!=end ; ++it)
4496 {
4497 const auto &match = *it;
4498 p = match.position();
4499 l = match.length();
4500 if (p>i)
4501 {
4502 growBuf.addStr(s.substr(i,p-i));
4503 }
4504 QCString entity(match.str());
4506 const char *code=nullptr;
4507 if (symType!=HtmlEntityMapper::Sym_Unknown && (code=HtmlEntityMapper::instance().utf8(symType)))
4508 {
4509 growBuf.addStr(code);
4510 }
4511 else
4512 {
4513 growBuf.addStr(entity);
4514 }
4515 i=p+l;
4516 }
4517 growBuf.addStr(s.substr(i));
4518 growBuf.addChar(0);
4519 //printf("convertCharEntitiesToUTF8(%s)->%s\n",qPrint(s),growBuf.get());
4520 return growBuf.get();
4521}
Class representing a string buffer optimized for growing.
Definition growbuf.h:28
void addChar(char c)
Definition growbuf.h:69
void addStr(const QCString &s)
Definition growbuf.h:72
char * get()
Definition growbuf.h:114
static HtmlEntityMapper & instance()
Returns the one and only instance of the HTML entity mapper.
SymType name2sym(const QCString &symName) const
Give code of the requested HTML entity name.
bool match(std::string_view str, Match &match, const Ex &re)
Matches a given string str for a match against regular expression re.
Definition regex.cpp:759

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

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

◆ convertFileNameFortranParserCode()

FortranFormat convertFileNameFortranParserCode ( QCString fn)

Definition at line 6820 of file util.cpp.

6821{
6823 QCString parserName = Doxygen::parserManager->getParserName(ext);
6824
6825 if (parserName == "fortranfixed") return FortranFormat::Fixed;
6826 else if (parserName == "fortranfree") return FortranFormat::Free;
6827
6829}
static ParserManager * parserManager
Definition doxygen.h:131
QCString getFileNameExtension(const QCString &fn)
Definition util.cpp:5687

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

3945{
3946 if (name.isEmpty()) return name;
3947 bool shortNames = Config_getBool(SHORT_NAMES);
3948 bool createSubdirs = Config_getBool(CREATE_SUBDIRS);
3949 QCString result;
3950 if (shortNames) // use short names only
3951 {
3952 std::lock_guard<std::mutex> lock(g_usedNamesMutex);
3953 auto kv = g_usedNames.find(name.str());
3954 uint32_t num=0;
3955 if (kv!=g_usedNames.end())
3956 {
3957 num = kv->second;
3958 }
3959 else
3960 {
3961 num = g_usedNamesCount;
3962 g_usedNames.emplace(name.str(),g_usedNamesCount++);
3963 }
3964 result.sprintf("a%05d",num);
3965 }
3966 else // long names
3967 {
3968 result=escapeCharsInString(name,allowDots,allowUnderscore);
3969 size_t resultLen = result.length();
3970 if (resultLen>=128) // prevent names that cannot be created!
3971 {
3972 // third algorithm based on MD5 hash
3973 uint8_t md5_sig[16];
3974 char sigStr[33];
3975 MD5Buffer(result.data(),static_cast<unsigned int>(resultLen),md5_sig);
3976 MD5SigToString(md5_sig,sigStr);
3977 result=result.left(128-32)+sigStr;
3978 }
3979 }
3980 if (createSubdirs)
3981 {
3982 int l1Dir=0,l2Dir=0;
3983 int createSubdirsLevel = Config_getInt(CREATE_SUBDIRS_LEVEL);
3984 int createSubdirsBitmaskL2 = (1<<createSubdirsLevel)-1;
3985
3986 // compute md5 hash to determine sub directory to use
3987 uint8_t md5_sig[16];
3988 MD5Buffer(result.data(),static_cast<unsigned int>(result.length()),md5_sig);
3989 l1Dir = md5_sig[14] & 0xf;
3990 l2Dir = md5_sig[15] & createSubdirsBitmaskL2;
3991
3992 result.prepend(QCString().sprintf("d%x/d%02x/",l1Dir,l2Dir));
3993 }
3994 //printf("*** convertNameToFile(%s)->%s\n",qPrint(name),qPrint(result));
3995 return result;
3996}
QCString & prepend(const char *s)
Definition qcstring.h:407
static int g_usedNamesCount
Definition util.cpp:3936
QCString escapeCharsInString(const QCString &name, bool allowDots, bool allowUnderscore)
Definition util.cpp:3770
static std::mutex g_usedNamesMutex
Definition util.cpp:3935
static std::unordered_map< std::string, int > g_usedNames
Definition util.cpp:3934

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

6659{
6660 bool extractPrivate = Config_getBool(EXTRACT_PRIVATE);
6661
6662 // default representing 1-1 mapping
6663 *outListType1=inListType;
6664 *outListType2=MemberListType::Invalid();
6665
6666 if (inProt==Protection::Public)
6667 {
6668 if (inListType.isPrivate())
6669 {
6670 *outListType1=MemberListType::Invalid();
6671 }
6672 }
6673 else if (inProt==Protection::Protected)
6674 {
6675 if (inListType.isPrivate() || inListType.isPublic())
6676 {
6677 *outListType1=MemberListType::Invalid();
6678 }
6679 else if (inListType.isProtected())
6680 {
6681 *outListType2=inListType.toPublic();
6682 }
6683 }
6684 else if (inProt==Protection::Private)
6685 {
6686 if (inListType.isPublic() || inListType.isProtected())
6687 {
6688 *outListType1=MemberListType::Invalid();
6689 }
6690 else if (inListType.isPrivate())
6691 {
6692 if (extractPrivate)
6693 {
6694 *outListType1=inListType.toPublic();
6695 *outListType2=inListType.toProtected();
6696 }
6697 else
6698 {
6699 *outListType1=MemberListType::Invalid();
6700 }
6701 }
6702 }
6703
6704 //printf("convertProtectionLevel(type=%s prot=%d): %s,%s\n",
6705 // qPrint(inListType.to_string()),inProt,qPrint(outListType1->to_string()),qPrint(outListType2->to_string()));
6706}
constexpr bool isProtected() const
Definition types.h:218
MemberListType toProtected() const
Definition types.h:276
MemberListType toPublic() const
Definition types.h:264
static MemberListType Invalid()
Definition types.h:209
constexpr bool isPrivate() const
Definition types.h:220
ML_TYPES constexpr bool isPublic() const
Definition types.h:216
@ Public
Definition types.h:26
@ Private
Definition types.h:26
@ Protected
Definition types.h:26

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

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

◆ convertToHtml()

QCString convertToHtml ( const QCString & s,
bool keepEntities )

Converts a string to a HTML-encoded string

Definition at line 4403 of file util.cpp.

4404{
4405 if (s.isEmpty()) return s;
4406 GrowBuf growBuf;
4407 const char *p=s.data();
4408 char c = 0;
4409 while ((c=*p++))
4410 {
4411 switch (c)
4412 {
4413 case '<': growBuf.addStr("&lt;"); break;
4414 case '>': growBuf.addStr("&gt;"); break;
4415 case '&': if (keepEntities)
4416 {
4417 const char *e=p;
4418 char ce = 0;
4419 while ((ce=*e++))
4420 {
4421 if (ce==';' || (!(isId(ce) || ce=='#'))) break;
4422 }
4423 if (ce==';') // found end of an entity
4424 {
4425 // copy entry verbatim
4426 growBuf.addChar(c);
4427 while (p<e) growBuf.addChar(*p++);
4428 }
4429 else
4430 {
4431 growBuf.addStr("&amp;");
4432 }
4433 }
4434 else
4435 {
4436 growBuf.addStr("&amp;");
4437 }
4438 break;
4439 case '\'': growBuf.addStr("&#39;"); break;
4440 case '"': growBuf.addStr("&quot;"); break;
4441 default:
4442 {
4443 uint8_t uc = static_cast<uint8_t>(c);
4444 if (uc<32 && !isspace(c))
4445 {
4446 growBuf.addStr("&#x24");
4447 growBuf.addChar(hex[uc>>4]);
4448 growBuf.addChar(hex[uc&0xF]);
4449 growBuf.addChar(';');
4450 }
4451 else
4452 {
4453 growBuf.addChar(c);
4454 }
4455 }
4456 break;
4457 }
4458 }
4459 growBuf.addChar(0);
4460 return growBuf.get();
4461}
static constexpr auto hex
bool isId(int c)
Definition util.h:206

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

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

◆ convertToId()

QCString convertToId ( const QCString & s)

Converts a string to a HTML id string

Definition at line 4312 of file util.cpp.

4313{
4314 if (s.isEmpty()) return s;
4315 GrowBuf growBuf;
4316 const char *p = s.data();
4317 char c = 0;
4318 bool first = true;
4319 while ((c=*p++))
4320 {
4321 char encChar[4];
4322 if ((c>='0' && c<='9') || (c>='a' && c<='z') || (c>='A' && c<='Z') || c=='-' || c==':' || c=='.')
4323 { // any permissive character except _
4324 if (first && c>='0' && c<='9') growBuf.addChar('a'); // don't start with a digit
4325 growBuf.addChar(c);
4326 }
4327 else
4328 {
4329 encChar[0]='_';
4330 encChar[1]=hex[static_cast<unsigned char>(c)>>4];
4331 encChar[2]=hex[static_cast<unsigned char>(c)&0xF];
4332 encChar[3]=0;
4333 growBuf.addStr(encChar);
4334 }
4335 first=FALSE;
4336 }
4337 growBuf.addChar(0);
4338 return growBuf.get();
4339}

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

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

◆ convertToJSString()

QCString convertToJSString ( const QCString & s)

Definition at line 4463 of file util.cpp.

4464{
4465 if (s.isEmpty()) return s;
4466 GrowBuf growBuf;
4467 const char *p=s.data();
4468 char c = 0;
4469 while ((c=*p++))
4470 {
4471 switch (c)
4472 {
4473 case '"': growBuf.addStr("\\\""); break;
4474 case '\\': if (*p=='u' && *(p+1)=='{') growBuf.addStr("\\");
4475 else growBuf.addStr("\\\\");
4476 break;
4477 default: growBuf.addChar(c); break;
4478 }
4479 }
4480 growBuf.addChar(0);
4481 return convertCharEntitiesToUTF8(growBuf.get());
4482}
QCString convertCharEntitiesToUTF8(const QCString &str)
Definition util.cpp:4484

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

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

◆ convertToXML()

QCString convertToXML ( const QCString & s,
bool keepEntities )

Converts a string to an XML-encoded string

Definition at line 4352 of file util.cpp.

4353{
4354 if (s.isEmpty()) return s;
4355 GrowBuf growBuf;
4356 const char *p = s.data();
4357 char c = 0;
4358 while ((c=*p++))
4359 {
4360 switch (c)
4361 {
4362 case '<': growBuf.addStr("&lt;"); break;
4363 case '>': growBuf.addStr("&gt;"); break;
4364 case '&': if (keepEntities)
4365 {
4366 const char *e=p;
4367 char ce = 0;
4368 while ((ce=*e++))
4369 {
4370 if (ce==';' || (!(isId(ce) || ce=='#'))) break;
4371 }
4372 if (ce==';') // found end of an entity
4373 {
4374 // copy entry verbatim
4375 growBuf.addChar(c);
4376 while (p<e) growBuf.addChar(*p++);
4377 }
4378 else
4379 {
4380 growBuf.addStr("&amp;");
4381 }
4382 }
4383 else
4384 {
4385 growBuf.addStr("&amp;");
4386 }
4387 break;
4388 case '\'': growBuf.addStr("&apos;"); break;
4389 case '"': growBuf.addStr("&quot;"); break;
4390 case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8:
4391 case 11: case 12: case 13: case 14: case 15: case 16: case 17: case 18:
4392 case 19: case 20: case 21: case 22: case 23: case 24: case 25: case 26:
4393 case 27: case 28: case 29: case 30: case 31:
4394 break; // skip invalid XML characters (see http://www.w3.org/TR/2000/REC-xml-20001006#NT-Char)
4395 default: growBuf.addChar(c); break;
4396 }
4397 }
4398 growBuf.addChar(0);
4399 return growBuf.get();
4400}

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

4346{
4347 if (s.isEmpty()) return s;
4348 return "a" + s;
4349}

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

6355{
6356 QCString result = url;
6357 if (!relPath.isEmpty() && !isURL(url))
6358 {
6359 result.prepend(relPath);
6360 }
6361 return result;
6362}
bool isURL(const QCString &url)
Checks whether the given url starts with a supported protocol.
Definition util.cpp:6342

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

6135{
6136 QCString url;
6137 if (!ref.isEmpty())
6138 {
6139 url = externalRef(relPath,ref,href);
6140 }
6141 if (!targetFileName.isEmpty())
6142 {
6143 QCString fn = targetFileName;
6144 if (ref.isEmpty())
6145 {
6146 if (!anchor.isEmpty() && isLocalFile)
6147 {
6148 fn=""; // omit file name for local links
6149 }
6150 else
6151 {
6152 url = relPath;
6153 }
6154 }
6155 url+=fn;
6156 }
6157 if (!anchor.isEmpty()) url+="#"+anchor;
6158 //printf("createHtmlUrl(relPath=%s,local=%d,target=%s,anchor=%s)=%s\n",qPrint(relPath),isLocalFile,qPrint(targetFileName),qPrint(anchor),qPrint(url));
6159 return url;
6160}
QCString externalRef(const QCString &relPath, const QCString &ref, bool href)
Definition util.cpp:6162

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

4081{
4082 if (Config_getBool(CREATE_SUBDIRS))
4083 {
4084 // create up to 4096 subdirectories
4085 int createSubdirsLevelPow2 = 1 << Config_getInt(CREATE_SUBDIRS_LEVEL);
4086 for (int l1=0; l1<16; l1++)
4087 {
4088 QCString subdir;
4089 subdir.sprintf("d%x",l1);
4090 if (!d.exists(subdir.str()) && !d.mkdir(subdir.str()))
4091 {
4092 term("Failed to create output directory '{}'\n",subdir);
4093 }
4094 for (int l2=0; l2<createSubdirsLevelPow2; l2++)
4095 {
4096 QCString subsubdir;
4097 subsubdir.sprintf("d%x/d%02x",l1,l2);
4098 if (!d.exists(subsubdir.str()) && !d.mkdir(subsubdir.str()))
4099 {
4100 term("Failed to create output directory '{}'\n",subsubdir);
4101 }
4102 }
4103 }
4104 }
4105}
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 7347 of file util.cpp.

7348{
7349 QCString result=name;
7350 if (result.endsWith("-g"))
7351 {
7352 int idx = result.find('-');
7353 result = result.left(idx)+templArgs;
7354 }
7355 return result;
7356}

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

Referenced by ClassDefImpl::className().

◆ detab()

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

Definition at line 7144 of file util.cpp.

7145{
7146 int tabSize = Config_getInt(TAB_SIZE);
7147 size_t size = s.length();
7148 GrowBuf out(size);
7149 const char *data = s.data();
7150 size_t i=0;
7151 int col=0;
7152 constexpr auto doxy_nbsp = "&_doxy_nbsp;"; // doxygen escape command for UTF-8 nbsp
7153 const int maxIndent=1000000; // value representing infinity
7154 int minIndent=maxIndent;
7155 bool skip = false;
7156 while (i<size)
7157 {
7158 char c = data[i++];
7159 switch(c)
7160 {
7161 case '\t': // expand tab
7162 {
7163 int stop = tabSize - (col%tabSize);
7164 //printf("expand at %d stop=%d\n",col,stop);
7165 col+=stop;
7166 while (stop--) out.addChar(' ');
7167 }
7168 break;
7169 case '\\':
7170 if (data[i] == '\\') // escaped command -> ignore
7171 {
7172 out.addChar(c);
7173 out.addChar(data[i++]);
7174 col+=2;
7175 }
7176 else if (i+5<size && qstrncmp(&data[i],"iskip",5)==0) // \iskip command
7177 {
7178 i+=5;
7179 skip = true;
7180 }
7181 else if (i+8<size && qstrncmp(&data[i],"endiskip",8)==0) // \endiskip command
7182 {
7183 i+=8;
7184 skip = false;
7185 }
7186 else // some other command
7187 {
7188 out.addChar(c);
7189 col++;
7190 }
7191 break;
7192 case '\n': // reset column counter
7193 out.addChar(c);
7194 col=0;
7195 break;
7196 case ' ': // increment column counter
7197 out.addChar(c);
7198 col++;
7199 break;
7200 default: // non-whitespace => update minIndent
7201 if (c<0 && i<size) // multibyte sequence
7202 {
7203 // special handling of the UTF-8 nbsp character 0xC2 0xA0
7204 int nb = isUTF8NonBreakableSpace(data);
7205 if (nb>0)
7206 {
7207 out.addStr(doxy_nbsp);
7208 i+=nb-1;
7209 }
7210 else
7211 {
7212 int bytes = getUTF8CharNumBytes(c);
7213 for (int j=0;j<bytes-1 && c;j++)
7214 {
7215 out.addChar(c);
7216 c = data[i++];
7217 }
7218 out.addChar(c);
7219 }
7220 }
7221 else
7222 {
7223 out.addChar(c);
7224 }
7225 if (!skip && col<minIndent) minIndent=col;
7226 col++;
7227 }
7228 }
7229 if (minIndent!=maxIndent) refIndent=minIndent; else refIndent=0;
7230 out.addChar(0);
7231 //printf("detab(\n%s\n)=[\n%s\n]\n",qPrint(s),qPrint(out.get()));
7232 return out.get();
7233}
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 qstrncmp().

Referenced by Markdown::process().

◆ determineAbsoluteIncludeName()

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

Definition at line 4040 of file util.cpp.

4041{
4042 bool searchIncludes = Config_getBool(SEARCH_INCLUDES);
4043 QCString absIncFileName = incFileName;
4044 FileInfo fi(curFile.str());
4045 if (fi.exists())
4046 {
4047 QCString absName = QCString(fi.dirPath(TRUE))+"/"+incFileName;
4048 FileInfo fi2(absName.str());
4049 if (fi2.exists())
4050 {
4051 absIncFileName=fi2.absFilePath();
4052 }
4053 else if (searchIncludes) // search in INCLUDE_PATH as well
4054 {
4055 const StringVector &includePath = Config_getList(INCLUDE_PATH);
4056 for (const auto &incPath : includePath)
4057 {
4058 FileInfo fi3(incPath);
4059 if (fi3.exists() && fi3.isDir())
4060 {
4061 absName = QCString(fi3.absFilePath())+"/"+incFileName;
4062 //printf("trying absName=%s\n",qPrint(absName));
4063 FileInfo fi4(absName.str());
4064 if (fi4.exists())
4065 {
4066 absIncFileName=fi4.absFilePath();
4067 break;
4068 }
4069 //printf( "absIncFileName = %s\n", qPrint(absIncFileName) );
4070 }
4071 }
4072 }
4073 //printf( "absIncFileName = %s\n", qPrint(absIncFileName) );
4074 }
4075 return absIncFileName;
4076}
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 3770 of file util.cpp.

3771{
3772 if (name.isEmpty()) return name;
3773 bool caseSenseNames = getCaseSenseNames();
3774 bool allowUnicodeNames = Config_getBool(ALLOW_UNICODE_NAMES);
3775 GrowBuf growBuf;
3776 signed char c = 0;
3777 const char *p=name.data();
3778 while ((c=*p++)!=0)
3779 {
3780 switch(c)
3781 {
3782 case '_': if (allowUnderscore) growBuf.addChar('_'); else growBuf.addStr("__"); break;
3783 case '-': growBuf.addChar('-'); break;
3784 case ':': growBuf.addStr("_1"); break;
3785 case '/': growBuf.addStr("_2"); break;
3786 case '<': growBuf.addStr("_3"); break;
3787 case '>': growBuf.addStr("_4"); break;
3788 case '*': growBuf.addStr("_5"); break;
3789 case '&': growBuf.addStr("_6"); break;
3790 case '|': growBuf.addStr("_7"); break;
3791 case '.': if (allowDots) growBuf.addChar('.'); else growBuf.addStr("_8"); break;
3792 case '!': growBuf.addStr("_9"); break;
3793 case ',': growBuf.addStr("_00"); break;
3794 case ' ': growBuf.addStr("_01"); break;
3795 case '{': growBuf.addStr("_02"); break;
3796 case '}': growBuf.addStr("_03"); break;
3797 case '?': growBuf.addStr("_04"); break;
3798 case '^': growBuf.addStr("_05"); break;
3799 case '%': growBuf.addStr("_06"); break;
3800 case '(': growBuf.addStr("_07"); break;
3801 case ')': growBuf.addStr("_08"); break;
3802 case '+': growBuf.addStr("_09"); break;
3803 case '=': growBuf.addStr("_0a"); break;
3804 case '$': growBuf.addStr("_0b"); break;
3805 case '\\': growBuf.addStr("_0c"); break;
3806 case '@': growBuf.addStr("_0d"); break;
3807 case ']': growBuf.addStr("_0e"); break;
3808 case '[': growBuf.addStr("_0f"); break;
3809 case '#': growBuf.addStr("_0g"); break;
3810 case '"': growBuf.addStr("_0h"); break;
3811 case '~': growBuf.addStr("_0i"); break;
3812 case '\'': growBuf.addStr("_0j"); break;
3813 case ';': growBuf.addStr("_0k"); break;
3814 case '`': growBuf.addStr("_0l"); break;
3815 default:
3816 if (c<0)
3817 {
3818 bool doEscape = true;
3819 if (allowUnicodeNames)
3820 {
3821 int charLen = getUTF8CharNumBytes(c);
3822 if (charLen>0)
3823 {
3824 growBuf.addStr(p-1,charLen);
3825 p+=charLen;
3826 doEscape = false;
3827 }
3828 }
3829 if (doEscape) // not a valid unicode char or escaping needed
3830 {
3831 char ids[5];
3832 unsigned char id = static_cast<unsigned char>(c);
3833 ids[0]='_';
3834 ids[1]='x';
3835 ids[2]=hex[id>>4];
3836 ids[3]=hex[id&0xF];
3837 ids[4]=0;
3838 growBuf.addStr(ids);
3839 }
3840 }
3841 else if (caseSenseNames || !isupper(c))
3842 {
3843 growBuf.addChar(c);
3844 }
3845 else
3846 {
3847 growBuf.addChar('_');
3848 growBuf.addChar(static_cast<char>(tolower(c)));
3849 }
3850 break;
3851 }
3852 }
3853 growBuf.addChar(0);
3854 return growBuf.get();
3855}
bool getCaseSenseNames()
Definition util.cpp:3760

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

6119{
6120 bool extLinksInWindow = Config_getBool(EXT_LINKS_IN_WINDOW);
6121 if (extLinksInWindow)
6122 return "target=\"_blank\" ";
6123 else if (parent)
6124 return "target=\"_parent\" ";
6125 else
6126 return "";
6127}
constexpr DocNodeVariant * parent(DocNodeVariant *n)
returns the parent node of a given node n or nullptr if the node has no parent.
Definition docnode.h:1324

References Config_getBool, and parent().

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

◆ externalRef()

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

Definition at line 6162 of file util.cpp.

6163{
6164 QCString result;
6165 if (!ref.isEmpty())
6166 {
6167 auto it = Doxygen::tagDestinationMap.find(ref.str());
6169 {
6170 result = it->second;
6171 size_t l = result.length();
6172 if (!relPath.isEmpty() && l>0 && result.at(0)=='.')
6173 { // relative path -> prepend relPath.
6174 result.prepend(relPath);
6175 l+=relPath.length();
6176 }
6177 if (l>0 && result.at(l-1)!='/') result+='/';
6178 if (!href) result.append("\" ");
6179 }
6180 }
6181 else
6182 {
6183 result = relPath;
6184 }
6185 return result;
6186}
static StringMap tagDestinationMap
Definition doxygen.h:116
char & at(size_t i)
Returns a reference to the character at index i.
Definition qcstring.h:578
QCString & append(char c)
Definition qcstring.h:381

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

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

◆ extractCanonicalArgType()

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

Definition at line 1800 of file util.cpp.

1801{
1802 QCString type = arg.type.stripWhiteSpace();
1803 QCString name = arg.name;
1804 //printf("----- extractCanonicalArgType(type=%s,name=%s)\n",qPrint(type),qPrint(name));
1805 if ((type=="const" || type=="volatile") && !name.isEmpty())
1806 { // name is part of type => correct
1807 type+=" ";
1808 type+=name;
1809 }
1810 if (name=="const" || name=="volatile")
1811 { // name is part of type => correct
1812 if (!type.isEmpty()) type+=" ";
1813 type+=name;
1814 }
1815 if (!arg.array.isEmpty())
1816 {
1817 type+=arg.array;
1818 }
1819
1820 return extractCanonicalType(d,fs,type,lang);
1821}
static QCString extractCanonicalType(const Definition *d, const FileDef *fs, QCString type, SrcLangExt lang)
Definition util.cpp:1724

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

Referenced by matchArgument2().

◆ extractCanonicalType()

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

Definition at line 1724 of file util.cpp.

1725{
1726 AUTO_TRACE("d={} fs={} type='{}'",d?d->name():"",fs?fs->name():"",type);
1727 type = type.stripWhiteSpace();
1728
1729 // strip const and volatile keywords that are not relevant for the type
1731
1732 // strip leading keywords
1733 type.stripPrefix("class ");
1734 type.stripPrefix("struct ");
1735 type.stripPrefix("union ");
1736 type.stripPrefix("enum ");
1737 type.stripPrefix("typename ");
1738
1739 type = removeRedundantWhiteSpace(type);
1740 //printf("extractCanonicalType(type=%s) start: def=%s file=%s\n",qPrint(type),
1741 // d ? qPrint(d->name()) : "<null>", fs ? qPrint(fs->name()) : "<null>");
1742
1743 QCString canType;
1744 QCString templSpec,word;
1745 int i=0,p=0,pp=0;
1746 while ((i=extractClassNameFromType(type,p,word,templSpec))!=-1)
1747 // foreach identifier in the type
1748 {
1749 //printf(" i=%d p=%d\n",i,p);
1750 if (i>pp) canType += type.mid(pp,i-pp);
1751
1752 QCString ct = getCanonicalTypeForIdentifier(d,fs,word,lang,&templSpec);
1753
1754 // in case the ct is empty it means that "word" represents scope "d"
1755 // and this does not need to be added to the canonical
1756 // type (it is redundant), so/ we skip it. This solves problem 589616.
1757 if (ct.isEmpty() && type.mid(p,2)=="::")
1758 {
1759 p+=2;
1760 }
1761 else
1762 {
1763 canType += ct;
1764 }
1765 //printf(" word=%s templSpec=%s canType=%s ct=%s\n",
1766 // qPrint(word), qPrint(templSpec), qPrint(canType), qPrint(ct));
1767 if (!templSpec.isEmpty()) // if we didn't use up the templSpec already
1768 // (i.e. type is not a template specialization)
1769 // then resolve any identifiers inside.
1770 {
1771 std::string ts = templSpec.str();
1772 static const reg::Ex re(R"(\a\w*)");
1773 reg::Iterator it(ts,re);
1775
1776 size_t tp=0;
1777 // for each identifier template specifier
1778 //printf("adding resolved %s to %s\n",qPrint(templSpec),qPrint(canType));
1779 for (; it!=end ; ++it)
1780 {
1781 const auto &match = *it;
1782 size_t ti = match.position();
1783 size_t tl = match.length();
1784 std::string matchStr = match.str();
1785 canType += ts.substr(tp,ti-tp);
1786 canType += getCanonicalTypeForIdentifier(d,fs,matchStr.c_str(),lang,nullptr);
1787 tp=ti+tl;
1788 }
1789 canType+=ts.substr(tp);
1790 }
1791
1792 pp=p;
1793 }
1794 canType += type.right(type.length()-pp);
1795 AUTO_TRACE_EXIT("canType='{}'",canType);
1796
1797 return removeRedundantWhiteSpace(canType);
1798}
bool stripPrefix(const QCString &prefix)
Definition qcstring.h:198
#define AUTO_TRACE(...)
Definition docnode.cpp:46
#define AUTO_TRACE_EXIT(...)
Definition docnode.cpp:48
int extractClassNameFromType(const QCString &type, int &pos, QCString &name, QCString &templSpec, SrcLangExt lang)
Definition util.cpp:4652
void stripIrrelevantConstVolatile(QCString &s)
Definition util.cpp:1524
static QCString getCanonicalTypeForIdentifier(const Definition *d, const FileDef *fs, const QCString &word, SrcLangExt lang, QCString *tSpec, int count=0)
Definition util.cpp:1570

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

Referenced by extractCanonicalArgType(), and getCanonicalTemplateSpec().

◆ extractClassNameFromType()

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

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

Definition at line 4652 of file util.cpp.

4653{
4654 static const reg::Ex re_norm(R"(\a[\w:]*)");
4655 static const reg::Ex re_fortran(R"(\a[\w:()=]*)");
4656 const reg::Ex *re = &re_norm;
4657
4658 name.clear();
4659 templSpec.clear();
4660 if (type.isEmpty()) return -1;
4661 size_t typeLen=type.length();
4662 if (typeLen>0)
4663 {
4664 if (lang == SrcLangExt::Fortran)
4665 {
4666 if (type[pos]==',') return -1;
4667 if (!type.lower().startsWith("type"))
4668 {
4669 re = &re_fortran;
4670 }
4671 }
4672 std::string s = type.str();
4673 reg::Iterator it(s,*re,static_cast<int>(pos));
4675
4676 if (it!=end)
4677 {
4678 const auto &match = *it;
4679 size_t i = match.position();
4680 size_t l = match.length();
4681 size_t ts = i+l;
4682 size_t te = ts;
4683 size_t tl = 0;
4684
4685 while (ts<typeLen && type[static_cast<uint32_t>(ts)]==' ') ts++,tl++; // skip any whitespace
4686 if (ts<typeLen && type[static_cast<uint32_t>(ts)]=='<') // assume template instance
4687 {
4688 // locate end of template
4689 te=ts+1;
4690 int brCount=1;
4691 while (te<typeLen && brCount!=0)
4692 {
4693 if (type[static_cast<uint32_t>(te)]=='<')
4694 {
4695 if (te<typeLen-1 && type[static_cast<uint32_t>(te)+1]=='<') te++; else brCount++;
4696 }
4697 if (type[static_cast<uint32_t>(te)]=='>')
4698 {
4699 if (te<typeLen-1 && type[static_cast<uint32_t>(te)+1]=='>') te++; else brCount--;
4700 }
4701 te++;
4702 }
4703 }
4704 name = match.str();
4705 if (te>ts)
4706 {
4707 templSpec = QCString(type).mid(ts,te-ts);
4708 tl+=te-ts;
4709 pos=static_cast<int>(i+l+tl);
4710 }
4711 else // no template part
4712 {
4713 pos=static_cast<int>(i+l);
4714 }
4715 //printf("extractClassNameFromType([in] type=%s,[out] pos=%d,[out] name=%s,[out] templ=%s)=TRUE i=%d\n",
4716 // qPrint(type),pos,qPrint(name),qPrint(templSpec),i);
4717 return static_cast<int>(i);
4718 }
4719 }
4720 pos = static_cast<int>(typeLen);
4721 //printf("extractClassNameFromType([in] type=%s,[out] pos=%d,[out] name=%s,[out] templ=%s)=FALSE\n",
4722 // qPrint(type),pos,qPrint(name),qPrint(templSpec));
4723 return -1;
4724}
bool startsWith(const char *s) const
Definition qcstring.h:492
QCString lower() const
Definition qcstring.h:234
void clear()
Definition qcstring.h:169
@ Fortran
Definition types.h:53

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

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

◆ extractDirection()

QCString extractDirection ( QCString & docs)

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

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

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

Definition at line 6602 of file util.cpp.

6603{
6604 std::string s = docs.str();
6605 static const reg::Ex re(R"(\[([ inout,]+)\])");
6606 reg::Iterator it(s,re);
6608 if (it!=end)
6609 {
6610 const auto &match = *it;
6611 size_t p = match.position();
6612 size_t l = match.length();
6613 if (p==0 && l>2)
6614 {
6615 // make dir the part inside [...] without separators
6616 std::string dir = match[1].str();
6617 // strip , and ' ' from dir
6618 dir.erase(std::remove_if(dir.begin(),dir.end(),
6619 [](const char c) { return c==' ' || c==','; }
6620 ),dir.end());
6621 unsigned char ioMask=0;
6622 size_t inIndex = dir.find( "in");
6623 size_t outIndex = dir.find("out");
6624 if ( inIndex!=std::string::npos) dir.erase( inIndex,2),ioMask|=(1<<0);
6625 if (outIndex!=std::string::npos) dir.erase(outIndex,3),ioMask|=(1<<1);
6626 if (dir.empty() && ioMask!=0) // only in and/or out attributes found
6627 {
6628 docs = s.substr(l); // strip attributes
6629 if (ioMask==((1<<0)|(1<<1))) return "[in,out]";
6630 else if (ioMask==(1<<0)) return "[in]";
6631 else if (ioMask==(1<<1)) return "[out]";
6632 }
6633 }
6634 }
6635 return "";
6636}

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

Referenced by inlineArgListToDoc().

◆ extractNamespaceName()

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

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

Definition at line 4137 of file util.cpp.

4140{
4141 int i=0, p=0;
4142 QCString clName=scopeName;
4143 NamespaceDef *nd = nullptr;
4144 if (!clName.isEmpty() && (nd=getResolvedNamespace(clName)) && getClass(clName)==nullptr)
4145 { // the whole name is a namespace (and not a class)
4146 namespaceName=nd->name();
4147 className.clear();
4148 goto done;
4149 }
4150 p=static_cast<int>(clName.length())-2;
4151 while (p>=0 && (i=clName.findRev("::",p))!=-1)
4152 // see if the first part is a namespace (and not a class)
4153 {
4154 //printf("Trying %s\n",qPrint(clName.left(i)));
4155 if (i>0 && (nd=getResolvedNamespace(clName.left(i))) && getClass(clName.left(i))==nullptr)
4156 {
4157 //printf("found!\n");
4158 namespaceName=nd->name();
4159 className=clName.right(clName.length()-i-2);
4160 goto done;
4161 }
4162 p=i-2; // try a smaller piece of the scope
4163 }
4164 //printf("not found!\n");
4165
4166 // not found, so we just have to guess.
4167 className=scopeName;
4168 namespaceName.clear();
4169
4170done:
4171 if (className.isEmpty() && !namespaceName.isEmpty() && !allowEmptyClass)
4172 {
4173 // class and namespace with the same name, correct to return the class.
4174 className=namespaceName;
4175 namespaceName.clear();
4176 }
4177 //printf("extractNamespace '%s' => '%s|%s'\n",qPrint(scopeName),
4178 // qPrint(className),qPrint(namespaceName));
4179 if (className.endsWith("-p"))
4180 {
4181 className = className.left(className.length()-2);
4182 }
4183 return;
4184}
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 1414 of file util.cpp.

1415{
1416 if (name.isEmpty()) return QCString();
1417 bool fileOpened=false;
1418 if (name[0]=='-' && name[1]==0) // read from stdin
1419 {
1420 std::string contents;
1421 std::string line;
1422 while (getline(std::cin,line))
1423 {
1424 contents+=line+'\n';
1425 }
1426 return QCString(contents);
1427 }
1428 else // read from file
1429 {
1430 FileInfo fi(name.str());
1431 if (!fi.exists() || !fi.isFile())
1432 {
1433 err("file '{}' not found\n",name);
1434 return "";
1435 }
1436 std::string buf;
1437 fileOpened=readInputFile(name,buf,filter,isSourceCode);
1438 if (fileOpened)
1439 {
1440 addTerminalCharIfMissing(buf,'\n');
1441 return buf;
1442 }
1443 }
1444 if (!fileOpened)
1445 {
1446 err("cannot open file '{}' for reading\n",name);
1447 }
1448 return "";
1449}
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:5937

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

6514{
6515 bool allExternals = Config_getBool(ALLEXTERNALS);
6516 bool isDocFile = fd->isDocumentationFile();
6517 genSourceFile = !isDocFile && fd->generateSourceFile();
6518 return ( ((allExternals && fd->isLinkable()) ||
6520 ) &&
6521 !isDocFile
6522 );
6523}
virtual bool isLinkable() const =0
virtual bool isLinkableInProject() const =0
virtual bool generateSourceFile() const =0
virtual bool isDocumentationFile() const =0

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

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

◆ filterCRLF()

static void filterCRLF ( std::string & contents)
static

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

Definition at line 1275 of file util.cpp.

1276{
1277 size_t src = 0; // source index
1278 size_t dest = 0; // destination index
1279 size_t len = contents.length();
1280
1281 while (src<len)
1282 {
1283 char c = contents[src++]; // Remember the processed character.
1284 if (c == '\r') // CR to be solved (MAC, DOS)
1285 {
1286 c = '\n'; // each CR to LF
1287 if (src<len && contents[src] == '\n')
1288 {
1289 ++src; // skip LF just after CR (DOS)
1290 }
1291 }
1292 else if ( c == '\0' && src<len-1) // filter out internal \0 characters, as it will confuse the parser
1293 {
1294 c = ' '; // turn into a space
1295 }
1296 contents[dest++] = c; // copy the (modified) character to dest
1297 }
1298 contents.resize(dest);
1299}

Referenced by readInputFile().

◆ filterTitle()

QCString filterTitle ( const QCString & title)

Definition at line 6017 of file util.cpp.

6018{
6019 std::string tf;
6020 std::string t = title.str();
6021 static const reg::Ex re(R"(%[a-z_A-Z]+)");
6022 reg::Iterator it(t,re);
6024 size_t p = 0;
6025 for (; it!=end ; ++it)
6026 {
6027 const auto &match = *it;
6028 size_t i = match.position();
6029 size_t l = match.length();
6030 if (i>p) tf+=t.substr(p,i-p);
6031 tf+=match.str().substr(1); // skip %
6032 p=i+l;
6033 }
6034 tf+=t.substr(p);
6035 return QCString(tf);
6036}

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

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

◆ findAndRemoveWord()

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

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

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

Definition at line 5421 of file util.cpp.

5422{
5423 static reg::Ex re(R"(\s*(<\a+>)\s*)");
5424 std::string s = sentence.str();
5425 reg::Iterator it(s,re);
5427 std::string result;
5428 bool found=false;
5429 size_t p=0;
5430 for ( ; it!=end ; ++it)
5431 {
5432 const auto match = *it;
5433 std::string part = match[1].str();
5434 if (part!=word)
5435 {
5436 size_t i = match.position();
5437 size_t l = match.length();
5438 result+=s.substr(p,i-p);
5439 result+=match.str();
5440 p=i+l;
5441 }
5442 else
5443 {
5444 found=true;
5445 size_t i = match[1].position();
5446 size_t l = match[1].length();
5447 result+=s.substr(p,i-p);
5448 p=i+l;
5449 }
5450 }
5451 result+=s.substr(p);
5452 sentence = QCString(result).simplifyWhiteSpace();
5453 return found;
5454}
QCString simplifyWhiteSpace() const
return a copy of this string with leading and trailing whitespace removed and multiple whitespace cha...
Definition qcstring.cpp:185
bool found
Definition util.cpp:984

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

Referenced by isVarWithConstructor().

◆ findFileDef()

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

Definition at line 3348 of file util.cpp.

3349{
3350 ambig=FALSE;
3351 if (n.isEmpty()) return nullptr;
3352
3353
3354 const int maxAddrSize = 20;
3355 char addr[maxAddrSize];
3356 qsnprintf(addr,maxAddrSize,"%p:",reinterpret_cast<const void*>(fnMap));
3357 QCString key = addr;
3358 key+=n;
3359
3360 std::lock_guard<std::mutex> lock(g_findFileDefMutex);
3361 FindFileCacheElem *cachedResult = g_findFileDefCache.find(key.str());
3362 //printf("key=%s cachedResult=%p\n",qPrint(key),cachedResult);
3363 if (cachedResult)
3364 {
3365 ambig = cachedResult->isAmbig;
3366 //printf("cached: fileDef=%p\n",cachedResult->fileDef);
3367 return cachedResult->fileDef;
3368 }
3369 else
3370 {
3371 cachedResult = g_findFileDefCache.insert(key.str(),FindFileCacheElem(nullptr,FALSE));
3372 }
3373
3374 QCString name=Dir::cleanDirPath(n.str());
3375 QCString path;
3376 if (name.isEmpty()) return nullptr;
3377 int slashPos=std::max(name.findRev('/'),name.findRev('\\'));
3378 if (slashPos!=-1)
3379 {
3380 path=removeLongPathMarker(name.left(slashPos+1));
3381 name=name.right(name.length()-slashPos-1);
3382 }
3383 if (name.isEmpty()) return nullptr;
3384 const FileName *fn = fnMap->find(name);
3385 if (fn)
3386 {
3387 //printf("fn->size()=%zu\n",fn->size());
3388 if (fn->size()==1)
3389 {
3390 const std::unique_ptr<FileDef> &fd = fn->front();
3391 bool isSamePath = Portable::fileSystemIsCaseSensitive() ?
3392 fd->getPath().right(path.length())==path :
3393 fd->getPath().right(path.length()).lower()==path.lower();
3394 if (path.isEmpty() || isSamePath)
3395 {
3396 cachedResult->fileDef = fd.get();
3397 return fd.get();
3398 }
3399 }
3400 else // file name alone is ambiguous
3401 {
3402 int count=0;
3403 FileDef *lastMatch=nullptr;
3404 QCString pathStripped = stripFromIncludePath(path);
3405 for (const auto &fd_p : *fn)
3406 {
3407 FileDef *fd = fd_p.get();
3408 QCString fdStripPath = stripFromIncludePath(fd->getPath());
3409 if (path.isEmpty() || fdStripPath.right(pathStripped.length())==pathStripped)
3410 {
3411 count++;
3412 lastMatch=fd;
3413 }
3414 }
3415
3416 ambig=(count>1);
3417 cachedResult->isAmbig = ambig;
3418 cachedResult->fileDef = lastMatch;
3419 return lastMatch;
3420 }
3421 }
3422 else
3423 {
3424 //printf("not found!\n");
3425 }
3426 return nullptr;
3427}
static std::string cleanDirPath(const std::string &path)
Definition dir.cpp:355
A model of a file symbol.
Definition filedef.h:99
virtual QCString getPath() const =0
Class representing all files with a certain base name.
Definition filename.h:30
bool fileSystemIsCaseSensitive()
Definition portable.cpp:487
#define qsnprintf
Definition qcstring.h:49
Cache element for the file name to FileDef mapping cache.
Definition util.cpp:3338
FileDef * fileDef
Definition util.cpp:3340
QCString stripFromIncludePath(const QCString &path)
Definition util.cpp:340
static Cache< std::string, FindFileCacheElem > g_findFileDefCache(5000)
static std::mutex g_findFileDefMutex
Definition util.cpp:3346
QCString removeLongPathMarker(QCString path)
Definition util.cpp:298

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

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

◆ findFilePath()

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

Definition at line 3431 of file util.cpp.

3432{
3433 ambig=false;
3434 QCString result;
3435 bool found=false;
3436 if (!found)
3437 {
3438 FileInfo fi(file.str());
3439 if (fi.exists())
3440 {
3441 result=fi.absFilePath();
3442 found=true;
3443 }
3444 }
3445 if (!found)
3446 {
3447 const StringVector &examplePathList = Config_getList(EXAMPLE_PATH);
3448 for (const auto &s : examplePathList)
3449 {
3450 std::string absFileName = s+(Portable::pathSeparator()+file).str();
3451 FileInfo fi(absFileName);
3452 if (fi.exists())
3453 {
3454 result=fi.absFilePath();
3455 found=true;
3456 }
3457 }
3458 }
3459
3460 if (!found)
3461 {
3462 // as a fallback we also look in the exampleNameDict
3464 if (fd && !ambig)
3465 {
3466 result=fd->absFilePath();
3467 }
3468 }
3469 return result;
3470}
static FileNameLinkedMap * exampleNameLinkedMap
Definition doxygen.h:103
virtual QCString absFilePath() const =0
QCString pathSeparator()
Definition portable.cpp:391
FileDef * findFileDef(const FileNameLinkedMap *fnMap, const QCString &n, bool &ambig)
Definition util.cpp:3348

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

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

◆ findIndex() [1/2]

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

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

Definition at line 7086 of file util.cpp.

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

References reg::search().

◆ findIndex() [2/2]

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

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

Definition at line 7078 of file util.cpp.

7079{
7080 auto it = std::find(sv.begin(),sv.end(),s);
7081 return it!=sv.end() ? static_cast<int>(it-sv.begin()) : -1;
7082}

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

◆ findMembersWithSpecificName()

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

Definition at line 2169 of file util.cpp.

2175{
2176 //printf(" Function with global scope name '%s' args='%s'\n",
2177 // mn->memberName(),args);
2178 for (const auto &md_p : *mn)
2179 {
2180 const MemberDef *md = md_p.get();
2181 const FileDef *fd=md->getFileDef();
2182 const GroupDef *gd=md->getGroupDef();
2183 //printf(" md->name()='%s' md->args='%s' fd=%p gd=%p current=%p ref=%s\n",
2184 // qPrint(md->name()),args,fd,gd,currentFile,qPrint(md->getReference()));
2185 if (
2186 ((gd && gd->isLinkable()) || (fd && fd->isLinkable()) || md->isReference()) &&
2187 md->getNamespaceDef()==nullptr && md->isLinkable() &&
2188 (!checkStatics || (!md->isStatic() && !md->isDefine()) ||
2189 currentFile==nullptr || fd==currentFile) // statics must appear in the same file
2190 )
2191 {
2192 bool match=TRUE;
2193 if (!args.isEmpty() && !md->isDefine() && args!="()")
2194 {
2195 const ArgumentList &mdAl = md->argumentList();
2196 auto argList_p = stringToArgumentList(md->getLanguage(),args);
2198 md->getOuterScope(),fd,&mdAl,
2199 Doxygen::globalScope,fd,argList_p.get(),
2200 checkCV,md->getLanguage());
2201 }
2202 if (match)
2203 {
2204 //printf("Found match!\n");
2205 members.push_back(md);
2206 }
2207 }
2208 }
2209}
This class represents an function or template argument list.
Definition arguments.h:60
virtual SrcLangExt getLanguage() const =0
Returns the programming language this definition was written in.
virtual Definition * getOuterScope() const =0
static NamespaceDefMutable * globalScope
Definition doxygen.h:121
A model of a group of symbols.
Definition groupdef.h:52
virtual GroupDef * getGroupDef()=0
virtual const FileDef * getFileDef() const =0
virtual const ArgumentList & argumentList() const =0
virtual bool isStatic() const =0
virtual bool isDefine() const =0
virtual const NamespaceDef * getNamespaceDef() const =0
std::unique_ptr< ArgumentList > stringToArgumentList(SrcLangExt lang, const QCString &argsString, QCString *extraTypeChars=nullptr)
Definition defargs.l:814
bool matchArguments2(const Definition *srcScope, const FileDef *srcFileScope, const ArgumentList *srcAl, const Definition *dstScope, const FileDef *dstFileScope, const ArgumentList *dstAl, bool checkCV, SrcLangExt lang)
Definition util.cpp:1931

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

Referenced by getDefsOld().

◆ findModuleDef()

static ModuleDef * findModuleDef ( const Definition * d)
static

Definition at line 5261 of file util.cpp.

5262{
5263 ModuleDef *mod = nullptr;
5265 {
5266 const FileDef *fd = toFileDef(d);
5267 if (fd) mod = fd->getModuleDef();
5268 }
5270 {
5271 const ClassDef *cd = toClassDef(d);
5272 if (cd)
5273 {
5274 const FileDef *fd = cd->getFileDef();
5275 if (fd) mod = fd->getModuleDef();
5276 }
5277 }
5279 {
5280 const ConceptDef *cd = toConceptDef(d);
5281 if (cd)
5282 {
5283 const FileDef *fd = cd->getFileDef();
5284 if (fd) mod = fd->getModuleDef();
5285 }
5286 }
5287 return mod;
5288}
A abstract class representing of a compound symbol.
Definition classdef.h:104
virtual FileDef * getFileDef() const =0
Returns the namespace this compound is in, or 0 if it has a global scope.
virtual const FileDef * getFileDef() const =0
virtual DefType definitionType() const =0
virtual ModuleDef * getModuleDef() const =0
ClassDef * toClassDef(Definition *d)
ConceptDef * toConceptDef(Definition *d)
FileDef * toFileDef(Definition *d)
Definition filedef.cpp:1894

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

Referenced by recursivelyAddGroupListToTitle().

◆ findParameterList()

int findParameterList ( const QCString & name)

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

Definition at line 836 of file util.cpp.

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

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

Referenced by resolveRef().

◆ generateAnonymousAnchor()

QCString generateAnonymousAnchor ( const QCString & fileName,
int count )

Definition at line 3998 of file util.cpp.

3999{
4000 QCString fn = stripFromPath(fileName)+":"+QCString().setNum(count);
4001 const int sig_size=16;
4002 uint8_t md5_sig[sig_size];
4003 MD5Buffer(fn.data(),static_cast<unsigned int>(fn.length()),md5_sig);
4004 char result[sig_size*3+2];
4005 char *p = result;
4006 *p++='@';
4007 for (int i=0;i<sig_size;i++)
4008 {
4009 static const char oct[]="01234567";
4010 uint8_t byte = md5_sig[i];
4011 *p++=oct[(byte>>6)&7];
4012 *p++=oct[(byte>>3)&7];
4013 *p++=oct[(byte>>0)&7];
4014 }
4015 *p='\0';
4016 return result;
4017}
QCString & setNum(short n)
Definition qcstring.h:444
static QCString stripFromPath(const QCString &p, const StringVector &l)
Definition util.cpp:309

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

◆ generateFileRef()

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

Definition at line 3320 of file util.cpp.

3321{
3322 //printf("generateFileRef(%s,%s)\n",name,text);
3323 QCString linkText = text.isEmpty() ? text : name;
3324 //FileInfo *fi;
3325 bool ambig = false;
3327 if (fd && fd->isLinkable())
3328 // link to documented input file
3329 ol.writeObjectLink(fd->getReference(),fd->getOutputFileBase(),QCString(),linkText);
3330 else
3331 ol.docify(linkText);
3332}
static FileNameLinkedMap * inputNameLinkedMap
Definition doxygen.h:105
void writeObjectLink(const QCString &ref, const QCString &file, const QCString &anchor, const QCString &name)
Definition outputlist.h:440
void docify(const QCString &s)
Definition outputlist.h:438

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

◆ generateMarker()

QCString generateMarker ( int id)

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

Definition at line 290 of file util.cpp.

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

References qsnprintf.

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

◆ genericPatternMatch()

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

Definition at line 6041 of file util.cpp.

6045{
6046 bool caseSenseNames = getCaseSenseNames();
6047 bool found = FALSE;
6048
6049 // For platforms where the file system is non case sensitive overrule the setting
6051 {
6052 caseSenseNames = FALSE;
6053 }
6054
6055 if (!patList.empty())
6056 {
6057 std::string fn = fi.fileName();
6058 std::string fp = fi.filePath();
6059 std::string afp= fi.absFilePath();
6060
6061 for (const auto &li : patList)
6062 {
6063 std::string pattern = getter(li).str();
6064 if (!pattern.empty())
6065 {
6066 size_t i=pattern.find('=');
6067 if (i!=std::string::npos) pattern=pattern.substr(0,i); // strip of the extension specific filter name
6068
6069 if (!caseSenseNames)
6070 {
6071 pattern = QCString(pattern).lower().str();
6072 fn = QCString(fn).lower().str();
6073 fp = QCString(fp).lower().str();
6074 afp = QCString(afp).lower().str();
6075 }
6076 reg::Ex re(pattern,reg::Ex::Mode::Wildcard);
6077 found = re.isValid() && (reg::match(fn,re) ||
6078 (fn!=fp && reg::match(fp,re)) ||
6079 (fn!=afp && fp!=afp && reg::match(afp,re)));
6080 if (found)
6081 {
6082 elem = li;
6083 break;
6084 }
6085 //printf("Matching '%s' against pattern '%s' found=%d\n",
6086 // qPrint(fi->fileName()),qPrint(pattern),found);
6087 }
6088 }
6089 }
6090 return found;
6091}
std::string fileName() const
Definition fileinfo.cpp:118
std::string filePath() const
Definition fileinfo.cpp:91
std::string absFilePath() const
Definition fileinfo.cpp:101
@ Wildcard
simple globbing pattern.
Definition regex.h:45

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

Referenced by getEncoding(), and patternMatch().

◆ getCanonicalTemplateSpec()

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

Definition at line 1550 of file util.cpp.

1551{
1552
1553 QCString templSpec = spec.stripWhiteSpace();
1554 // this part had been commented out before... but it is needed to match for instance
1555 // std::list<std::string> against list<string> so it is now back again!
1556 if (!templSpec.isEmpty() && templSpec.at(0) == '<')
1557 {
1558 templSpec = "< " + extractCanonicalType(d,fs,templSpec.right(templSpec.length()-1).stripWhiteSpace(),lang);
1559 }
1560 QCString resolvedType = lang==SrcLangExt::Java ? templSpec : resolveTypeDef(d,templSpec);
1561 if (!resolvedType.isEmpty()) // not known as a typedef either
1562 {
1563 templSpec = resolvedType;
1564 }
1565 //printf("getCanonicalTemplateSpec(%s)=%s\n",qPrint(spec),qPrint(templSpec));
1566 return templSpec;
1567}
QCString resolveTypeDef(const Definition *context, const QCString &qualifiedName, const Definition **typedefContext)
Definition util.cpp:384

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

Referenced by getCanonicalTypeForIdentifier().

◆ getCanonicalTypeForIdentifier()

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

Definition at line 1570 of file util.cpp.

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

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

Referenced by extractCanonicalType(), and getCanonicalTypeForIdentifier().

◆ getCaseSenseNames()

bool getCaseSenseNames ( )

Definition at line 3760 of file util.cpp.

3761{
3762 auto caseSenseNames = Config_getEnum(CASE_SENSE_NAMES);
3763
3764 if (caseSenseNames == CASE_SENSE_NAMES_t::YES) return true;
3765 else if (caseSenseNames == CASE_SENSE_NAMES_t::NO) return false;
3767}
#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 2762 of file util.cpp.

2763{
2764 if (false) // set this to true to try the old and new routine side-by-side and compare the results
2765 {
2766 printf("@@ ------ getDefsOld start\n");
2767 GetDefResult result = getDefsOld(input);
2768 printf("@@ ------ getDefsOld end\n");
2769 printf("@@ ------ getDefsNew start\n");
2770 GetDefResult newResult = getDefsNew(input);
2771 printf("@@ ------ getDefsNew end\n");
2772 if (result.found!=newResult.found ||
2773 result.md!=newResult.md ||
2774 result.cd!=newResult.cd ||
2775 result.fd!=newResult.fd ||
2776 result.nd!=newResult.nd ||
2777 result.gd!=newResult.gd
2778 )
2779 {
2780 printf("@@ getDefsOld(scName=%s, mbName=%s, args=%s, forceEmptyScope=%d "
2781 "currentFile=%s checkCV=%d)=%d md=%s (%p) cd=%s fd=%s nd=%s gd=%s\n",
2782 qPrint(input.scopeName), qPrint(input.memberName), qPrint(input.args),
2783 input.forceEmptyScope, qPrint(input.currentFile?input.currentFile->name():QCString()),
2784 input.checkCV,
2785 result.found,
2786 qPrint(result.md ? result.md->name() : QCString()),
2787 (void*)result.md,
2788 qPrint(result.cd ? result.cd->name() : QCString()),
2789 qPrint(result.fd ? result.fd->name() : QCString()),
2790 qPrint(result.nd ? result.nd->name() : QCString()),
2791 qPrint(result.gd ? result.gd->name() : QCString())
2792 );
2793 printf("@@ ------ getDefsOld start\n");
2794 printf("@@ getDefsNew(scName=%s, mbName=%s, args=%s, forceEmptyScope=%d "
2795 "currentFile=%s checkCV=%d)=%d md=%s (%p) cd=%s fd=%s nd=%s gd=%s\n",
2796 qPrint(input.scopeName), qPrint(input.memberName), qPrint(input.args),
2797 input.forceEmptyScope, qPrint(input.currentFile?input.currentFile->name():QCString()),
2798 input.checkCV,
2799 newResult.found,
2800 qPrint(newResult.md ? newResult.md->name() : QCString()),
2801 (void*)newResult.md,
2802 qPrint(newResult.cd ? newResult.cd->name() : QCString()),
2803 qPrint(newResult.fd ? newResult.fd->name() : QCString()),
2804 qPrint(newResult.nd ? newResult.nd->name() : QCString()),
2805 qPrint(newResult.gd ? newResult.gd->name() : QCString())
2806 );
2807 }
2808 return result; // use return newResult to use the result of the new routine
2809 }
2810 else // do one of the two getDefs routines (comment out the other one)
2811 {
2812 return getDefsNew(input);
2813 }
2814}
const char * qPrint(const char *s)
Definition qcstring.h:672
bool forceEmptyScope
Definition util.h:116
const FileDef * currentFile
Definition util.h:117
QCString scopeName
Definition util.h:113
bool checkCV
Definition util.h:118
QCString args
Definition util.h:115
QCString memberName
Definition util.h:114
const MemberDef * md
Definition util.h:125
const FileDef * fd
Definition util.h:127
const GroupDef * gd
Definition util.h:129
bool found
Definition util.h:124
const ClassDef * cd
Definition util.h:126
const NamespaceDef * nd
Definition util.h:128
GetDefResult getDefsOld(const GetDefInput &input)
Definition util.cpp:2288
GetDefResult getDefsNew(const GetDefInput &input)
Definition util.cpp:2213

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

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

◆ getDefsNew()

GetDefResult getDefsNew ( const GetDefInput & input)

Definition at line 2213 of file util.cpp.

2214{
2215 GetDefResult result;
2216 if (input.memberName.isEmpty()) return result;
2217
2218 //printf("@@ --- getDefsNew(%s,%s)-----------\n",qPrint(scName),qPrint(mbName));
2219 const Definition *scope = Doxygen::globalScope;
2220 SymbolResolver resolver;
2221 if (input.currentFile) resolver.setFileScope(input.currentFile);
2222 if (!input.scopeName.isEmpty())
2223 {
2224 scope = resolver.resolveSymbol(scope,input.scopeName);
2225 }
2226 if (scope==Doxygen::globalScope)
2227 {
2228 scope = input.currentFile;
2229 }
2230 //printf("@@ -> found scope scope=%s member=%s out=%s\n",qPrint(input.scopeName),qPrint(input.memberName),qPrint(scope?scope->name():""));
2231 //
2232 const Definition *symbol = resolver.resolveSymbol(scope,input.memberName,input.args,input.checkCV,input.insideCode);
2233 //printf("@@ -> found symbol in=%s out=%s\n",qPrint(input.memberName),qPrint(symbol?symbol->qualifiedName():QCString()));
2234 if (symbol && symbol->definitionType()==Definition::TypeMember)
2235 {
2236 result.md = toMemberDef(symbol);
2237 result.cd = result.md->getClassDef();
2238 if (result.cd==nullptr) result.nd = result.md->getNamespaceDef();
2239 if (result.cd==nullptr && result.nd==nullptr) result.fd = result.md->getFileDef();
2240 result.gd = result.md->getGroupDef();
2241 result.found = true;
2242 }
2243 else if (symbol && symbol->definitionType()==Definition::TypeClass)
2244 {
2245 result.cd = toClassDef(symbol);
2246 result.found = true;
2247 }
2248 else if (symbol && symbol->definitionType()==Definition::TypeNamespace)
2249 {
2250 result.nd = toNamespaceDef(symbol);
2251 result.found = true;
2252 }
2253 else if (symbol && symbol->definitionType()==Definition::TypeConcept)
2254 {
2255 result.cnd = toConceptDef(symbol);
2256 result.found = true;
2257 }
2258 else if (symbol && symbol->definitionType()==Definition::TypeModule)
2259 {
2260 result.modd = toModuleDef(symbol);
2261 result.found = true;
2262 }
2263 return result;
2264}
The common base class of all entity definitions found in the sources.
Definition definition.h:76
virtual const ClassDef * getClassDef() const =0
const Definition * resolveSymbol(const Definition *scope, const QCString &name, const QCString &args=QCString(), bool checkCV=false, bool insideCode=false)
Find the symbool definition matching name within the scope set.
void setFileScope(const FileDef *fd)
Sets or updates the file scope using when resolving symbols.
MemberDef * toMemberDef(Definition *d)
ModuleDef * toModuleDef(Definition *d)
NamespaceDef * toNamespaceDef(Definition *d)
bool insideCode
Definition util.h:119
const ConceptDef * cnd
Definition util.h:130
const ModuleDef * modd
Definition util.h:131

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

Referenced by getDefs().

◆ getDefsOld()

GetDefResult getDefsOld ( const GetDefInput & input)

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

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

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

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

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

Definition at line 2288 of file util.cpp.

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

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

Referenced by getDefs().

◆ getDotImageExtension()

QCString getDotImageExtension ( )

Definition at line 6713 of file util.cpp.

6714{
6715 QCString imgExt = Config_getEnumAsString(DOT_IMAGE_FORMAT);
6716 int i= imgExt.find(':'); // strip renderer part when using e.g. 'png:cairo:gd' as format
6717 return i==-1 ? imgExt : imgExt.left(i);
6718}
#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 6104 of file util.cpp.

6105{
6106 InputFileEncoding elem;
6107 auto getter = [](const InputFileEncoding &e) { return e.pattern; };
6108 if (genericPatternMatch(fi,Doxygen::inputFileEncodingList,elem,getter)) // check for file specific encoding
6109 {
6110 return elem.encoding;
6111 }
6112 else // fall back to default encoding
6113 {
6114 return Config_getString(INPUT_ENCODING);
6115 }
6116}
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:6041

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

1343{
1344 // sanity check
1345 if (name.isEmpty()) return "";
1346
1347 const StringVector& filterSrcList = Config_getList(FILTER_SOURCE_PATTERNS);
1348 const StringVector& filterList = Config_getList(FILTER_PATTERNS);
1349
1350 QCString filterName;
1351 bool found=FALSE;
1352 if (isSourceCode && !filterSrcList.empty())
1353 { // first look for source filter pattern list
1354 filterName = getFilterFromList(name,filterSrcList,found);
1355 }
1356 if (!found && filterName.isEmpty())
1357 { // then look for filter pattern list
1358 filterName = getFilterFromList(name,filterList,found);
1359 }
1360 if (!found)
1361 { // then use the generic input filter
1362 return Config_getString(INPUT_FILTER);
1363 }
1364 else
1365 {
1366 /* remove surrounding double quotes */
1367 if (filterName.length()>=2 && filterName[0]=='"' && filterName[static_cast<int>(filterName.length())-1]=='"')
1368 {
1369 filterName = filterName.mid(1,filterName.length()-2);
1370 }
1371 return filterName;
1372 }
1373}
static QCString getFilterFromList(const QCString &name, const StringVector &filterList, bool &found)
Definition util.cpp:1301

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

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

◆ getFileNameExtension()

◆ getFilterFromList()

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

Definition at line 1301 of file util.cpp.

1302{
1303 found=FALSE;
1304 // compare the file name to the filter pattern list
1305 for (const auto &filterStr : filterList)
1306 {
1307 QCString fs = filterStr.c_str();
1308 int i_equals=fs.find('=');
1309 if (i_equals!=-1)
1310 {
1311 QCString filterPattern = fs.left(i_equals);
1312 QCString input = name;
1314 {
1315 filterPattern = filterPattern.lower();
1316 input = input.lower();
1317 }
1318 reg::Ex re(filterPattern.str(),reg::Ex::Mode::Wildcard);
1319 if (re.isValid() && reg::match(input.str(),re))
1320 {
1321 // found a match!
1322 QCString filterName = fs.mid(i_equals+1);
1323 if (filterName.find(' ')!=-1)
1324 { // add quotes if the name has spaces
1325 filterName="\""+filterName+"\"";
1326 }
1327 found=TRUE;
1328 return filterName;
1329 }
1330 }
1331 }
1332
1333 // no match
1334 return "";
1335}

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

Referenced by getFileFilter().

◆ getLanguageFromCodeLang()

SrcLangExt getLanguageFromCodeLang ( QCString & fileName)

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

Definition at line 5663 of file util.cpp.

5664{
5665 // try the extension
5666 auto lang = getLanguageFromFileName(fileName, SrcLangExt::Unknown);
5667 if (lang == SrcLangExt::Unknown)
5668 {
5669 // try the language names
5670 QCString langName = fileName.lower();
5671 if (langName.at(0)=='.') langName = langName.mid(1);
5672 auto it = std::find_if(g_lang2extMap.begin(),g_lang2extMap.end(),
5673 [&langName](const auto &info) { return info.langName==langName; });
5674 if (it != g_lang2extMap.end())
5675 {
5676 lang = it->parserId;
5677 fileName = it->defExt;
5678 }
5679 else // default to C++
5680 {
5681 return SrcLangExt::Cpp;
5682 }
5683 }
5684 return lang;
5685}
@ Unknown
Definition types.h:43
SrcLangExt getLanguageFromFileName(const QCString &fileName, SrcLangExt defLang)
Definition util.cpp:5645
static std::vector< Lang2ExtMap > g_lang2extMap
Definition util.cpp:5516

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

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

◆ getLanguageFromFileName()

SrcLangExt getLanguageFromFileName ( const QCString & fileName,
SrcLangExt defLang )

Definition at line 5645 of file util.cpp.

5646{
5647 FileInfo fi(fileName.str());
5648 // we need only the part after the last ".", newer implementations of FileInfo have 'suffix()' for this.
5649 QCString extName = QCString(fi.extension(FALSE)).lower();
5650 if (extName.isEmpty()) extName=".no_extension";
5651 if (extName.at(0)!='.') extName.prepend(".");
5652 auto it = g_extLookup.find(extName.str());
5653 if (it!=g_extLookup.end()) // listed extension
5654 {
5655 //printf("getLanguageFromFileName(%s)=%x\n",qPrint(fi.extension()),*pVal);
5656 return it->second;
5657 }
5658 //printf("getLanguageFromFileName(%s) not found!\n",qPrint(fileName));
5659 return defLang; // not listed => assume C-ish language.
5660}
static std::unordered_map< std::string, SrcLangExt > g_extLookup
Definition util.cpp:5506

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

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

◆ getLanguageSpecificSeparator()

◆ getMemberFromSymbol()

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

Definition at line 5697 of file util.cpp.

5699{
5700 if (scope==nullptr ||
5703 )
5704 )
5705 {
5707 }
5708
5709 QCString name = n;
5710 if (name.isEmpty())
5711 return nullptr; // no name was given
5712
5713 auto &range = Doxygen::symbolMap->find(name);
5714 if (range.empty())
5715 return nullptr; // could not find any matching symbols
5716
5717 // mostly copied from getResolvedClassRec()
5718 QCString explicitScopePart;
5719 int qualifierIndex = computeQualifiedIndex(name);
5720 if (qualifierIndex!=-1)
5721 {
5722 explicitScopePart = name.left(qualifierIndex);
5723 replaceNamespaceAliases(explicitScopePart);
5724 name = name.mid(qualifierIndex+2);
5725 }
5726 //printf("explicitScopePart=%s\n",qPrint(explicitScopePart));
5727
5728 int minDistance = 10000;
5729 MemberDef *bestMatch = nullptr;
5730
5731 for (Definition *d : range)
5732 {
5733 if (d->definitionType()==Definition::TypeMember)
5734 {
5735 SymbolResolver resolver(fileScope);
5736 int distance = resolver.isAccessibleFromWithExpScope(scope,d,explicitScopePart);
5737 if (distance!=-1 && distance<minDistance)
5738 {
5739 minDistance = distance;
5740 bestMatch = toMemberDef(d);
5741 //printf("new best match %s distance=%d\n",qPrint(bestMatch->qualifiedName()),distance);
5742 }
5743 }
5744 }
5745 return bestMatch;
5746}
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:7248

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

4527{
4528 return theTranslator->trOverloadText();
4529 //"This is an overloaded member function, "
4530 // "provided for convenience. It differs from the above "
4531 // "function only in what argument(s) it accepts.";
4532}
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 3676 of file util.cpp.

3677{
3678 if (name.isEmpty()) return 0;
3679 const StringVector &sl = Config_getList(IGNORE_PREFIX);
3680 for (const auto &s : sl)
3681 {
3682 const char *ps=s.c_str();
3683 const char *pd=name.data();
3684 int i=0;
3685 while (*ps!=0 && *pd!=0 && *ps==*pd) ps++,pd++,i++;
3686 if (*ps==0 && *pd!=0)
3687 {
3688 return i;
3689 }
3690 }
3691 return 0;
3692}

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

7236{
7237 QCString projectCookie = Config_getString(HTML_PROJECT_COOKIE);
7238 if (projectCookie.isEmpty()) return QCString();
7239 uint8_t md5_sig[16];
7240 char sigStr[34];
7241 MD5Buffer(projectCookie.data(),static_cast<unsigned int>(projectCookie.length()),md5_sig);
7242 MD5SigToString(md5_sig,sigStr);
7243 sigStr[32]='_'; sigStr[33]=0;
7244 return sigStr;
7245}

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

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

◆ getScopeDefs()

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

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

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

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

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

Definition at line 2830 of file util.cpp.

2832{
2833 cd=nullptr;
2834 cnd=nullptr;
2835 nd=nullptr;
2836 modd=nullptr;
2837
2838 QCString scopeName=scope;
2839 //printf("getScopeDefs: docScope='%s' scope='%s'\n",qPrint(docScope),qPrint(scope));
2840 if (scopeName.isEmpty()) return FALSE;
2841
2842 bool explicitGlobalScope=FALSE;
2843 if (scopeName.at(0)==':' && scopeName.at(1)==':')
2844 {
2845 scopeName=scopeName.right(scopeName.length()-2);
2846 explicitGlobalScope=TRUE;
2847 }
2848 if (scopeName.isEmpty())
2849 {
2850 return FALSE;
2851 }
2852
2853 QCString docScopeName=docScope;
2854 int scopeOffset=explicitGlobalScope ? 0 : static_cast<int>(docScopeName.length());
2855
2856 do // for each possible docScope (from largest to and including empty)
2857 {
2858 QCString fullName=scopeName;
2859 if (scopeOffset>0) fullName.prepend(docScopeName.left(scopeOffset)+"::");
2860
2861 if (((cd=getClass(fullName)) || // normal class
2862 (cd=getClass(fullName+"-p")) // ObjC protocol
2863 ) && cd->isLinkable())
2864 {
2865 return TRUE; // class link written => quit
2866 }
2867 else if ((nd=Doxygen::namespaceLinkedMap->find(fullName)) && nd->isLinkable())
2868 {
2869 return TRUE; // namespace link written => quit
2870 }
2871 else if ((cnd=Doxygen::conceptLinkedMap->find(fullName)) && cnd->isLinkable())
2872 {
2873 return TRUE; // concept link written => quit
2874 }
2875 else if ((modd=ModuleManager::instance().modules().find(fullName)) && modd->isLinkable())
2876 {
2877 return TRUE; // module link written => quit
2878 }
2879 if (scopeOffset==0)
2880 {
2881 scopeOffset=-1;
2882 }
2883 else if ((scopeOffset=docScopeName.findRev("::",scopeOffset-1))==-1)
2884 {
2885 scopeOffset=0;
2886 }
2887 } while (scopeOffset>=0);
2888
2889 return FALSE;
2890}
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 5065 of file util.cpp.

5066{
5067 int sl=static_cast<int>(s.length());
5068 int sp=p;
5069 int count=0;
5070 bool done=false;
5071 if (sp>=sl) return -1;
5072 while (sp<sl)
5073 {
5074 char c=s.at(sp);
5075 if (c==':') sp++,p++; else break;
5076 }
5077 while (sp<sl)
5078 {
5079 char c=s.at(sp);
5080 switch (c)
5081 {
5082 case ':': // found next part
5083 goto found;
5084 case '<': // skip template specifier
5085 count=1;sp++;
5086 done=false;
5087 while (sp<sl && !done)
5088 {
5089 // TODO: deal with << and >> operators!
5090 c=s.at(sp++);
5091 switch(c)
5092 {
5093 case '<': count++; break;
5094 case '>': count--; if (count==0) done=true; break;
5095 default: break;
5096 }
5097 }
5098 break;
5099 default:
5100 sp++;
5101 break;
5102 }
5103 }
5104found:
5105 *l=sp-p;
5106 //printf("getScopeFragment(%s,%d)=%s\n",qPrint(s),p,qPrint(s.mid(p,*l)));
5107 return p;
5108}

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

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

◆ guessSection()

EntryType guessSection ( const QCString & name)

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

Definition at line 349 of file util.cpp.

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

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

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

◆ if() [1/2]

if ( ! insideString)

Definition at line 985 of file util.cpp.

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

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

◆ if() [2/2]

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

Definition at line 949 of file util.cpp.

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

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

Referenced by DocLink::DocLink().

◆ initDefaultExtensionMapping()

void initDefaultExtensionMapping ( )

Definition at line 5572 of file util.cpp.

5573{
5574 // NOTE: when adding an extension, also add the extension in config.xml
5575 // extension parser id
5576 updateLanguageMapping(".dox", "c");
5577 updateLanguageMapping(".txt", "c"); // see bug 760836
5578 updateLanguageMapping(".doc", "c");
5579 updateLanguageMapping(".c", "c");
5580 updateLanguageMapping(".C", "c");
5581 updateLanguageMapping(".cc", "c");
5582 updateLanguageMapping(".CC", "c");
5583 updateLanguageMapping(".cxx", "c");
5584 updateLanguageMapping(".cpp", "c");
5585 updateLanguageMapping(".c++", "c");
5586 updateLanguageMapping(".cxxm", "c"); // C++20 modules
5587 updateLanguageMapping(".cppm", "c"); // C++20 modules
5588 updateLanguageMapping(".ccm", "c"); // C++20 modules
5589 updateLanguageMapping(".c++m", "c"); // C++20 modules
5590 updateLanguageMapping(".ii", "c");
5591 updateLanguageMapping(".ixx", "c");
5592 updateLanguageMapping(".ipp", "c");
5593 updateLanguageMapping(".i++", "c");
5594 updateLanguageMapping(".inl", "c");
5595 updateLanguageMapping(".h", "c");
5596 updateLanguageMapping(".H", "c");
5597 updateLanguageMapping(".hh", "c");
5598 updateLanguageMapping(".HH", "c");
5599 updateLanguageMapping(".hxx", "c");
5600 updateLanguageMapping(".hpp", "c");
5601 updateLanguageMapping(".h++", "c");
5602 updateLanguageMapping(".idl", "idl");
5603 updateLanguageMapping(".ddl", "idl");
5604 updateLanguageMapping(".odl", "idl");
5605 updateLanguageMapping(".java", "java");
5606 //updateLanguageMapping(".as", "javascript"); // not officially supported
5607 //updateLanguageMapping(".js", "javascript"); // not officially supported
5608 updateLanguageMapping(".cs", "csharp");
5609 updateLanguageMapping(".d", "d");
5610 updateLanguageMapping(".php", "php");
5611 updateLanguageMapping(".php4", "php");
5612 updateLanguageMapping(".php5", "php");
5613 updateLanguageMapping(".inc", "php");
5614 updateLanguageMapping(".phtml", "php");
5615 updateLanguageMapping(".m", "objective-c");
5616 updateLanguageMapping(".M", "objective-c");
5617 updateLanguageMapping(".mm", "c"); // see bug746361
5618 updateLanguageMapping(".py", "python");
5619 updateLanguageMapping(".pyw", "python");
5620 updateLanguageMapping(".f", "fortran");
5621 updateLanguageMapping(".for", "fortran");
5622 updateLanguageMapping(".f90", "fortran");
5623 updateLanguageMapping(".f95", "fortran");
5624 updateLanguageMapping(".f03", "fortran");
5625 updateLanguageMapping(".f08", "fortran");
5626 updateLanguageMapping(".f18", "fortran");
5627 updateLanguageMapping(".vhd", "vhdl");
5628 updateLanguageMapping(".vhdl", "vhdl");
5629 updateLanguageMapping(".ucf", "vhdl");
5630 updateLanguageMapping(".qsf", "vhdl");
5631 updateLanguageMapping(".md", "md");
5632 updateLanguageMapping(".markdown", "md");
5633 updateLanguageMapping(".ice", "slice");
5634 updateLanguageMapping(".l", "lex");
5635 updateLanguageMapping(".doxygen_lex_c", "c"); // this is a placeholder so we can map initializations
5636 // in the lex scanning to cpp
5637}

References updateLanguageMapping().

Referenced by initDoxygen().

◆ inlineArgListToDoc()

QCString inlineArgListToDoc ( const ArgumentList & al)

Definition at line 1156 of file util.cpp.

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

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

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

◆ insertTemplateSpecifierInScope()

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

Definition at line 4186 of file util.cpp.

4187{
4188 QCString result=scope;
4189 if (!templ.isEmpty() && scope.find('<')==-1)
4190 {
4191 int si=0, pi=0;
4192 ClassDef *cd=nullptr;
4193 while (
4194 (si=scope.find("::",pi))!=-1 && !getClass(scope.left(si)+templ) &&
4195 ((cd=getClass(scope.left(si)))==nullptr || cd->templateArguments().empty())
4196 )
4197 {
4198 //printf("Tried '%s'\n",qPrint((scope.left(si)+templ)));
4199 pi=si+2;
4200 }
4201 if (si==-1) // not nested => append template specifier
4202 {
4203 result+=templ;
4204 }
4205 else // nested => insert template specifier before after first class name
4206 {
4207 result=scope.left(si) + templ + scope.right(scope.length()-si);
4208 }
4209 }
4210 //printf("insertTemplateSpecifierInScope('%s','%s')=%s\n",
4211 // qPrint(scope),qPrint(templ),qPrint(result));
4212 return result;
4213}
bool empty() const
Definition arguments.h:92
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 7106 of file util.cpp.

7107{
7108 QCString result;
7109 int residual = n;
7110
7111 char modVal[2];
7112 modVal[1] = 0;
7113 while (residual > 0)
7114 {
7115 modVal[0] = (upper ? 'A': 'a') + (residual-1)%26;
7116 result = modVal + result;
7117 residual = (residual-1) / 26;
7118 }
7119 return result;
7120}

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

◆ integerToRoman()

QCString integerToRoman ( int n,
bool upper )

Definition at line 7122 of file util.cpp.

7123{
7124 static const char *str_romans_upper[] = { "M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I" };
7125 static const char *str_romans_lower[] = { "m", "cm", "d", "cd", "c", "xc", "l", "xl", "x", "ix", "v", "iv", "i" };
7126 static const int values[] = { 1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1 };
7127 static const char **str_romans = upper ? str_romans_upper : str_romans_lower;
7128
7129 QCString result;
7130 int residual = n;
7131
7132 for (int i = 0; i < 13; ++i)
7133 {
7134 while (residual - values[i] >= 0)
7135 {
7136 result += str_romans[i];
7137 residual -= values[i];
7138 }
7139 }
7140
7141 return result;
7142}

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

◆ isLowerCase()

static bool isLowerCase ( QCString & s)
static

Definition at line 2892 of file util.cpp.

2893{
2894 if (s.isEmpty()) return true;
2895 const char *p=s.data();
2896 int c=0;
2897 while ((c=static_cast<uint8_t>(*p++))) if (!islower(c)) return false;
2898 return true;
2899}

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

6343{
6344 static const std::unordered_set<std::string> schemes = {
6345 "http", "https", "ftp", "ftps", "sftp", "file", "news", "irc", "ircs"
6346 };
6347 QCString loc_url = url.stripWhiteSpace();
6348 int colonPos = loc_url.find(':');
6349 return colonPos!=-1 && schemes.find(loc_url.left(colonPos).str())!=schemes.end();
6350}

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

7094{
7095 std::string result;
7096 bool first=true;
7097 for (const auto &s : sv)
7098 {
7099 if (!first) result+=delimiter;
7100 first=false;
7101 result+=s;
7102 }
7103 return result;
7104}

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

◆ keyWordsFortranC()

static bool keyWordsFortranC ( const char * contents)
static

Definition at line 6747 of file util.cpp.

6748{
6749 static const std::unordered_set<std::string> fortran_C_keywords = {
6750 "character", "call", "close", "common", "continue",
6751 "case", "contains", "cycle", "class", "codimension",
6752 "concurrent", "contiguous", "critical"
6753 };
6754
6755 if (*contents != 'c' && *contents != 'C') return false;
6756
6757 const char *c = contents;
6758 QCString keyword;
6759 while (*c && *c != ' ') {keyword += *c; c++;}
6760 keyword = keyword.lower();
6761
6762 return (fortran_C_keywords.find(keyword.str()) != fortran_C_keywords.end());
6763}

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

Referenced by recognizeFixedForm().

◆ langToString()

QCString langToString ( SrcLangExt lang)

Returns a string representation of lang.

Definition at line 6300 of file util.cpp.

6301{
6302 switch(lang)
6303 {
6304 case SrcLangExt::Unknown: return "Unknown";
6305 case SrcLangExt::IDL: return "IDL";
6306 case SrcLangExt::Java: return "Java";
6307 case SrcLangExt::CSharp: return "C#";
6308 case SrcLangExt::D: return "D";
6309 case SrcLangExt::PHP: return "PHP";
6310 case SrcLangExt::ObjC: return "Objective-C";
6311 case SrcLangExt::Cpp: return "C++";
6312 case SrcLangExt::JS: return "JavaScript";
6313 case SrcLangExt::Python: return "Python";
6314 case SrcLangExt::Fortran: return "Fortran";
6315 case SrcLangExt::VHDL: return "VHDL";
6316 case SrcLangExt::XML: return "XML";
6317 case SrcLangExt::SQL: return "SQL";
6318 case SrcLangExt::Markdown: return "Markdown";
6319 case SrcLangExt::Slice: return "Slice";
6320 case SrcLangExt::Lex: return "Lex";
6321 }
6322 return "Unknown";
6323}
@ Markdown
Definition types.h:57
@ Slice
Definition types.h:59

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

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

◆ leftScopeMatch()

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

Definition at line 892 of file util.cpp.

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

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

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

◆ lineBlock()

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

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

See also
routine extractBlock

Definition at line 6279 of file util.cpp.

6280{
6281 int result = 1;
6282
6283 // find the character positions of the first marker
6284 int m1 = text.find(marker);
6285 if (m1==-1) return result;
6286
6287 // find start line positions for the markers
6288 bool found=false;
6289 int p=0, i=0;
6290 while (!found && (i=text.find('\n',p))!=-1)
6291 {
6292 found = (p<=m1 && m1<i); // found the line with the start marker
6293 p=i+1;
6294 result++;
6295 }
6296 return result;
6297}

References QCString::find(), and found.

Referenced by readIncludeFile().

◆ linkifyText()

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

Definition at line 904 of file util.cpp.

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

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

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

◆ linkToText()

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

Definition at line 3159 of file util.cpp.

3160{
3161 //bool optimizeOutputJava = Config_getBool(OPTIMIZE_OUTPUT_JAVA);
3162 QCString result=link;
3163 if (!result.isEmpty())
3164 {
3165 // replace # by ::
3166 result=substitute(result,"#","::");
3167 // replace . by ::
3168 if (!isFileName && result.find('<')==-1) result=substitute(result,".","::",3);
3169 // strip leading :: prefix if present
3170 if (result.at(0)==':' && result.at(1)==':')
3171 {
3172 result=result.right(result.length()-2);
3173 }
3175 if (sep!="::")
3176 {
3177 result=substitute(result,"::",sep);
3178 }
3179 }
3180 //printf("linkToText(%s,lang=%d)=%s\n",qPrint(link),lang,qPrint(result));
3181 return result;
3182}
QCString getLanguageSpecificSeparator(SrcLangExt lang, bool classScope)
Returns the scope separator to use given the programming language lang.
Definition util.cpp:6326

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

6709{
6710 return Doxygen::mainPage!=nullptr && Doxygen::mainPage->hasTitle();
6711}
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 7337 of file util.cpp.

7338{
7339 int idx = name.find('<');
7340 if (idx!=-1)
7341 {
7342 return name.left(idx)+"-"+QCString().setNum(name.contains(",")+1)+"-g";
7343 }
7344 return name;
7345}
int contains(char c, bool cs=TRUE) const
Definition qcstring.cpp:143

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

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

◆ matchArgument2()

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

Definition at line 1865 of file util.cpp.

1870{
1871 AUTO_TRACE("src: scope={} type={} name={} canType={}, dst: scope={} type={} name={} canType={}",
1872 srcScope?srcScope->name():"",srcA.type,srcA.name,srcA.canType,
1873 dstScope?dstScope->name():"",dstA.type,dstA.name,dstA.canType);
1874 //printf(">> match argument: %s::'%s|%s' (%s) <-> %s::'%s|%s' (%s)\n",
1875 // srcScope ? qPrint(srcScope->name()) : "",
1876 // qPrint(srcA.type), qPrint(srcA.name), qPrint(srcA.canType),
1877 // dstScope ? qPrint(dstScope->name()) : "",
1878 // qPrint(dstA.type), qPrint(dstA.name), qPrint(dstA.canType));
1879
1880 QCString sSrcName = " "+srcA.name;
1881 QCString sDstName = " "+dstA.name;
1882 QCString srcType = srcA.type;
1883 QCString dstType = dstA.type;
1886 //printf("'%s'<->'%s'\n",qPrint(sSrcName),qPrint(dstType.right(sSrcName.length())));
1887 //printf("'%s'<->'%s'\n",qPrint(sDstName),qPrint(srcType.right(sDstName.length())));
1888 if (sSrcName==dstType.right(sSrcName.length()))
1889 { // case "unsigned int" <-> "unsigned int i"
1890 srcA.type+=sSrcName;
1891 srcA.name="";
1892 srcA.canType=""; // invalidate cached type value
1893 }
1894 else if (sDstName==srcType.right(sDstName.length()))
1895 { // case "unsigned int i" <-> "unsigned int"
1896 dstA.type+=sDstName;
1897 dstA.name="";
1898 dstA.canType=""; // invalidate cached type value
1899 }
1900
1901 {
1902 std::lock_guard lock(g_matchArgsMutex);
1903 if (srcA.canType.isEmpty() || dstA.canType.isEmpty())
1904 {
1905 // need to re-evaluate both see issue #8370
1906 srcA.canType = extractCanonicalArgType(srcScope,srcFileScope,srcA,lang);
1907 dstA.canType = extractCanonicalArgType(dstScope,dstFileScope,dstA,lang);
1908 }
1909 }
1910
1911 if (matchCanonicalTypes(srcScope,srcFileScope,srcA.canType,
1912 dstScope,dstFileScope,dstA.canType,
1913 lang))
1914 {
1915 MATCH
1916 AUTO_TRACE_EXIT("true");
1917 return TRUE;
1918 }
1919 else
1920 {
1921 //printf(" Canonical types do not match [%s]<->[%s]\n",
1922 // qPrint(srcA->canType),qPrint(dstA->canType));
1923 NOMATCH
1924 AUTO_TRACE_EXIT("false");
1925 return FALSE;
1926 }
1927}
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:1833
#define MATCH
Definition util.cpp:1826
static QCString extractCanonicalArgType(const Definition *d, const FileDef *fs, const Argument &arg, SrcLangExt lang)
Definition util.cpp:1800
#define NOMATCH
Definition util.cpp:1827
static std::mutex g_matchArgsMutex
Definition util.cpp:1823

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

1934{
1935 ASSERT(srcScope!=nullptr && dstScope!=nullptr);
1936
1937 AUTO_TRACE("srcScope='{}' dstScope='{}' srcArgs='{}' dstArgs='{}' checkCV={} lang={}",
1938 srcScope->name(),dstScope->name(),srcAl?argListToString(*srcAl):"",dstAl?argListToString(*dstAl):"",checkCV,lang);
1939
1940 if (srcAl==nullptr || dstAl==nullptr)
1941 {
1942 bool match = srcAl==dstAl;
1943 if (match)
1944 {
1945 MATCH
1946 return TRUE;
1947 }
1948 else
1949 {
1950 NOMATCH
1951 return FALSE;
1952 }
1953 }
1954
1955 // handle special case with void argument
1956 if ( srcAl->empty() && dstAl->size()==1 && dstAl->front().type=="void" )
1957 { // special case for finding match between func() and func(void)
1958 Argument a;
1959 a.type = "void";
1960 const_cast<ArgumentList*>(srcAl)->push_back(a);
1961 MATCH
1962 return TRUE;
1963 }
1964 if ( dstAl->empty() && srcAl->size()==1 && srcAl->front().type=="void" )
1965 { // special case for finding match between func(void) and func()
1966 Argument a;
1967 a.type = "void";
1968 const_cast<ArgumentList*>(dstAl)->push_back(a);
1969 MATCH
1970 return TRUE;
1971 }
1972
1973 if (srcAl->size() != dstAl->size())
1974 {
1975 NOMATCH
1976 return FALSE; // different number of arguments -> no match
1977 }
1978
1979 if (checkCV)
1980 {
1981 if (srcAl->constSpecifier() != dstAl->constSpecifier())
1982 {
1983 NOMATCH
1984 return FALSE; // one member is const, the other not -> no match
1985 }
1986 if (srcAl->volatileSpecifier() != dstAl->volatileSpecifier())
1987 {
1988 NOMATCH
1989 return FALSE; // one member is volatile, the other not -> no match
1990 }
1991 }
1992
1993 if (srcAl->refQualifier() != dstAl->refQualifier())
1994 {
1995 NOMATCH
1996 return FALSE; // one member is has a different ref-qualifier than the other
1997 }
1998
1999 // so far the argument list could match, so we need to compare the types of
2000 // all arguments.
2001 auto srcIt = srcAl->begin();
2002 auto dstIt = dstAl->begin();
2003 for (;srcIt!=srcAl->end() && dstIt!=dstAl->end();++srcIt,++dstIt)
2004 {
2005 Argument &srcA = const_cast<Argument&>(*srcIt);
2006 Argument &dstA = const_cast<Argument&>(*dstIt);
2007 if (!matchArgument2(srcScope,srcFileScope,srcA,
2008 dstScope,dstFileScope,dstA,
2009 lang)
2010 )
2011 {
2012 NOMATCH
2013 return FALSE;
2014 }
2015 }
2016 MATCH
2017 return TRUE; // all arguments match
2018}
Argument & front()
Definition arguments.h:98
size_t size() const
Definition arguments.h:93
QCString argListToString(const ArgumentList &al, bool useCanonicalType, bool showDefVals)
Definition util.cpp:1174
static bool matchArgument2(const Definition *srcScope, const FileDef *srcFileScope, Argument &srcA, const Definition *dstScope, const FileDef *dstFileScope, Argument &dstA, SrcLangExt lang)
Definition util.cpp:1865

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

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

◆ matchCanonicalTypes()

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

Definition at line 1833 of file util.cpp.

1837{
1838 AUTO_TRACE("srcType='{}' dstType='{}'",srcType,dstType);
1839 if (srcType==dstType) return true;
1840
1841 // check if the types are function pointers
1842 int i1=srcType.find(")(");
1843 if (i1==-1) return false;
1844 int i2=dstType.find(")(");
1845 if (i1!=i2) return false;
1846
1847 // check if the result part of the function pointer types matches
1848 int j1=srcType.find("(");
1849 if (j1==-1 || j1>i1) return false;
1850 int j2=dstType.find("(");
1851 if (j2!=j1) return false;
1852 if (srcType.left(j1)!=dstType.left(j2)) return false; // different return types
1853
1854 // if srcType and dstType are both function pointers with the same return type,
1855 // then match against the parameter lists.
1856 // This way srcType='void (*fptr)(int x)' will match against `void (*fptr)(int y)' because
1857 // 'int x' matches 'int y'. A simple literal string match would treat these as different.
1858 auto srcAl = stringToArgumentList(lang,srcType.mid(i1+1));
1859 auto dstAl = stringToArgumentList(lang,dstType.mid(i2+1));
1860 return matchArguments2(srcScope,srcFileScope,srcAl.get(),
1861 dstScope,dstFileScope,dstAl.get(),
1862 true,lang);
1863}

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

Referenced by matchArgument2().

◆ mergeArguments()

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

Definition at line 2025 of file util.cpp.

2026{
2027 AUTO_TRACE("srcAl='{}',dstAl='{}',forceNameOverwrite={}",
2028 qPrint(argListToString(srcAl)),qPrint(argListToString(dstAl)),forceNameOverwrite);
2029
2030 if (srcAl.size()!=dstAl.size())
2031 {
2032 return; // invalid argument lists -> do not merge
2033 }
2034
2035 auto srcIt=srcAl.begin();
2036 auto dstIt=dstAl.begin();
2037 while (srcIt!=srcAl.end() && dstIt!=dstAl.end())
2038 {
2039 Argument &srcA = *srcIt;
2040 Argument &dstA = *dstIt;
2041
2042 AUTO_TRACE_ADD("before merge: src=[type='{}',name='{}',def='{}'] dst=[type='{}',name='{}',def='{}']",
2043 srcA.type,srcA.name,srcA.defval,
2044 dstA.type,dstA.name,dstA.defval);
2045 if (srcA.defval.isEmpty() && !dstA.defval.isEmpty())
2046 {
2047 //printf("Defval changing '%s'->'%s'\n",qPrint(srcA.defval),qPrint(dstA.defval));
2048 srcA.defval=dstA.defval;
2049 }
2050 else if (!srcA.defval.isEmpty() && dstA.defval.isEmpty())
2051 {
2052 //printf("Defval changing '%s'->'%s'\n",qPrint(dstA.defval),qPrint(srcA.defval));
2053 dstA.defval=srcA.defval;
2054 }
2055
2056 // fix wrongly detected const or volatile specifiers before merging.
2057 // example: "const A *const" is detected as type="const A *" name="const"
2058 if (srcA.name=="const" || srcA.name=="volatile")
2059 {
2060 srcA.type+=" "+srcA.name;
2061 srcA.name.clear();
2062 }
2063 if (dstA.name=="const" || dstA.name=="volatile")
2064 {
2065 dstA.type+=" "+dstA.name;
2066 dstA.name.clear();
2067 }
2068
2069 if (srcA.type==dstA.type)
2070 {
2071 //printf("1. merging %s:%s <-> %s:%s\n",qPrint(srcA.type),qPrint(srcA.name),qPrint(dstA.type),qPrint(dstA.name));
2072 if (srcA.name.isEmpty() && !dstA.name.isEmpty())
2073 {
2074 //printf("type: '%s':='%s'\n",qPrint(srcA.type),qPrint(dstA.type));
2075 //printf("name: '%s':='%s'\n",qPrint(srcA.name),qPrint(dstA.name));
2076 srcA.type = dstA.type;
2077 srcA.name = dstA.name;
2078 }
2079 else if (!srcA.name.isEmpty() && dstA.name.isEmpty())
2080 {
2081 //printf("type: '%s':='%s'\n",qPrint(dstA.type),qPrint(srcA.type));
2082 //printf("name: '%s':='%s'\n",qPrint(dstA.name),qPrint(srcA.name));
2083 dstA.type = srcA.type;
2084 dstA.name = srcA.name;
2085 }
2086 else if (!srcA.name.isEmpty() && !dstA.name.isEmpty())
2087 {
2088 //printf("srcA.name=%s dstA.name=%s\n",qPrint(srcA.name),qPrint(dstA.name));
2089 if (forceNameOverwrite)
2090 {
2091 srcA.name = dstA.name;
2092 }
2093 else
2094 {
2095 if (srcA.docs.isEmpty() && !dstA.docs.isEmpty())
2096 {
2097 srcA.name = dstA.name;
2098 }
2099 else if (!srcA.docs.isEmpty() && dstA.docs.isEmpty())
2100 {
2101 dstA.name = srcA.name;
2102 }
2103 }
2104 }
2105 }
2106 else
2107 {
2108 //printf("2. merging '%s':'%s' <-> '%s':'%s'\n",qPrint(srcA.type),qPrint(srcA.name),qPrint(dstA.type),qPrint(dstA.name));
2109 srcA.type=srcA.type.stripWhiteSpace();
2110 dstA.type=dstA.type.stripWhiteSpace();
2111 if (srcA.type+" "+srcA.name==dstA.type) // "unsigned long:int" <-> "unsigned long int:bla"
2112 {
2113 srcA.type+=" "+srcA.name;
2114 srcA.name=dstA.name;
2115 }
2116 else if (dstA.type+" "+dstA.name==srcA.type) // "unsigned long int bla" <-> "unsigned long int"
2117 {
2118 dstA.type+=" "+dstA.name;
2119 dstA.name=srcA.name;
2120 }
2121 else if (srcA.name.isEmpty() && !dstA.name.isEmpty())
2122 {
2123 srcA.name = dstA.name;
2124 }
2125 else if (dstA.name.isEmpty() && !srcA.name.isEmpty())
2126 {
2127 dstA.name = srcA.name;
2128 }
2129 }
2130 int i1=srcA.type.find("::"),
2131 i2=dstA.type.find("::"),
2132 j1=static_cast<int>(srcA.type.length())-i1-2,
2133 j2=static_cast<int>(dstA.type.length())-i2-2;
2134 if (i1!=-1 && i2==-1 && srcA.type.right(j1)==dstA.type)
2135 {
2136 //printf("type: '%s':='%s'\n",qPrint(dstA.type),qPrint(srcA.type));
2137 //printf("name: '%s':='%s'\n",qPrint(dstA.name),qPrint(srcA.name));
2138 dstA.type = srcA.type.left(i1+2)+dstA.type;
2139 dstA.name = srcA.name;
2140 }
2141 else if (i1==-1 && i2!=-1 && dstA.type.right(j2)==srcA.type)
2142 {
2143 //printf("type: '%s':='%s'\n",qPrint(srcA.type),qPrint(dstA.type));
2144 //printf("name: '%s':='%s'\n",qPrint(dstA.name),qPrint(srcA.name));
2145 srcA.type = dstA.type.left(i2+2)+srcA.type;
2146 srcA.name = dstA.name;
2147 }
2148 if (srcA.docs.isEmpty() && !dstA.docs.isEmpty())
2149 {
2150 srcA.docs = dstA.docs;
2151 }
2152 else if (dstA.docs.isEmpty() && !srcA.docs.isEmpty())
2153 {
2154 dstA.docs = srcA.docs;
2155 }
2156 //printf("Merge argument '%s|%s' '%s|%s'\n",
2157 // qPrint(srcA.type), qPrint(srcA.name),
2158 // qPrint(dstA.type), qPrint(dstA.name));
2159 ++srcIt;
2160 ++dstIt;
2161 AUTO_TRACE_ADD("after merge: src=[type='{}',name='{}',def='{}'] dst=[type='{}',name='{}',def='{}']",
2162 srcA.type,srcA.name,srcA.defval,
2163 dstA.type,dstA.name,dstA.defval);
2164 }
2165}
QCString docs
Definition arguments.h:42

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

7286{
7287 if (Config_getBool(CALL_GRAPH) !=md1->hasCallGraph()) md2->overrideCallGraph(md1->hasCallGraph());
7288 if (Config_getBool(CALLER_GRAPH)!=md1->hasCallerGraph()) md2->overrideCallerGraph(md1->hasCallerGraph());
7289 if (Config_getBool(CALL_GRAPH) !=md2->hasCallGraph()) md1->overrideCallGraph( md2->hasCallGraph());
7290 if (Config_getBool(CALLER_GRAPH)!=md2->hasCallerGraph()) md1->overrideCallerGraph(md2->hasCallerGraph());
7291
7292 if (Config_getBool(SHOW_ENUM_VALUES) !=md1->hasEnumValues()) md2->overrideEnumValues(md1->hasEnumValues());
7293 if (Config_getBool(SHOW_ENUM_VALUES) !=md2->hasEnumValues()) md1->overrideEnumValues( md2->hasEnumValues());
7294
7295 if (Config_getBool(REFERENCED_BY_RELATION)!=md1->hasReferencedByRelation()) md2->overrideReferencedByRelation(md1->hasReferencedByRelation());
7296 if (Config_getBool(REFERENCES_RELATION) !=md1->hasReferencesRelation()) md2->overrideReferencesRelation(md1->hasReferencesRelation());
7297 if (Config_getBool(REFERENCED_BY_RELATION)!=md2->hasReferencedByRelation()) md1->overrideReferencedByRelation(md2->hasReferencedByRelation());
7298 if (Config_getBool(REFERENCES_RELATION) !=md2->hasReferencesRelation()) md1->overrideReferencesRelation(md2->hasReferencesRelation());
7299
7300 if (Config_getBool(INLINE_SOURCES)!=md1->hasInlineSource()) md2->overrideInlineSource(md1->hasInlineSource());
7301 if (Config_getBool(INLINE_SOURCES)!=md2->hasInlineSource()) md1->overrideInlineSource(md2->hasInlineSource());
7302}
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 5020 of file util.cpp.

5021{
5022 AUTO_TRACE("leftScope='{}' rightScope='{}'",leftScope,rightScope);
5023 // case leftScope=="A" rightScope=="A::B" => result = "A::B"
5024 if (leftScopeMatch(leftScope,rightScope))
5025 {
5026 AUTO_TRACE_EXIT("case1={}",rightScope);
5027 return rightScope;
5028 }
5029 QCString result;
5030 int i=0,p=static_cast<int>(leftScope.length());
5031
5032 // case leftScope=="A::B" rightScope=="B::C" => result = "A::B::C"
5033 // case leftScope=="A::B" rightScope=="B" => result = "A::B"
5034 bool found=FALSE;
5035 while ((i=leftScope.findRev("::",p))>0)
5036 {
5037 if (leftScopeMatch(rightScope,leftScope.right(leftScope.length()-i-2)))
5038 {
5039 result = leftScope.left(i+2)+rightScope;
5040 found=TRUE;
5041 }
5042 p=i-1;
5043 }
5044 if (found)
5045 {
5046 AUTO_TRACE_EXIT("case2={}",result);
5047 return result;
5048 }
5049
5050 // case leftScope=="A" rightScope=="B" => result = "A::B"
5051 result=leftScope;
5052 if (!result.isEmpty() && !rightScope.isEmpty()) result+="::";
5053 result+=rightScope;
5054 AUTO_TRACE_EXIT("case3={}",result);
5055 return result;
5056}
bool leftScopeMatch(const QCString &scope, const QCString &name)
Definition util.cpp:892

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

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

◆ nextUTF8CharPosition()

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

Definition at line 5759 of file util.cpp.

5760{
5761 if (startPos>=len) return len;
5762 uint8_t c = static_cast<uint8_t>(utf8Str[startPos]);
5763 int bytes=getUTF8CharNumBytes(c);
5764 if (c=='&') // skip over character entities
5765 {
5766 bytes=1;
5767 int (*matcher)(int) = nullptr;
5768 c = static_cast<uint8_t>(utf8Str[startPos+bytes]);
5769 if (c=='#') // numerical entity?
5770 {
5771 bytes++;
5772 c = static_cast<uint8_t>(utf8Str[startPos+bytes]);
5773 if (c=='x') // hexadecimal entity?
5774 {
5775 bytes++;
5776 matcher = std::isxdigit;
5777 }
5778 else // decimal entity
5779 {
5780 matcher = std::isdigit;
5781 }
5782 }
5783 else if (std::isalnum(c)) // named entity?
5784 {
5785 bytes++;
5786 matcher = std::isalnum;
5787 }
5788 if (matcher)
5789 {
5790 while ((c = static_cast<uint8_t>(utf8Str[startPos+bytes]))!=0 && matcher(c))
5791 {
5792 bytes++;
5793 }
5794 }
5795 if (c!=';')
5796 {
5797 bytes=1; // not a valid entity, reset bytes counter
5798 }
5799 }
5800 return startPos+bytes;
5801}

References getUTF8CharNumBytes().

Referenced by parseCommentAsText().

◆ normalizeNonTemplateArgumentsInString()

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

Definition at line 4726 of file util.cpp.

4730{
4731 // skip until <
4732 int p=name.find('<');
4733 if (p==-1) return name;
4734 p++;
4735 QCString result = name.left(p);
4736
4737 std::string s = name.mid(p).str();
4738 static const reg::Ex re(R"([\a:][\w:]*)");
4739 reg::Iterator it(s,re);
4741 size_t pi=0;
4742 // for each identifier in the template part (e.g. B<T> -> T)
4743 for (; it!=end ; ++it)
4744 {
4745 const auto &match = *it;
4746 size_t i = match.position();
4747 size_t l = match.length();
4748 result += s.substr(pi,i-pi);
4749 QCString n(match.str());
4750 bool found=FALSE;
4751 for (const Argument &formArg : formalArgs)
4752 {
4753 if (formArg.name == n)
4754 {
4755 found=TRUE;
4756 break;
4757 }
4758 }
4759 if (!found)
4760 {
4761 // try to resolve the type
4762 SymbolResolver resolver;
4763 const ClassDef *cd = resolver.resolveClass(context,n);
4764 if (cd)
4765 {
4766 result+=cd->name();
4767 }
4768 else
4769 {
4770 result+=n;
4771 }
4772 }
4773 else
4774 {
4775 result+=n;
4776 }
4777 pi=i+l;
4778 }
4779 result+=s.substr(pi);
4780 //printf("normalizeNonTemplateArgumentInString(%s)=%s\n",qPrint(name),qPrint(result));
4781 return removeRedundantWhiteSpace(result);
4782}

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

Referenced by findUsedClassesForClass().

◆ openOutputFile()

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

Definition at line 6720 of file util.cpp.

6721{
6722 assert(!f.is_open());
6723 bool fileOpened=FALSE;
6724 bool writeToStdout=outFile=="-";
6725 if (writeToStdout) // write to stdout
6726 {
6727 f.basic_ios<char>::rdbuf(std::cout.rdbuf());
6728 fileOpened = true;
6729 }
6730 else // write to file
6731 {
6732 FileInfo fi(outFile.str());
6733 if (fi.exists()) // create a backup
6734 {
6735 Dir dir;
6736 FileInfo backup(fi.filePath()+".bak");
6737 if (backup.exists()) // remove existing backup
6738 dir.remove(backup.filePath());
6739 dir.rename(fi.filePath(),fi.filePath()+".bak");
6740 }
6741 f = Portable::openOutputStream(outFile);
6742 fileOpened = f.is_open();
6743 }
6744 return fileOpened;
6745}
bool remove(const std::string &path, bool acceptsAbsPath=true) const
Definition dir.cpp:314
bool rename(const std::string &orgName, const std::string &newName, bool acceptsAbsPath=true) const
Definition dir.cpp:321
std::ofstream openOutputStream(const QCString &name, bool append=false)
Definition portable.cpp:665

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

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

◆ parseCommentAsText()

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

Definition at line 5803 of file util.cpp.

5805{
5806 if (doc.isEmpty()) return "";
5807 //printf("parseCommentAsText(%s)\n",qPrint(doc));
5808 TextStream t;
5809 auto parser { createDocParser() };
5810 auto ast { validatingParseDoc(*parser.get(),
5811 fileName,lineNr,
5812 scope,md,doc,FALSE,FALSE,
5813 QCString(),FALSE,FALSE,Config_getBool(MARKDOWN_SUPPORT)) };
5814 auto astImpl = dynamic_cast<const DocNodeAST*>(ast.get());
5815 if (astImpl)
5816 {
5817 TextDocVisitor visitor(t);
5818 std::visit(visitor,astImpl->root);
5819 }
5820 QCString result = convertCharEntitiesToUTF8(t.str().c_str()).stripWhiteSpace();
5821 int i=0;
5822 int charCnt=0;
5823 int l=static_cast<int>(result.length());
5824 while ((i=nextUTF8CharPosition(result,l,i))<l)
5825 {
5826 charCnt++;
5827 if (charCnt>=80) break;
5828 }
5829 if (charCnt>=80) // try to truncate the string
5830 {
5831 while ((i=nextUTF8CharPosition(result,l,i))<l && charCnt<100)
5832 {
5833 charCnt++;
5834 if (result.at(i)==',' ||
5835 result.at(i)=='.' ||
5836 result.at(i)=='!' ||
5837 result.at(i)=='?' ||
5838 result.at(i)=='}') // good for UTF-16 characters and } otherwise also a good point to stop the string
5839 {
5840 i++; // we want to be "behind" last inspected character
5841 break;
5842 }
5843 }
5844 }
5845 if ( i < l) result=result.left(i)+"...";
5846 return result.data();
5847}
Class representing the abstract syntax tree of a documentation block.
Definition docnode.h:1460
Concrete visitor implementation for TEXT output.
Text streaming class that buffers data.
Definition textstream.h:36
std::string str() const
Return the contents of the buffer as a std::string object.
Definition textstream.h:229
IDocParserPtr createDocParser()
factory function to create a parser
Definition docparser.cpp:54
IDocNodeASTPtr validatingParseDoc(IDocParser &parserIntf, const QCString &fileName, int startLine, const Definition *ctx, const MemberDef *md, const QCString &input, bool indexWords, bool isExample, const QCString &exampleName, bool singleLine, bool linkFromIndex, bool markdownSupport)
static int nextUTF8CharPosition(const QCString &utf8Str, uint32_t len, uint32_t startPos)
Definition util.cpp:5759

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

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

◆ patternMatch()

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

Definition at line 6097 of file util.cpp.

6098{
6099 std::string elem;
6100 auto getter = [](std::string s) { return QCString(s); };
6101 return genericPatternMatch(fi,patList,elem,getter);
6102}

References genericPatternMatch().

Referenced by checkAndOpenFile(), and readDir().

◆ projectLogoFile()

QCString projectLogoFile ( )

Definition at line 3581 of file util.cpp.

3582{
3583 QCString projectLogo = Config_getString(PROJECT_LOGO);
3584 if (!projectLogo.isEmpty())
3585 {
3586 // check for optional width= and height= specifier
3587 int wi = projectLogo.find(" width=");
3588 if (wi!=-1) // and strip them
3589 {
3590 projectLogo = projectLogo.left(wi);
3591 }
3592 int hi = projectLogo.find(" height=");
3593 if (hi!=-1)
3594 {
3595 projectLogo = projectLogo.left(hi);
3596 }
3597 }
3598 //printf("projectlogo='%s'\n",qPrint(projectLogo));
3599 return projectLogo;
3600}

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

Referenced by copyLogo(), and substituteKeywords().

◆ projectLogoSize()

static QCString projectLogoSize ( )
static

Definition at line 3602 of file util.cpp.

3603{
3604 QCString sizeVal;
3605 QCString projectLogo = Config_getString(PROJECT_LOGO);
3606 if (!projectLogo.isEmpty())
3607 {
3608 auto extractDimension = [&projectLogo](const char *startMarker,size_t startPos,size_t endPos) -> QCString
3609 {
3610 QCString result = projectLogo.mid(startPos,endPos-startPos).stripWhiteSpace().quoted();
3611 if (result.length()>=2 && result.at(0)!='"' && result.at(result.length()-1)!='"')
3612 {
3613 result="\""+result+"\"";
3614 }
3615 result.prepend(startMarker);
3616 return result;
3617 };
3618 // check for optional width= and height= specifier
3619 int wi = projectLogo.find(" width=");
3620 int hi = projectLogo.find(" height=");
3621 if (wi!=-1 && hi!=-1)
3622 {
3623 if (wi<hi) // "... width=x height=y..."
3624 {
3625 sizeVal = extractDimension(" width=", wi+7, hi) + " "
3626 + extractDimension(" height=", hi+8, projectLogo.length());
3627 }
3628 else // "... height=y width=x..."
3629 {
3630 sizeVal = extractDimension(" height=", hi+8, wi) + " "
3631 + extractDimension(" width=", wi+7, projectLogo.length());
3632 }
3633 }
3634 else if (wi!=-1) // ... width=x..."
3635 {
3636 sizeVal = extractDimension(" width=", wi+7, projectLogo.length());
3637 }
3638 else if (hi!=-1) // ... height=x..."
3639 {
3640 sizeVal = extractDimension(" height=", hi+8, projectLogo.length());
3641 }
3642 }
3643 //printf("projectsize='%s'\n",qPrint(sizeVal));
3644 return sizeVal;
3645}
QCString quoted() const
Definition qcstring.h:260

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

Referenced by substituteKeywords().

◆ protectionLevelVisible()

◆ readInputFile()

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

read a file name fileName and optionally filter and transcode it

Definition at line 5937 of file util.cpp.

5938{
5939 // try to open file
5940 FileInfo fi(fileName.str());
5941 if (!fi.exists()) return FALSE;
5942 QCString filterName = getFileFilter(fileName,isSourceCode);
5943 if (filterName.isEmpty() || !filter)
5944 {
5945 std::ifstream f = Portable::openInputStream(fileName,true);
5946 if (!f.is_open())
5947 {
5948 err("could not open file {}\n",fileName);
5949 return FALSE;
5950 }
5951 // read the file
5952 auto fileSize = fi.size();
5953 contents.resize(fileSize);
5954 f.read(contents.data(),fileSize);
5955 if (f.fail())
5956 {
5957 err("problems while reading file {}\n",fileName);
5958 return FALSE;
5959 }
5960 }
5961 else
5962 {
5963 QCString cmd=filterName+" \""+fileName+"\"";
5964 Debug::print(Debug::ExtCmd,0,"Executing popen(`{}`)\n",cmd);
5965 FILE *f=Portable::popen(cmd,"r");
5966 if (!f)
5967 {
5968 err("could not execute filter {}\n",filterName);
5969 return FALSE;
5970 }
5971 const int bufSize=4096;
5972 char buf[bufSize];
5973 int numRead = 0;
5974 while ((numRead=static_cast<int>(fread(buf,1,bufSize,f)))>0)
5975 {
5976 //printf(">>>>>>>>Reading %d bytes\n",numRead);
5977 contents.append(buf,numRead);
5978 }
5980 Debug::print(Debug::FilterOutput, 0, "Filter output\n");
5981 Debug::print(Debug::FilterOutput,0,"-------------\n{}\n-------------\n",contents);
5982 }
5983
5984 if (contents.size()>=2 &&
5985 static_cast<uint8_t>(contents[0])==0xFF &&
5986 static_cast<uint8_t>(contents[1])==0xFE // Little endian BOM
5987 ) // UCS-2LE encoded file
5988 {
5989 transcodeCharacterBuffer(fileName,contents,"UCS-2LE","UTF-8");
5990 }
5991 else if (contents.size()>=2 &&
5992 static_cast<uint8_t>(contents[0])==0xFE &&
5993 static_cast<uint8_t>(contents[1])==0xFF // big endian BOM
5994 ) // UCS-2BE encoded file
5995 {
5996 transcodeCharacterBuffer(fileName,contents,"UCS-2BE","UTF-8");
5997 }
5998 else if (contents.size()>=3 &&
5999 static_cast<uint8_t>(contents[0])==0xEF &&
6000 static_cast<uint8_t>(contents[1])==0xBB &&
6001 static_cast<uint8_t>(contents[2])==0xBF
6002 ) // UTF-8 encoded file
6003 {
6004 contents.erase(0,3); // remove UTF-8 BOM: no translation needed
6005 }
6006 else // transcode according to the INPUT_ENCODING setting
6007 {
6008 // do character transcoding if needed.
6009 transcodeCharacterBuffer(fileName,contents,getEncoding(fi),"UTF-8");
6010 }
6011
6012 filterCRLF(contents);
6013 return true;
6014}
@ FilterOutput
Definition debug.h:38
@ ExtCmd
Definition debug.h:36
static void print(DebugMask mask, int prio, fmt::format_string< Args... > fmt, Args &&... args)
Definition debug.h:76
std::ifstream openInputStream(const QCString &name, bool binary=false, bool openAtEnd=false)
Definition portable.cpp:676
FILE * popen(const QCString &name, const QCString &type)
Definition portable.cpp:496
int pclose(FILE *stream)
Definition portable.cpp:505
static void filterCRLF(std::string &contents)
Definition util.cpp:1275
static void transcodeCharacterBuffer(const QCString &fileName, std::string &contents, const QCString &inputEncoding, const QCString &outputEncoding)
Definition util.cpp:5901
QCString getEncoding(const FileInfo &fi)
Definition util.cpp:6104
QCString getFileFilter(const QCString &name, bool isSourceCode)
Definition util.cpp:1342

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

6768{
6769 int column=0;
6770 bool skipLine=FALSE;
6771
6772 if (format == FortranFormat::Fixed) return TRUE;
6773 if (format == FortranFormat::Free) return FALSE;
6774
6775 int tabSize=Config_getInt(TAB_SIZE);
6776 size_t sizCont = contents.length();
6777 for (size_t i=0;i<sizCont;i++)
6778 {
6779 column++;
6780
6781 switch(contents.at(i))
6782 {
6783 case '\n':
6784 column=0;
6785 skipLine=FALSE;
6786 break;
6787 case '\t':
6788 column += tabSize-1;
6789 break;
6790 case ' ':
6791 break;
6792 case '\000':
6793 return FALSE;
6794 case '#':
6795 skipLine=TRUE;
6796 break;
6797 case 'C':
6798 case 'c':
6799 if (column==1)
6800 {
6801 return !keyWordsFortranC(contents.data()+i);
6802 }
6803 // fallthrough
6804 case '*':
6805 if (column==1) return TRUE;
6806 if (skipLine) break;
6807 return FALSE;
6808 case '!':
6809 if (column!=6) skipLine=TRUE;
6810 break;
6811 default:
6812 if (skipLine) break;
6813 if (column>=7) return TRUE;
6814 return FALSE;
6815 }
6816 }
6817 return FALSE;
6818}
static bool keyWordsFortranC(const char *contents)
Definition util.cpp:6747

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

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

◆ recursivelyAddGroupListToTitle()

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

Definition at line 5290 of file util.cpp.

5291{
5292 ModuleDef *mod = root ? findModuleDef(d) : nullptr;
5293 if (!d->partOfGroups().empty() || mod!=nullptr) // write list of group to which this definition belongs
5294 {
5295 if (root)
5296 {
5297 ol.pushGeneratorState();
5299 ol.writeString("<div class=\"ingroups\">");
5300 }
5301 bool first=true;
5302 for (const auto &gd : d->partOfGroups())
5303 {
5304 if (!first) { ol.writeString(" &#124; "); } else first=false;
5306 {
5307 ol.writeString(" &raquo; ");
5308 }
5309 ol.writeObjectLink(gd->getReference(),gd->getOutputFileBase(),QCString(),gd->groupTitle());
5310 }
5311 if (root)
5312 {
5313 // add module as a group to the file as well
5314 if (mod)
5315 {
5316 if (!first) { ol.writeString(" &#124; "); } else first=false;
5317 ol.writeString(theTranslator->trModule(false,true)+" ");
5319 mod->displayName());
5320 }
5321 ol.writeString("</div>");
5322 ol.popGeneratorState();
5323 }
5324 return true;
5325 }
5326 return false;
5327}
virtual const GroupList & partOfGroups() const =0
virtual QCString displayName(bool includeScope=TRUE) const =0
void writeString(const QCString &text)
Definition outputlist.h:412
void pushGeneratorState()
void disableAllBut(OutputType o)
void popGeneratorState()
static ModuleDef * findModuleDef(const Definition *d)
Definition util.cpp:5261

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

4020{
4021 QCString result;
4022 if (Config_getBool(CREATE_SUBDIRS))
4023 {
4024 if (name.isEmpty())
4025 {
4026 return REL_PATH_TO_ROOT;
4027 }
4028 else
4029 {
4030 int i = name.findRev('/');
4031 if (i!=-1)
4032 {
4033 result=REL_PATH_TO_ROOT;
4034 }
4035 }
4036 }
4037 return result;
4038}
#define REL_PATH_TO_ROOT
Definition util.cpp:95

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

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

◆ removeAnonymousScopes()

QCString removeAnonymousScopes ( const QCString & str)

Removes all anonymous scopes from string s Possible examples:

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

Definition at line 172 of file util.cpp.

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

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

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

◆ removeEmptyLines()

QCString removeEmptyLines ( const QCString & s)

Definition at line 7010 of file util.cpp.

7011{
7012 std::string out;
7013 out.reserve(s.length());
7014 const char *p=s.data();
7015 if (p)
7016 {
7017 char c = 0;
7018 while ((c=*p++))
7019 {
7020 if (c=='\n')
7021 {
7022 const char *e = p;
7023 while (*e==' ' || *e=='\t') e++;
7024 if (*e=='\n')
7025 {
7026 p=e;
7027 }
7028 else out+=c;
7029 }
7030 else
7031 {
7032 out+=c;
7033 }
7034 }
7035 }
7036 //printf("removeEmptyLines(%s)=%s\n",qPrint(s),qPrint(out));
7037 return out;
7038}

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

Referenced by substituteHtmlKeywords(), and substituteLatexKeywords().

◆ removeLongPathMarker()

QCString removeLongPathMarker ( QCString path)

Definition at line 298 of file util.cpp.

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

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

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

◆ removeRedundantWhiteSpace()

QCString removeRedundantWhiteSpace ( const QCString & s)

Definition at line 578 of file util.cpp.

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

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

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

◆ replaceAnonymousScopes()

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

Definition at line 229 of file util.cpp.

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

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

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

◆ replaceColorMarkers()

QCString replaceColorMarkers ( const QCString & str)

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

Definition at line 6215 of file util.cpp.

6216{
6217 if (str.isEmpty()) return QCString();
6218 std::string result;
6219 std::string s=str.str();
6220 static const reg::Ex re(R"(##[0-9A-Fa-f][0-9A-Fa-f])");
6221 reg::Iterator it(s,re);
6223 int hue = Config_getInt(HTML_COLORSTYLE_HUE);
6224 int sat = Config_getInt(HTML_COLORSTYLE_SAT);
6225 int gamma = Config_getInt(HTML_COLORSTYLE_GAMMA);
6226 size_t sl=s.length();
6227 size_t p=0;
6228 for (; it!=end ; ++it)
6229 {
6230 const auto &match = *it;
6231 size_t i = match.position();
6232 size_t l = match.length();
6233 if (i>p) result+=s.substr(p,i-p);
6234 std::string lumStr = match.str().substr(2);
6235#define HEXTONUM(x) (((x)>='0' && (x)<='9') ? ((x)-'0') : \
6236 ((x)>='a' && (x)<='f') ? ((x)-'a'+10) : \
6237 ((x)>='A' && (x)<='F') ? ((x)-'A'+10) : 0)
6238
6239 double r = 0,g = 0,b = 0;
6240 int level = HEXTONUM(lumStr[0])*16+HEXTONUM(lumStr[1]);
6241 ColoredImage::hsl2rgb(hue/360.0,sat/255.0,
6242 pow(level/255.0,gamma/100.0),&r,&g,&b);
6243 int red = static_cast<int>(r*255.0);
6244 int green = static_cast<int>(g*255.0);
6245 int blue = static_cast<int>(b*255.0);
6246 char colStr[8];
6247 colStr[0]='#';
6248 colStr[1]=hex[red>>4];
6249 colStr[2]=hex[red&0xf];
6250 colStr[3]=hex[green>>4];
6251 colStr[4]=hex[green&0xf];
6252 colStr[5]=hex[blue>>4];
6253 colStr[6]=hex[blue&0xf];
6254 colStr[7]=0;
6255 //printf("replacing %s->%s (level=%d)\n",qPrint(lumStr),colStr,level);
6256 result+=colStr;
6257 p=i+l;
6258 }
6259 if (p<sl) result+=s.substr(p);
6260 return QCString(result);
6261}
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 3185 of file util.cpp.

3193{
3194 *resContext=nullptr;
3195
3196 QCString linkRef=lr;
3197 if (lang==SrcLangExt::CSharp)
3198 {
3199 linkRef = mangleCSharpGenericName(linkRef);
3200 }
3201 QCString linkRefWithoutTemplates = stripTemplateSpecifiersFromScope(linkRef,FALSE);
3202 AUTO_TRACE("scName='{}',ref='{}'",scName,lr);
3203 const FileDef *fd = nullptr;
3204 const GroupDef *gd = nullptr;
3205 const PageDef *pd = nullptr;
3206 const ClassDef *cd = nullptr;
3207 const DirDef *dir = nullptr;
3208 const ConceptDef *cnd = nullptr;
3209 const ModuleDef *modd = nullptr;
3210 const NamespaceDef *nd = nullptr;
3211 const SectionInfo *si = nullptr;
3212 bool ambig = false;
3213 if (linkRef.isEmpty()) // no reference name!
3214 {
3215 AUTO_TRACE_EXIT("no_ref");
3216 return FALSE;
3217 }
3218 else if ((pd=Doxygen::pageLinkedMap->find(linkRef))) // link to a page
3219 {
3220 gd = pd->getGroupDef();
3221 if (gd)
3222 {
3223 if (!pd->name().isEmpty()) si=SectionManager::instance().find(pd->name());
3224 *resContext=gd;
3225 if (si) resAnchor = si->label();
3226 }
3227 else
3228 {
3229 *resContext=pd;
3230 }
3231 AUTO_TRACE_EXIT("page");
3232 return TRUE;
3233 }
3234 else if ((si=SectionManager::instance().find(prefix+linkRef)))
3235 {
3236 *resContext=si->definition();
3237 resAnchor = si->label();
3238 AUTO_TRACE_EXIT("section");
3239 return TRUE;
3240 }
3241 else if ((pd=Doxygen::exampleLinkedMap->find(linkRef))) // link to an example
3242 {
3243 *resContext=pd;
3244 AUTO_TRACE_EXIT("example");
3245 return TRUE;
3246 }
3247 else if ((gd=Doxygen::groupLinkedMap->find(linkRef))) // link to a group
3248 {
3249 *resContext=gd;
3250 AUTO_TRACE_EXIT("group");
3251 return TRUE;
3252 }
3253 else if ((fd=findFileDef(Doxygen::inputNameLinkedMap,linkRef,ambig)) // file link
3254 && fd->isLinkable())
3255 {
3256 *resContext=fd;
3257 AUTO_TRACE_EXIT("file");
3258 return TRUE;
3259 }
3260 else if ((cd=getClass(linkRef))) // class link
3261 {
3262 *resContext=cd;
3263 resAnchor=cd->anchor();
3264 AUTO_TRACE_EXIT("class");
3265 return TRUE;
3266 }
3267 else if (lang==SrcLangExt::Java &&
3268 (cd=getClass(linkRefWithoutTemplates))) // Java generic class link
3269 {
3270 *resContext=cd;
3271 resAnchor=cd->anchor();
3272 AUTO_TRACE_EXIT("generic");
3273 return TRUE;
3274 }
3275 else if ((cd=getClass(linkRef+"-p"))) // Obj-C protocol link
3276 {
3277 *resContext=cd;
3278 resAnchor=cd->anchor();
3279 AUTO_TRACE_EXIT("protocol");
3280 return TRUE;
3281 }
3282 else if ((cnd=getConcept(linkRef))) // C++20 concept definition
3283 {
3284 *resContext=cnd;
3285 resAnchor=cnd->anchor();
3286 AUTO_TRACE_EXIT("concept");
3287 return TRUE;
3288 }
3289 else if ((modd=ModuleManager::instance().modules().find(linkRef)))
3290 {
3291 *resContext=modd;
3292 resAnchor=modd->anchor();
3293 AUTO_TRACE_EXIT("module");
3294 return TRUE;
3295 }
3296 else if ((nd=Doxygen::namespaceLinkedMap->find(linkRef)))
3297 {
3298 *resContext=nd;
3299 AUTO_TRACE_EXIT("namespace");
3300 return TRUE;
3301 }
3302 else if ((dir=Doxygen::dirLinkedMap->find(FileInfo(linkRef.str()).absFilePath()+"/"))
3303 && dir->isLinkable()) // TODO: make this location independent like filedefs
3304 {
3305 *resContext=dir;
3306 AUTO_TRACE_EXIT("directory");
3307 return TRUE;
3308 }
3309 else // probably a member reference
3310 {
3311 const MemberDef *md = nullptr;
3312 bool res = resolveRef(scName,lr,TRUE,resContext,&md,lang);
3313 if (md) resAnchor=md->anchor();
3314 AUTO_TRACE_EXIT("member? res={}",res);
3315 return res;
3316 }
3317}
A model of a directory symbol.
Definition dirdef.h:110
static PageLinkedMap * exampleLinkedMap
Definition doxygen.h:99
static DirLinkedMap * dirLinkedMap
Definition doxygen.h:129
static GroupLinkedMap * groupLinkedMap
Definition doxygen.h:114
virtual const GroupDef * getGroupDef() const =0
QCString label() const
Definition section.h:68
Definition * definition() const
Definition section.h:76
bool resolveRef(const QCString &scName, const QCString &name, bool inSeeBlock, const Definition **resContext, const MemberDef **resMember, SrcLangExt lang, bool lookForSpecialization, const FileDef *currentFile, bool checkScope)
Definition util.cpp:2904
QCString mangleCSharpGenericName(const QCString &name)
Definition util.cpp:7337

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

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

◆ resolveRef()

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

Returns an object to reference to given its name and context

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

Definition at line 2904 of file util.cpp.

2914{
2915 AUTO_TRACE("scope={} name={} inSeeBlock={}",scName,name,inSeeBlock);
2916 //printf("resolveRef(scope=%s,name=%s,inSeeBlock=%d)\n",qPrint(scName),qPrint(name),inSeeBlock);
2917 QCString tsName = name;
2918 //bool memberScopeFirst = tsName.find('#')!=-1;
2919 QCString fullName = substitute(tsName,"#","::");
2920 if (fullName.find("anonymous_namespace{")==-1)
2921 {
2922 fullName = removeRedundantWhiteSpace(substitute(fullName,".","::",3));
2923 }
2924 else
2925 {
2926 fullName = removeRedundantWhiteSpace(fullName);
2927 }
2928
2929 int templStartPos;
2930 if (lang==SrcLangExt::CSharp && (templStartPos=fullName.find('<'))!=-1)
2931 {
2932 int templEndPos = fullName.findRev('>');
2933 if (templEndPos!=-1)
2934 {
2935 fullName = mangleCSharpGenericName(fullName.left(templEndPos+1))+fullName.mid(templEndPos+1);
2936 AUTO_TRACE_ADD("C# mangled name='{}'",fullName);
2937 }
2938 }
2939
2940 int bracePos=findParameterList(fullName);
2941 int endNamePos=bracePos!=-1 ? bracePos : static_cast<int>(fullName.length());
2942 int scopePos=fullName.findRev("::",endNamePos);
2943 bool explicitScope = fullName.startsWith("::") && // ::scope or #scope
2944 (scopePos>2 || // ::N::A
2945 tsName.startsWith("::") || // ::foo in local scope
2946 scName==nullptr // #foo in global scope
2947 );
2948 bool allowTypeOnly=false;
2949
2950 // default result values
2951 *resContext=nullptr;
2952 *resMember=nullptr;
2953
2954 if (bracePos==-1) // simple name
2955 {
2956 // the following if() was commented out for releases in the range
2957 // 1.5.2 to 1.6.1, but has been restored as a result of bug report 594787.
2958 if (!inSeeBlock && scopePos==-1 && isLowerCase(tsName))
2959 { // link to lower case only name => do not try to autolink
2960 AUTO_TRACE_ADD("false");
2961 return FALSE;
2962 }
2963
2964 ClassDef *cd=nullptr;
2965 NamespaceDef *nd=nullptr;
2966 ConceptDef *cnd=nullptr;
2967 ModuleDef *modd=nullptr;
2968
2969 //printf("scName=%s fullName=%s\n",qPrint(scName),qPrint(fullName));
2970
2971 // check if this is a class or namespace reference
2972 if (scName!=fullName && getScopeDefs(scName,fullName,cd,cnd,nd,modd))
2973 {
2974 //printf("found scopeDef\n");
2975 if (cd) // scope matches that of a class
2976 {
2977 *resContext = cd;
2978 }
2979 else if (cnd)
2980 {
2981 *resContext = cnd;
2982 }
2983 else if (modd)
2984 {
2985 *resContext = modd;
2986 }
2987 else // scope matches that of a namespace
2988 {
2989 ASSERT(nd!=nullptr);
2990 *resContext = nd;
2991 }
2992 AUTO_TRACE_ADD("true");
2993 return TRUE;
2994 }
2995 else if (scName==fullName || (!inSeeBlock && scopePos==-1))
2996 // nothing to link => output plain text
2997 {
2998 //printf("found scName=%s fullName=%s scName==fullName=%d "
2999 // "inSeeBlock=%d scopePos=%d!\n",
3000 // qPrint(scName),qPrint(fullName),scName==fullName,inSeeBlock,scopePos);
3001
3002 // at this point we have a bare word that is not a class or namespace
3003 // we should also allow typedefs or enums to be linked, but not for instance member
3004 // functions, otherwise 'Foo' would always link to the 'Foo()' constructor instead of the
3005 // 'Foo' class. So we use this flag as a filter.
3006 allowTypeOnly=true;
3007 }
3008
3009 // continue search...
3010 }
3011
3012 // extract userscope+name
3013 QCString nameStr=fullName.left(endNamePos);
3014 if (explicitScope) nameStr=nameStr.mid(2);
3015
3016
3017 // extract arguments
3018 QCString argsStr;
3019 if (bracePos!=-1) argsStr=fullName.right(fullName.length()-bracePos);
3020
3021 // strip template specifier
3022 // TODO: match against the correct partial template instantiation
3023 int templPos=nameStr.find('<');
3024 bool tryUnspecializedVersion = FALSE;
3025 if (templPos!=-1 && nameStr.find("operator")==-1)
3026 {
3027 int endTemplPos=nameStr.findRev('>');
3028 if (endTemplPos!=-1)
3029 {
3030 if (!lookForSpecialization)
3031 {
3032 nameStr=nameStr.left(templPos)+nameStr.right(nameStr.length()-endTemplPos-1);
3033 }
3034 else
3035 {
3036 tryUnspecializedVersion = TRUE;
3037 }
3038 }
3039 }
3040
3041 QCString scopeStr=scName;
3042 if (nameStr.length()>scopeStr.length() && leftScopeMatch(scopeStr,nameStr))
3043 {
3044 nameStr=nameStr.mid(scopeStr.length()+2);
3045 }
3046
3047 const GroupDef *gd = nullptr;
3048 const ConceptDef *cnd = nullptr;
3049 const ModuleDef *modd = nullptr;
3050
3051 // check if nameStr is a member or global.
3052 //printf("getDefs(scope=%s,name=%s,args=%s checkScope=%d)\n",
3053 // qPrint(scopeStr), qPrint(nameStr), qPrint(argsStr),checkScope);
3054 GetDefInput input(scopeStr,nameStr,argsStr);
3055 input.forceEmptyScope = explicitScope;
3056 input.currentFile = currentFile;
3057 input.checkCV = true;
3058 GetDefResult result = getDefs(input);
3059 if (result.found)
3060 {
3061 //printf("after getDefs checkScope=%d nameStr=%s\n",checkScope,qPrint(nameStr));
3062 if (checkScope && result.md && result.md->getOuterScope()==Doxygen::globalScope &&
3063 !result.md->isStrongEnumValue() &&
3064 (!scopeStr.isEmpty() || nameStr.find("::")>0))
3065 {
3066 // we did find a member, but it is a global one while we were explicitly
3067 // looking for a scoped variable. See bug 616387 for an example why this check is needed.
3068 // note we do need to support autolinking to "::symbol" hence the >0
3069 //printf("not global member!\n");
3070 *resContext=nullptr;
3071 *resMember=nullptr;
3072 AUTO_TRACE_ADD("false");
3073 return FALSE;
3074 }
3075 //printf("after getDefs md=%p cd=%p fd=%p nd=%p gd=%p\n",md,cd,fd,nd,gd);
3076 if (result.md)
3077 {
3078 if (!allowTypeOnly || result.md->isTypedef() || result.md->isEnumerate())
3079 {
3080 *resMember=result.md;
3081 *resContext=result.md;
3082 }
3083 else // md is not a type, but we explicitly expect one
3084 {
3085 *resContext=nullptr;
3086 *resMember=nullptr;
3087 AUTO_TRACE_ADD("false");
3088 return FALSE;
3089 }
3090 }
3091 else if (result.cd) *resContext=result.cd;
3092 else if (result.nd) *resContext=result.nd;
3093 else if (result.fd) *resContext=result.fd;
3094 else if (result.gd) *resContext=result.gd;
3095 else if (result.cnd) *resContext=result.cnd;
3096 else if (result.modd) *resContext=result.modd;
3097 else
3098 {
3099 *resContext=nullptr; *resMember=nullptr;
3100 AUTO_TRACE_ADD("false");
3101 return FALSE;
3102 }
3103 //printf("member=%s (md=%p) anchor=%s linkable()=%d context=%s\n",
3104 // qPrint(md->name()), md, qPrint(md->anchor()), md->isLinkable(), qPrint((*resContext)->name()));
3105 AUTO_TRACE_ADD("true");
3106 return TRUE;
3107 }
3108 else if (inSeeBlock && !nameStr.isEmpty() && (gd=Doxygen::groupLinkedMap->find(nameStr)))
3109 { // group link
3110 *resContext=gd;
3111 AUTO_TRACE_ADD("true");
3112 return TRUE;
3113 }
3114 else if ((cnd=Doxygen::conceptLinkedMap->find(nameStr)))
3115 {
3116 *resContext=cnd;
3117 AUTO_TRACE_ADD("true");
3118 return TRUE;
3119 }
3120 else if ((modd=ModuleManager::instance().modules().find(nameStr)))
3121 {
3122 *resContext=modd;
3123 AUTO_TRACE_ADD("true");
3124 return TRUE;
3125 }
3126 else if (tsName.find('.')!=-1) // maybe a link to a file
3127 {
3128 bool ambig = false;
3129 const FileDef *fd=findFileDef(Doxygen::inputNameLinkedMap,tsName,ambig);
3130 if (fd && !ambig)
3131 {
3132 *resContext=fd;
3133 AUTO_TRACE_ADD("true");
3134 return TRUE;
3135 }
3136 }
3137
3138 if (tryUnspecializedVersion)
3139 {
3140 bool b = resolveRef(scName,name,inSeeBlock,resContext,resMember,lang,FALSE,nullptr,checkScope);
3141 AUTO_TRACE_ADD("{}",b);
3142 return b;
3143 }
3144 if (bracePos!=-1) // Try without parameters as well, could be a constructor invocation
3145 {
3146 *resContext=getClass(fullName.left(bracePos));
3147 if (*resContext)
3148 {
3149 AUTO_TRACE_ADD("true");
3150 return TRUE;
3151 }
3152 }
3153 //printf("resolveRef: %s not found!\n",qPrint(name));
3154
3155 AUTO_TRACE_ADD("false");
3156 return FALSE;
3157}
static bool isLowerCase(QCString &s)
Definition util.cpp:2892
int findParameterList(const QCString &name)
Returns the position in the string where a function parameter list begins, or -1 if one is not found.
Definition util.cpp:836
static bool getScopeDefs(const QCString &docScope, const QCString &scope, ClassDef *&cd, ConceptDef *&cnd, NamespaceDef *&nd, ModuleDef *&modd)
Definition util.cpp:2830

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

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

◆ resolveTypeDef()

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

Definition at line 384 of file util.cpp.

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

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

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

◆ rightScopeMatch()

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

Definition at line 881 of file util.cpp.

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

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

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

◆ selectBlocks()

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

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

Definition at line 6833 of file util.cpp.

6834{
6835 if (s.isEmpty()) return s;
6836
6837 // helper to find the end of a block
6838 auto skipBlock = [&markerInfo](const char *p,const SelectionBlock &blk)
6839 {
6840 char c = 0;
6841 while ((c=*p))
6842 {
6843 if (c==markerInfo.markerChar && qstrncmp(p,markerInfo.endStr,markerInfo.endLen)==0) // end marker
6844 {
6845 size_t len = markerInfo.endLen;
6846 bool negate = *(p+markerInfo.endLen)=='!';
6847 if (negate) len++;
6848 size_t blkNameLen = qstrlen(blk.name);
6849 if (qstrncmp(p+len,blk.name,blkNameLen)==0 && // matching marker name
6850 qstrncmp(p+len+blkNameLen,markerInfo.closeStr,markerInfo.closeLen)==0) // matching marker closing
6851 {
6852 //printf("Found end marker %s enabled=%d negate=%d\n",blk.name,blk.enabled,negate);
6853 return p+len+blkNameLen+markerInfo.closeLen;
6854 }
6855 else // not the right marker id
6856 {
6857 p++;
6858 }
6859 }
6860 else // not and end marker
6861 {
6862 p++;
6863 }
6864 }
6865 return p;
6866 };
6867
6868 QCString result;
6869 result.reserve(s.length());
6870 const char *p = s.data();
6871 char c = 0;
6872 while ((c=*p))
6873 {
6874 if (c==markerInfo.markerChar) // potential start of marker
6875 {
6876 if (qstrncmp(p,markerInfo.beginStr,markerInfo.beginLen)==0) // start of begin marker
6877 {
6878 bool found = false;
6879 size_t len = markerInfo.beginLen;
6880 bool negate = *(p+len)=='!';
6881 if (negate) len++;
6882 for (const auto &blk : blockList)
6883 {
6884 size_t blkNameLen = qstrlen(blk.name);
6885 if (qstrncmp(p+len,blk.name,blkNameLen)==0 && // matching marker name
6886 qstrncmp(p+len+blkNameLen,markerInfo.closeStr,markerInfo.closeLen)==0) // matching marker closing
6887 {
6888 bool blockEnabled = blk.enabled!=negate;
6889 //printf("Found start marker %s enabled=%d negate=%d\n",blk.name,blk.enabled,negate);
6890 p+=len+blkNameLen+markerInfo.closeLen;
6891 if (!blockEnabled) // skip until the end of the block
6892 {
6893 //printf("skipping block\n");
6894 p=skipBlock(p,blk);
6895 }
6896 found=true;
6897 break;
6898 }
6899 }
6900 if (!found) // unknown marker id
6901 {
6902 result+=c;
6903 p++;
6904 }
6905 }
6906 else if (qstrncmp(p,markerInfo.endStr,markerInfo.endLen)==0) // start of end marker
6907 {
6908 bool found = false;
6909 size_t len = markerInfo.endLen;
6910 bool negate = *(p+len)=='!';
6911 if (negate) len++;
6912 for (const auto &blk : blockList)
6913 {
6914 size_t blkNameLen = qstrlen(blk.name);
6915 if (qstrncmp(p+len,blk.name,blkNameLen)==0 && // matching marker name
6916 qstrncmp(p+len+blkNameLen,markerInfo.closeStr,markerInfo.closeLen)==0) // matching marker closing
6917 {
6918 //printf("Found end marker %s enabled=%d negate=%d\n",blk.name,blk.enabled,negate);
6919 p+=len+blkNameLen+markerInfo.closeLen;
6920 found=true;
6921 break;
6922 }
6923 }
6924 if (!found) // unknown marker id
6925 {
6926 result+=c;
6927 p++;
6928 }
6929 }
6930 else // not a start or end marker
6931 {
6932 result+=c;
6933 p++;
6934 }
6935 }
6936 else // not a marker character
6937 {
6938 result+=c;
6939 p++;
6940 }
6941 }
6942 //printf("====\n%s\n-----\n%s\n~~~~\n",qPrint(s),qPrint(result));
6943 return result;
6944}
void reserve(size_t size)
Reserve space for size bytes without changing the string contents.
Definition qcstring.h:172
uint32_t qstrlen(const char *str)
Returns the length of string str, or 0 if a null pointer is passed.
Definition qcstring.h:58

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

Referenced by substituteHtmlKeywords(), and substituteLatexKeywords().

◆ showDate()

static QCString showDate ( const QCString & fmt)
static

Definition at line 3568 of file util.cpp.

3569{
3570 // get the current date and time
3571 std::tm dat{};
3572 int specFormat=0;
3573 QCString specDate = "";
3574 QCString err = dateTimeFromString(specDate,dat,specFormat);
3575
3576 // do the conversion
3577 int usedFormat=0;
3578 return formatDateTime(fmt,dat,usedFormat);
3579}
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 3474 of file util.cpp.

3475{
3476 QCString result;
3477 QCString name=n;
3478 QCString path;
3479 int slashPos=std::max(name.findRev('/'),name.findRev('\\'));
3480 if (slashPos!=-1)
3481 {
3482 path=name.left(slashPos+1);
3483 name=name.right(name.length()-slashPos-1);
3484 }
3485 const FileName *fn=fnMap->find(name);
3486 if (fn)
3487 {
3488 bool first = true;
3489 for (const auto &fd : *fn)
3490 {
3491 if (path.isEmpty() || fd->getPath().right(path.length())==path)
3492 {
3493 if (!first) result += "\n";
3494 else first = false;
3495 result+=" "+fd->absFilePath();
3496 }
3497 }
3498 }
3499 return result;
3500}

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

7060{
7061 StringVector result;
7062 reg::Iterator iter(s, delimiter);
7064 size_t p=0;
7065 for ( ; iter != end; ++iter)
7066 {
7067 const auto &match = *iter;
7068 size_t i=match.position();
7069 size_t l=match.length();
7070 if (i>p) result.push_back(s.substr(p,i-p));
7071 p=i+l;
7072 }
7073 if (p<s.length()) result.push_back(s.substr(p));
7074 return result;
7075}

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

7043{
7044 StringVector result;
7045 size_t prev = 0, pos = 0, len = s.length();
7046 do
7047 {
7048 pos = s.find(delimiter, prev);
7049 if (pos == std::string::npos) pos = len;
7050 if (pos>prev) result.push_back(s.substr(prev,pos-prev));
7051 prev = pos + delimiter.length();
7052 }
7053 while (pos<len && prev<len);
7054 return result;
7055}

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

◆ stackTrace()

void stackTrace ( )

Definition at line 5873 of file util.cpp.

5874{
5875#ifdef TRACINGSUPPORT
5876 void *backtraceFrames[128];
5877 int frameCount = backtrace(backtraceFrames, 128);
5878 const size_t cmdLen = 40960;
5879 static char cmd[cmdLen];
5880 char *p = cmd;
5881 p += qsnprintf(p,cmdLen,"/usr/bin/atos -p %d ", (int)getpid());
5882 for (int x = 0; x < frameCount; x++)
5883 {
5884 p += qsnprintf(p,cmdLen,"%p ", backtraceFrames[x]);
5885 }
5886 fprintf(stderr,"========== STACKTRACE START ==============\n");
5887 if (FILE *fp = Portable::popen(cmd, "r"))
5888 {
5889 char resBuf[512];
5890 while (size_t len = fread(resBuf, 1, sizeof(resBuf), fp))
5891 {
5892 fwrite(resBuf, 1, len, stderr);
5893 }
5894 Portable::pclose(fp);
5895 }
5896 fprintf(stderr,"============ STACKTRACE END ==============\n");
5897 //fprintf(stderr,"%s\n", frameStrings[x]);
5898#endif
5899}

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

◆ stripAnonymousNamespaceScope()

QCString stripAnonymousNamespaceScope ( const QCString & s)

Definition at line 241 of file util.cpp.

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

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

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

◆ stripDeclKeywords()

static QCString stripDeclKeywords ( const QCString & s)
static

Definition at line 1534 of file util.cpp.

1535{
1536 int i=s.find(" class ");
1537 if (i!=-1) return s.left(i)+s.mid(i+6);
1538 i=s.find(" typename ");
1539 if (i!=-1) return s.left(i)+s.mid(i+9);
1540 i=s.find(" union ");
1541 if (i!=-1) return s.left(i)+s.mid(i+6);
1542 i=s.find(" struct ");
1543 if (i!=-1) return s.left(i)+s.mid(i+7);
1544 return s;
1545}

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

Referenced by getCanonicalTypeForIdentifier().

◆ stripExtension()

QCString stripExtension ( const QCString & fName)

Definition at line 5361 of file util.cpp.

5362{
5364}
QCString stripExtensionGeneral(const QCString &fName, const QCString &ext)
Definition util.cpp:5351

References Doxygen::htmlFileExtension, and stripExtensionGeneral().

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

◆ stripExtensionGeneral()

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

◆ stripFromIncludePath()

QCString stripFromIncludePath ( const QCString & path)

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

Definition at line 340 of file util.cpp.

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

References Config_getList, and stripFromPath().

Referenced by addIncludeFile(), and findFileDef().

◆ stripFromPath() [1/2]

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

Definition at line 309 of file util.cpp.

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

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

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

◆ stripFromPath() [2/2]

QCString stripFromPath ( const QCString & path)

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

Definition at line 332 of file util.cpp.

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

References Config_getList, and stripFromPath().

◆ stripIndentation()

QCString stripIndentation ( const QCString & s)

Definition at line 6378 of file util.cpp.

6379{
6380 if (s.isEmpty()) return s; // empty string -> we're done
6381
6382 //printf("stripIndentation:\n%s\n------\n",qPrint(s));
6383 // compute minimum indentation over all lines
6384 const char *p=s.data();
6385 char c=0;
6386 int indent=0;
6387 int minIndent=1000000; // "infinite"
6388 bool searchIndent=TRUE;
6389 int tabSize=Config_getInt(TAB_SIZE);
6390 while ((c=*p++))
6391 {
6392 if (c=='\t') indent+=tabSize - (indent%tabSize);
6393 else if (c=='\n') indent=0,searchIndent=TRUE;
6394 else if (c==' ') indent++;
6395 else if (searchIndent)
6396 {
6397 searchIndent=FALSE;
6398 if (indent<minIndent) minIndent=indent;
6399 }
6400 }
6401
6402 // no indent to remove -> we're done
6403 if (minIndent==0) return substitute(s,"@ilinebr","\\ilinebr");
6404
6405 // remove minimum indentation for each line
6406 TextStream result;
6407 p=s.data();
6408 indent=0;
6409 while ((c=*p++))
6410 {
6411 if (c=='\n') // start of new line
6412 {
6413 indent=0;
6414 result << c;
6415 }
6416 else if (indent<minIndent) // skip until we reach minIndent
6417 {
6418 if (c=='\t')
6419 {
6420 int newIndent = indent+tabSize-(indent%tabSize);
6421 int i=newIndent;
6422 while (i>minIndent) // if a tab crosses the minIndent boundary fill the rest with spaces
6423 {
6424 result << ' ';
6425 i--;
6426 }
6427 indent=newIndent;
6428 }
6429 else // space
6430 {
6431 indent++;
6432 }
6433 }
6434 else if (c=='\\' && qstrncmp(p,"ilinebr ",8)==0)
6435 // we also need to remove the indentation after a \ilinebr command at the end of a line
6436 {
6437 result << "\\ilinebr ";
6438 p+=8;
6439 int skipAmount=0;
6440 for (int j=0;j<minIndent;j++) if (*(p+j)==' ') skipAmount++; // test to see if we have the indent
6441 if (skipAmount==minIndent)
6442 {
6443 p+=skipAmount; // remove the indent
6444 }
6445 }
6446 else if (c=='@' && qstrncmp(p,"ilinebr",7)==0)
6447 {
6448 result << "\\ilinebr";
6449 p+=7;
6450 }
6451 else // copy anything until the end of the line
6452 {
6453 result << c;
6454 }
6455 }
6456
6457 //printf("stripIndentation: result=\n%s\n------\n",qPrint(result.str()));
6458
6459 return result.str();
6460}

References Config_getInt, QCString::data(), FALSE, QCString::isEmpty(), qstrncmp(), TextStream::str(), substitute(), and TRUE.

Referenced by handleCommentBlock(), handleCommentBlock(), handleCommentBlock(), handleParametersCommentBlocks(), and DocPara::handleStartCode().

◆ stripIndentationVerbatim()

void stripIndentationVerbatim ( QCString & doc,
const int indentationLevel )

Definition at line 6463 of file util.cpp.

6464{
6465 //printf("stripIndentationVerbatim(level=%d):\n%s\n------\n",indentationLevel,qPrint(doc));
6466 if (indentationLevel <= 0 || doc.isEmpty()) return; // nothing to strip
6467
6468 // by stripping content the string will only become shorter so we write the results
6469 // back into the input string and then resize it at the end.
6470 char c = 0;
6471 const char *src = doc.data();
6472 char *dst = doc.rawData();
6473 bool insideIndent = false; // skip the initial line from stripping
6474 int cnt = 0;
6475 while ((c=*src++))
6476 {
6477 // invariant: dst<=src
6478 switch(c)
6479 {
6480 case '\n':
6481 *dst++ = c;
6482 insideIndent = true;
6483 cnt = indentationLevel;
6484 break;
6485 case ' ':
6486 if (insideIndent)
6487 {
6488 if (cnt>0) // count down the spacing until the end of the indent
6489 {
6490 cnt--;
6491 }
6492 else // reached the end of the indent, start of the part of the line to keep
6493 {
6494 insideIndent = false;
6495 *dst++ = c;
6496 }
6497 }
6498 else // part after indent, copy to the output
6499 {
6500 *dst++ = c;
6501 }
6502 break;
6503 default:
6504 insideIndent = false;
6505 *dst++ = c;
6506 break;
6507 }
6508 }
6509 doc.resize(static_cast<uint32_t>(dst-doc.data()));
6510 //printf("stripIndentationVerbatim: result=\n%s\n------\n",qPrint(doc));
6511}
char * rawData()
Returns a writable pointer to the data.
Definition qcstring.h:165
void resize(size_t newlen)
Definition qcstring.h:167

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

◆ stripIrrelevantConstVolatile()

void stripIrrelevantConstVolatile ( QCString & s)

According to the C++ spec and Ivan Vecerina:

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

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

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

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

Definition at line 1524 of file util.cpp.

1525{
1526 //printf("stripIrrelevantConstVolatile(%s)=",qPrint(s));
1527 stripIrrelevantString(s,"const");
1528 stripIrrelevantString(s,"volatile");
1529 stripIrrelevantString(s,"final");
1530 //printf("%s\n",qPrint(s));
1531}
static void stripIrrelevantString(QCString &target, const QCString &str)
Definition util.cpp:1473

References stripIrrelevantString().

Referenced by extractCanonicalType(), and matchArgument2().

◆ stripIrrelevantString()

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

Definition at line 1473 of file util.cpp.

1474{
1475 if (target==str) { target.clear(); return; }
1476 int i=0,p=0;
1477 int l=static_cast<int>(str.length());
1478 bool changed=FALSE;
1479 while ((i=target.find(str,p))!=-1)
1480 {
1481 bool isMatch = (i==0 || !isId(target.at(i-1))) && // not a character before str
1482 (i+l==static_cast<int>(target.length()) || !isId(target.at(i+l))); // not a character after str
1483 if (isMatch)
1484 {
1485 int i1=target.find('*',i+l);
1486 int i2=target.find('&',i+l);
1487 if (i1==-1 && i2==-1)
1488 {
1489 // strip str from target at index i
1490 target=target.left(i)+target.right(target.length()-i-l);
1491 changed=TRUE;
1492 i-=l;
1493 }
1494 else if ((i1!=-1 && i<i1) || (i2!=-1 && i<i2)) // str before * or &
1495 {
1496 // move str to front
1497 target=str+" "+target.left(i)+target.right(target.length()-i-l);
1498 changed=TRUE;
1499 i++;
1500 }
1501 }
1502 p = i+l;
1503 }
1504 if (changed) target=target.stripWhiteSpace();
1505}

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

Referenced by stripIrrelevantConstVolatile().

◆ stripLeadingAndTrailingEmptyLines()

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

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

Parameters
sthe string to be stripped
docLinethe line number corresponding to the start of the string. This will be adjusted based on the number of lines stripped from the start.
Returns
The stripped string.

Definition at line 5464 of file util.cpp.

5465{
5466 if (s.isEmpty()) return QCString();
5467 const char *p = s.data();
5468
5469 // search for leading empty lines
5470 int i=0,li=-1,l=static_cast<int>(s.length());
5471 char c = 0;
5472 while ((c=*p))
5473 {
5474 if (c==' ' || c=='\t' || c=='\r') i++,p++;
5475 else if (c=='\\' && qstrncmp(p,"\\ilinebr",8)==0) i+=8,li=i,p+=8;
5476 else if (c=='\n') i++,li=i,docLine++,p++;
5477 else break;
5478 }
5479
5480 // search for trailing empty lines
5481 int b=l-1,bi=-1;
5482 p=s.data()+b;
5483 while (b>=0)
5484 {
5485 c=*p;
5486 if (c==' ' || c=='\t' || c=='\r') b--,p--;
5487 else if (c=='r' && b>=7 && qstrncmp(p-7,"\\ilinebr",8)==0) bi=b-7,b-=8,p-=8;
5488 else if (c=='>' && b>=11 && qstrncmp(p-11,"\\ilinebr<br>",12)==0) bi=b-11,b-=12,p-=12;
5489 else if (c=='\n') bi=b,b--,p--;
5490 else break;
5491 }
5492
5493 // return whole string if no leading or trailing lines where found
5494 if (li==-1 && bi==-1) return s;
5495
5496 // return substring
5497 if (bi==-1) bi=l;
5498 if (li==-1) li=0;
5499 if (bi<=li) return QCString(); // only empty lines
5500 //printf("docLine='%s' len=%d li=%d bi=%d\n",qPrint(s),s.length(),li,bi);
5501 return s.mid(li,bi-li);
5502}

References QCString::data(), QCString::isEmpty(), QCString::length(), QCString::mid(), and qstrncmp().

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

◆ stripPath()

QCString stripPath ( const QCString & s)

Definition at line 5388 of file util.cpp.

5389{
5390 QCString result=s;
5391 int i=result.findRev('/');
5392 if (i!=-1)
5393 {
5394 result=result.mid(i+1);
5395 }
5396 i=result.findRev('\\');
5397 if (i!=-1)
5398 {
5399 result=result.mid(i+1);
5400 }
5401 return result;
5402}

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

4220{
4221 QCString result = name;
4222 int l = static_cast<int>(result.length());
4223 int p = 0;
4224 bool done = FALSE;
4225 bool skipBracket=FALSE; // if brackets do not match properly, ignore them altogether
4226 int count=0;
4227 int round=0;
4228
4229 do
4230 {
4231 p=l-1; // start at the end of the string
4232 while (p>=0 && count>=0)
4233 {
4234 char c=result.at(p);
4235 switch (c)
4236 {
4237 case ':':
4238 // only exit in the case of ::
4239 //printf("stripScope(%s)=%s\n",name,qPrint(result.right(l-p-1)));
4240 if (p>0 && result.at(p-1)==':' && (count==0 || skipBracket))
4241 {
4242 return result.right(l-p-1);
4243 }
4244 p--;
4245 break;
4246 case '>':
4247 if (skipBracket) // we don't care about brackets
4248 {
4249 p--;
4250 }
4251 else // count open/close brackets
4252 {
4253 if (p>0 && result.at(p-1)=='>') // skip >> operator
4254 {
4255 p-=2;
4256 break;
4257 }
4258 count=1;
4259 //printf("pos < = %d\n",p);
4260 p--;
4261 bool foundMatch=false;
4262 while (p>=0 && !foundMatch)
4263 {
4264 c=result.at(p--);
4265 switch (c)
4266 {
4267 case ')':
4268 round++;
4269 break;
4270 case '(':
4271 round--;
4272 break;
4273 case '>': // ignore > inside (...) to support e.g. (sizeof(T)>0) inside template parameters
4274 if (round==0) count++;
4275 break;
4276 case '<':
4277 if (round==0)
4278 {
4279 if (p>0)
4280 {
4281 if (result.at(p-1) == '<') // skip << operator
4282 {
4283 p--;
4284 break;
4285 }
4286 }
4287 count--;
4288 foundMatch = count==0;
4289 }
4290 break;
4291 default:
4292 //printf("c=%c count=%d\n",c,count);
4293 break;
4294 }
4295 }
4296 }
4297 //printf("pos > = %d\n",p+1);
4298 break;
4299 default:
4300 p--;
4301 }
4302 }
4303 done = count==0 || skipBracket; // reparse if brackets do not match
4304 skipBracket=TRUE;
4305 }
4306 while (!done); // if < > unbalanced repeat ignoring them
4307 //printf("stripScope(%s)=%s\n",name,name);
4308 return name;
4309}

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

4958{
4959 //printf("stripTemplateSpecifiersFromScope(name=%s,scopeName=%s)\n",qPrint(fullName),qPrint(scopeName));
4960 int i=fullName.find('<');
4961 if (i==-1) return fullName;
4962 QCString result;
4963 int p=0;
4964 int l=static_cast<int>(fullName.length());
4965 while (i!=-1)
4966 {
4967 //printf("1:result+=%s\n",qPrint(fullName.mid(p,i-p)));
4968 int e=i+1;
4969 int count=1;
4970 int round=0;
4971 while (e<l && count>0)
4972 {
4973 char c=fullName.at(e++);
4974 switch (c)
4975 {
4976 case '(': round++; break;
4977 case ')': if (round>0) round--; break;
4978 case '<': if (round==0) count++; break;
4979 case '>': if (round==0) count--; break;
4980 default:
4981 break;
4982 }
4983 }
4984 int si= fullName.find("::",e);
4985
4986 if (parentOnly && si==-1) break;
4987 // we only do the parent scope, so we stop here if needed
4988
4989 result+=fullName.mid(p,i-p);
4990 //printf(" trying %s\n",qPrint(mergeScopes(scopeName,result+fullName.mid(i,e-i))));
4991 ClassDef *cd = getClass(mergeScopes(scopeName,result+fullName.mid(i,e-i)));
4992 if (cd!=nullptr && (allowArtificial || !cd->isArtificial()))
4993 {
4994 result+=fullName.mid(i,e-i);
4995 //printf(" 2:result+=%s\n",qPrint(fullName.mid(i,e-i-1)));
4996 }
4997 else if (pLastScopeStripped)
4998 {
4999 //printf(" last stripped scope '%s'\n",qPrint(fullName.mid(i,e-i)));
5000 *pLastScopeStripped=fullName.mid(i,e-i);
5001 }
5002 p=e;
5003 i=fullName.find('<',p);
5004 }
5005 result+=fullName.right(l-p);
5006 //printf("3:result+=%s\n",qPrint(fullName.right(l-p)));
5007 //printf("end result=%s\n",qPrint(result));
5008 return result;
5009}
virtual bool isArtificial() const =0
QCString mergeScopes(const QCString &leftScope, const QCString &rightScope)
Definition util.cpp:5020

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

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

◆ substituteKeywords() [1/2]

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

Definition at line 3504 of file util.cpp.

3505{
3506 std::string substRes;
3507 const char *p = s.data();
3508 if (p)
3509 {
3510 // reserve some room for expansion
3511 substRes.reserve(s.length()+1024);
3512 char c = 0;
3513 while ((c=*p))
3514 {
3515 bool found = false;
3516 if (c=='$')
3517 {
3518 for (const auto &kw : keywords)
3519 {
3520 size_t keyLen = qstrlen(kw.keyword);
3521 if (qstrncmp(p,kw.keyword,keyLen)==0)
3522 {
3523 const char *startArg = p+keyLen;
3524 bool expectParam = std::holds_alternative<KeywordSubstitution::GetValueWithParam>(kw.getValueVariant);
3525 //printf("%s: expectParam=%d *startArg=%c\n",kw.keyword,expectParam,*startArg);
3526 if (expectParam && *startArg=='(') // $key(value)
3527 {
3528 size_t j=1;
3529 const char *endArg = nullptr;
3530 while ((c=*(startArg+j)) && c!=')' && c!='\n' && c!=0) j++;
3531 if (c==')') endArg=startArg+j;
3532 if (endArg)
3533 {
3534 QCString value = QCString(startArg+1).left(endArg-startArg-1);
3535 auto &&getValue = std::get<KeywordSubstitution::GetValueWithParam>(kw.getValueVariant);
3536 substRes+=getValue(value).str();
3537 p=endArg+1;
3538 //printf("found '%s'->'%s'\n",kw.keyword,qPrint(getValue(value)));
3539 }
3540 else
3541 {
3542 //printf("missing argument\n");
3543 p+=keyLen;
3544 }
3545 }
3546 else if (!expectParam) // $key
3547 {
3548 auto &&getValue = std::get<KeywordSubstitution::GetValue>(kw.getValueVariant);
3549 substRes+=getValue().str();
3550 //printf("found '%s'->'%s'\n",kw.keyword,qPrint(getValue()));
3551 p+=keyLen;
3552 }
3553 found = true;
3554 break;
3555 }
3556 }
3557 }
3558 if (!found) // copy
3559 {
3560 substRes+=c;
3561 p++;
3562 }
3563 }
3564 }
3565 return substRes;
3566}

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

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

◆ substituteKeywords() [2/2]

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

Definition at line 3647 of file util.cpp.

3649{
3650 return substituteKeywords(s,
3651 {
3652 // keyword value getter
3653 { "$title", [&]() { return !title.isEmpty() ? title : projName; } },
3654 { "$datetime", [&]() { return dateToString(DateTimeType::DateTime); } },
3655 { "$date", [&]() { return dateToString(DateTimeType::Date); } },
3656 { "$time", [&]() { return dateToString(DateTimeType::Time); } },
3657 { "$year", [&]() { return yearToString(); } },
3658 { "$doxygenversion", [&]() { return getDoxygenVersion(); } },
3659 { "$projectname", [&]() { return projName; } },
3660 { "$projectnumber", [&]() { return projNum; } },
3661 { "$projectbrief", [&]() { return projBrief; } },
3662 { "$projectlogo", [&]() { return stripPath(projectLogoFile()); } },
3663 { "$logosize", [&]() { return projectLogoSize(); } },
3664 { "$projecticon", [&]() { return stripPath(Config_getString(PROJECT_ICON)); } },
3665 { "$langISO", [&]() { return theTranslator->trISOLang(); } },
3666 { "$showdate", [&](const QCString &fmt) { return showDate(fmt); } }
3667 });
3668}
QCString dateToString(DateTimeType includeTime)
Returns the current date, when includeTime is set also the time is provided.
Definition datetime.cpp:63
QCString yearToString()
Returns the current year as a string.
Definition datetime.cpp:76
QCString stripPath(const QCString &s)
Definition util.cpp:5388
QCString substituteKeywords(const QCString &s, const KeywordSubstitutionList &keywords)
Definition util.cpp:3504
QCString projectLogoFile()
Definition util.cpp:3581
static QCString projectLogoSize()
Definition util.cpp:3602
static QCString showDate(const QCString &fmt)
Definition util.cpp:3568

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

◆ substituteTemplateArgumentsInString()

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

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

Definition at line 4791 of file util.cpp.

4795{
4796 AUTO_TRACE("name={} formalArgs={} actualArgs={}",nm,argListToString(formalArgs),actualArgs ? argListToString(*actualArgs) : QCString());
4797 if (formalArgs.empty()) return nm;
4798 QCString result;
4799
4800 static const reg::Ex re(R"(\a\w*)");
4801 std::string name = nm.str();
4802 reg::Iterator it(name,re);
4804 size_t p=0;
4805
4806 for (; it!=end ; ++it)
4807 {
4808 const auto &match = *it;
4809 size_t i = match.position();
4810 size_t l = match.length();
4811 if (i>p) result += name.substr(p,i-p);
4812 QCString n(match.str());
4814 if (actualArgs)
4815 {
4816 actIt = actualArgs->begin();
4817 }
4818 //printf(": name=%s\n",qPrint(name));
4819
4820 // if n is a template argument, then we substitute it
4821 // for its template instance argument.
4822 bool found=FALSE;
4823 for (auto formIt = formalArgs.begin();
4824 formIt!=formalArgs.end() && !found;
4825 ++formIt
4826 )
4827 {
4828 Argument formArg = *formIt;
4829 Argument actArg;
4830 if (actualArgs && actIt!=actualArgs->end())
4831 {
4832 actArg = *actIt;
4833 }
4834 if (formArg.type.startsWith("class ") && formArg.name.isEmpty())
4835 {
4836 formArg.name = formArg.type.mid(6);
4837 formArg.type = "class";
4838 }
4839 else if (formArg.type.startsWith("typename ") && formArg.name.isEmpty())
4840 {
4841 formArg.name = formArg.type.mid(9);
4842 formArg.type = "typename";
4843 }
4844 else if (formArg.type.startsWith("class...")) // match 'class... name' to 'name...'
4845 {
4846 formArg.name += "...";
4847 formArg.type = formArg.type.left(5)+formArg.type.mid(8);
4848 }
4849 else if (formArg.type.startsWith("typename...")) // match 'typename... name' to 'name...'
4850 {
4851 formArg.name += "...";
4852 formArg.type = formArg.type.left(8)+formArg.type.mid(11);
4853 }
4854 //printf(": n=%s formArg->type='%s' formArg->name='%s' formArg->defval='%s' actArg->type='%s' actArg->name='%s' \n",
4855 // qPrint(n),qPrint(formArg.type),qPrint(formArg.name),qPrint(formArg.defval),qPrint(actArg.type),qPrint(actArg.name));
4856 if (formArg.type=="class" || formArg.type=="typename" || formArg.type.startsWith("template"))
4857 {
4858 if (formArg.name==n && actualArgs && actIt!=actualArgs->end() && !actArg.type.isEmpty()) // base class is a template argument
4859 {
4860 static constexpr auto hasRecursion = [](const QCString &prefix,const QCString &nameArg,const QCString &subst) -> bool
4861 {
4862 int ii=0;
4863 int pp=0;
4864
4865 ii = subst.find('<');
4866 //printf("prefix='%s' subst='%s'\n",qPrint(prefix.mid(prefix.length()-ii-2,ii+1)),qPrint(subst.left(ii+1)));
4867 if (ii!=-1 && static_cast<int>(prefix.length())>=ii+2 && prefix.mid(prefix.length()-ii-2,ii+1)==subst.left(ii+1))
4868 {
4869 return true; // don't replace 'A< ' with 'A< A<...', see issue #10951
4870 }
4871
4872 while ((ii=subst.find(nameArg,pp))!=-1)
4873 {
4874 bool beforeNonWord = ii==0 || !isId(subst.at(ii-1));
4875 bool afterNonWord = subst.length()==ii+nameArg.length() || !isId(subst.at(ii+nameArg.length()));
4876 if (beforeNonWord && afterNonWord)
4877 {
4878 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
4879 }
4880 pp=ii+static_cast<int>(nameArg.length());
4881 }
4882 return false;
4883 };
4884 // replace formal argument with the actual argument of the instance
4885 AUTO_TRACE_ADD("result={} n={} type={} hasRecursion={}",result,n,actArg.type,hasRecursion(result,n,actArg.type));
4886 if (!hasRecursion(result,n,actArg.type))
4887 // the scope guard is to prevent recursive lockup for
4888 // template<class A> class C : public<A::T>,
4889 // where A::T would become A::T::T here,
4890 // since n==A and actArg->type==A::T
4891 // see bug595833 for an example
4892 //
4893 // Also prevent recursive substitution if n is part of actArg.type, i.e.
4894 // n='A' in argType='S< A >' would produce 'S< S< A > >'
4895 {
4896 if (actArg.name.isEmpty())
4897 {
4898 result += actArg.type;
4899 }
4900 else
4901 // for case where the actual arg is something like "unsigned int"
4902 // the "int" part is in actArg->name.
4903 {
4904 result += actArg.type+" "+actArg.name;
4905 }
4906 found=TRUE;
4907 }
4908 }
4909 else if (formArg.name==n &&
4910 (actualArgs==nullptr || actIt==actualArgs->end()) &&
4911 !formArg.defval.isEmpty() &&
4912 formArg.defval!=nm /* to prevent recursion */
4913 )
4914 {
4915 result += substituteTemplateArgumentsInString(formArg.defval,formalArgs,actualArgs);
4916 found=TRUE;
4917 }
4918 }
4919 else if (formArg.name==n &&
4920 (actualArgs==nullptr || actIt==actualArgs->end()) &&
4921 !formArg.defval.isEmpty() &&
4922 formArg.defval!=nm /* to prevent recursion */
4923 )
4924 {
4925 result += substituteTemplateArgumentsInString(formArg.defval,formalArgs,actualArgs);
4926 found=TRUE;
4927 }
4928 if (actualArgs && actIt!=actualArgs->end())
4929 {
4930 actIt++;
4931 }
4932 }
4933 if (!found)
4934 {
4935 result += n;
4936 }
4937 p=i+l;
4938 }
4939 result+=name.substr(p);
4940 result=result.simplifyWhiteSpace();
4941 AUTO_TRACE_EXIT("result={}",result);
4942 return result.stripWhiteSpace();
4943}
typename Vec::const_iterator const_iterator
Definition arguments.h:64
QCString substituteTemplateArgumentsInString(const QCString &nm, const ArgumentList &formalArgs, const ArgumentList *actualArgs)
Definition util.cpp:4791

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

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

◆ tempArgListToString()

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

Definition at line 1219 of file util.cpp.

1220{
1221 QCString result;
1222 if (al.empty()) return result;
1223 result="<";
1224 bool first=true;
1225 for (const auto &a : al)
1226 {
1227 if (a.defval.isEmpty() || includeDefault)
1228 {
1229 if (!first) result+=", ";
1230 if (!a.name.isEmpty()) // add template argument name
1231 {
1232 if (lang==SrcLangExt::Java || lang==SrcLangExt::CSharp)
1233 {
1234 result+=a.type+" ";
1235 }
1236 result+=a.name;
1237 }
1238 else // extract name from type
1239 {
1240 int i = static_cast<int>(a.type.length())-1;
1241 while (i>=0 && isId(a.type.at(i))) i--;
1242 if (i>0)
1243 {
1244 result+=a.type.right(a.type.length()-i-1);
1245 if (a.type.find("...")!=-1)
1246 {
1247 result+="...";
1248 }
1249 }
1250 else // nothing found -> take whole name
1251 {
1252 result+=a.type;
1253 }
1254 }
1255 if (!a.typeConstraint.isEmpty() && lang==SrcLangExt::Java)
1256 {
1257 result+=" extends "; // TODO: now Java specific, C# has where...
1258 result+=a.typeConstraint;
1259 }
1260 first=false;
1261 }
1262 }
1263 result+=">";
1264 return removeRedundantWhiteSpace(result);
1265}

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

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

◆ transcodeCharacterBuffer()

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

Definition at line 5901 of file util.cpp.

5903{
5904 if (inputEncoding.isEmpty() || outputEncoding.isEmpty()) return; // no encoding specified
5905 if (qstricmp(inputEncoding,outputEncoding)==0) return; // input encoding same as output encoding
5906 void *cd = portable_iconv_open(outputEncoding.data(),inputEncoding.data());
5907 if (cd==reinterpret_cast<void *>(-1))
5908 {
5909 term("unsupported character conversion: '{}'->'{}': {}\n"
5910 "Check the INPUT_ENCODING setting in the config file!\n",
5911 inputEncoding,outputEncoding,strerror(errno));
5912 }
5913 size_t iLeft = contents.size();
5914 const char *srcPtr = contents.data();
5915 size_t tmpBufSize = contents.size()*4+1;
5916 size_t oLeft = tmpBufSize;
5917 std::string tmpBuf;
5918 tmpBuf.resize(tmpBufSize);
5919 char *dstPtr = tmpBuf.data();
5920 size_t newSize=0;
5921 if (!portable_iconv(cd, &srcPtr, &iLeft, &dstPtr, &oLeft))
5922 {
5923 newSize = tmpBufSize-oLeft;
5924 tmpBuf.resize(newSize);
5925 std::swap(contents,tmpBuf);
5926 //printf("iconv: input size=%d output size=%d\n[%s]\n",size,newSize,qPrint(srcBuf));
5927 }
5928 else
5929 {
5930 term("{}: failed to translate characters from {} to {}: check INPUT_ENCODING\n",
5931 fileName,inputEncoding,outputEncoding);
5932 }
5934}
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 1376 of file util.cpp.

1377{
1378 const char *outputEncoding = "UTF-8";
1379 if (inputEncoding==nullptr || qstricmp(inputEncoding,outputEncoding)==0) return true;
1380 size_t inputSize=input.length();
1381 size_t outputSize=inputSize*4;
1382 QCString output(outputSize, QCString::ExplicitSize);
1383 void *cd = portable_iconv_open(outputEncoding,inputEncoding);
1384 if (cd==reinterpret_cast<void *>(-1))
1385 {
1386 return false;
1387 }
1388 bool ok=true;
1389 size_t iLeft=inputSize;
1390 size_t oLeft=outputSize;
1391 const char *inputPtr = input.data();
1392 char *outputPtr = output.rawData();
1393 if (!portable_iconv(cd, &inputPtr, &iLeft, &outputPtr, &oLeft))
1394 {
1395 outputSize-=static_cast<int>(oLeft);
1396 output.resize(outputSize);
1397 output.at(outputSize)='\0';
1398 // replace input
1399 input=output.str();
1400 //printf("iconv: input size=%d output size=%d\n[%s]\n",size,newSize,qPrint(srcBuf));
1401 }
1402 else
1403 {
1404 ok=false;
1405 }
1407 return ok;
1408}
@ ExplicitSize
Definition qcstring.h:133

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

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

◆ trimBaseClassScope()

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

Definition at line 1451 of file util.cpp.

1452{
1453 //printf("trimBaseClassScope level=%d '%s'\n",level,qPrint(s));
1454 for (const auto &bcd : bcl)
1455 {
1456 ClassDef *cd=bcd.classDef;
1457 //printf("Trying class %s\n",qPrint(cd->name()));
1458 int spos=s.find(cd->name()+"::");
1459 if (spos!=-1)
1460 {
1461 s = s.left(spos)+s.right(
1462 s.length()-spos-cd->name().length()-2
1463 );
1464 }
1465 //printf("base class '%s'\n",qPrint(cd->name()));
1466 if (!cd->baseClasses().empty())
1467 {
1468 trimBaseClassScope(cd->baseClasses(),s,level+1);
1469 }
1470 }
1471}
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:1451

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

3858{
3859 if (s.isEmpty()) return s;
3860 bool caseSenseNames = getCaseSenseNames();
3861 QCString result;
3862 const char *p = s.data();
3863 if (p)
3864 {
3865 char c = 0;
3866 while ((c=*p++))
3867 {
3868 if (c=='_') // 2 or 3 character escape
3869 {
3870 switch (*p)
3871 {
3872 case '_': result+=c; p++; break; // __ -> '_'
3873 case '1': result+=':'; p++; break; // _1 -> ':'
3874 case '2': result+='/'; p++; break; // _2 -> '/'
3875 case '3': result+='<'; p++; break; // _3 -> '<'
3876 case '4': result+='>'; p++; break; // _4 -> '>'
3877 case '5': result+='*'; p++; break; // _5 -> '*'
3878 case '6': result+='&'; p++; break; // _6 -> '&'
3879 case '7': result+='|'; p++; break; // _7 -> '|'
3880 case '8': result+='.'; p++; break; // _8 -> '.'
3881 case '9': result+='!'; p++; break; // _9 -> '!'
3882 case '0': // 3 character escape
3883 switch (*(p+1))
3884 {
3885 case '0': result+=','; p+=2; break; // _00 -> ','
3886 case '1': result+=' '; p+=2; break; // _01 -> ' '
3887 case '2': result+='{'; p+=2; break; // _02 -> '{'
3888 case '3': result+='}'; p+=2; break; // _03 -> '}'
3889 case '4': result+='?'; p+=2; break; // _04 -> '?'
3890 case '5': result+='^'; p+=2; break; // _05 -> '^'
3891 case '6': result+='%'; p+=2; break; // _06 -> '%'
3892 case '7': result+='('; p+=2; break; // _07 -> '('
3893 case '8': result+=')'; p+=2; break; // _08 -> ')'
3894 case '9': result+='+'; p+=2; break; // _09 -> '+'
3895 case 'a': result+='='; p+=2; break; // _0a -> '='
3896 case 'b': result+='$'; p+=2; break; // _0b -> '$'
3897 case 'c': result+='\\'; p+=2; break;// _0c -> '\'
3898 case 'd': result+='@'; p+=2; break; // _0d -> '@'
3899 case 'e': result+=']'; p+=2; break; // _0e -> ']'
3900 case 'f': result+='['; p+=2; break; // _0f -> '['
3901 case 'g': result+='#'; p+=2; break; // _0g -> '#'
3902 case 'h': result+='"'; p+=2; break; // _0h -> '"'
3903 case 'i': result+='~'; p+=2; break; // _0i -> '~'
3904 case 'j': result+='\''; p+=2; break;// _0j -> '\'
3905 case 'k': result+=';'; p+=2; break; // _0k -> ';'
3906 case 'l': result+='`'; p+=2; break; // _0l -> '`'
3907 default: // unknown escape, just pass underscore character as-is
3908 result+=c;
3909 break;
3910 }
3911 break;
3912 default:
3913 if (!caseSenseNames && c>='a' && c<='z') // lower to upper case escape, _a -> 'A'
3914 {
3915 result+=static_cast<char>(toupper(*p));
3916 p++;
3917 }
3918 else // unknown escape, pass underscore character as-is
3919 {
3920 result+=c;
3921 }
3922 break;
3923 }
3924 }
3925 else // normal character; pass as is
3926 {
3927 result+=c;
3928 }
3929 }
3930 }
3931 return result;
3932}

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

◆ updateColumnCount()

size_t updateColumnCount ( const char * s,
size_t col )

Definition at line 7304 of file util.cpp.

7305{
7306 if (s)
7307 {
7308 const int tabSize = Config_getInt(TAB_SIZE);
7309 char c;
7310 while ((c=*s++))
7311 {
7312 switch(c)
7313 {
7314 case '\t': col+=tabSize - (col%tabSize);
7315 break;
7316 case '\n': col=0;
7317 break;
7318 default:
7319 col++;
7320 if (c<0) // multi-byte character
7321 {
7322 int numBytes = getUTF8CharNumBytes(c);
7323 for (int i=0;i<numBytes-1 && (c=*s++);i++) {} // skip over extra chars
7324 if (c==0) return col; // end of string half way a multibyte char
7325 }
7326 break;
7327 }
7328 }
7329 }
7330 return col;
7331}

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

5541{
5542 QCString langName = language.lower();
5543 auto it1 = std::find_if(g_lang2extMap.begin(),g_lang2extMap.end(),
5544 [&langName](const auto &info) { return info.langName==langName; });
5545 if (it1 == g_lang2extMap.end()) return false;
5546
5547 // found the language
5548 SrcLangExt parserId = it1->parserId;
5549 QCString extName = extension.lower();
5550 if (extName.isEmpty()) return FALSE;
5551 if (extName.at(0)!='.') extName.prepend(".");
5552 auto it2 = g_extLookup.find(extName.str());
5553 if (it2!=g_extLookup.end())
5554 {
5555 g_extLookup.erase(it2); // language was already register for this ext
5556 }
5557 //printf("registering extension %s\n",qPrint(extName));
5558 g_extLookup.emplace(extName.str(),parserId);
5559 if (!Doxygen::parserManager->registerExtension(extName,it1->parserName))
5560 {
5561 err("Failed to assign extension {} to parser {} for language {}\n",
5562 extName.data(),it1->parserName,language);
5563 }
5564 else
5565 {
5566 //msg("Registered extension {} to language parser {}...\n",
5567 // extName,language);
5568 }
5569 return TRUE;
5570}
SrcLangExt
Language as given by extension.
Definition types.h:42

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

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

◆ writeColoredImgData()

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

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

Definition at line 6191 of file util.cpp.

6192{
6193 int hue = Config_getInt(HTML_COLORSTYLE_HUE);
6194 int sat = Config_getInt(HTML_COLORSTYLE_SAT);
6195 int gamma = Config_getInt(HTML_COLORSTYLE_GAMMA);
6196 while (data->name)
6197 {
6198 QCString fileName = dir+"/"+data->name;
6199 ColoredImage img(data->width,data->height,data->content,data->alpha,
6200 sat,hue,gamma);
6201 if (!img.save(fileName))
6202 {
6203 fprintf(stderr,"Warning: Cannot open file %s for writing\n",data->name);
6204 }
6205 Doxygen::indexList->addImageFile(data->name);
6206 data++;
6207 }
6208}
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:416
unsigned short height
Definition util.h:415
const unsigned char * alpha
Definition util.h:417
unsigned short width
Definition util.h:414
const char * name
Definition util.h:413

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

Referenced by ResourceMgr::copyResourceAs().

◆ writeExamples()

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

Definition at line 1127 of file util.cpp.

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

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

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

◆ writeMarkerList()

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

Definition at line 1103 of file util.cpp.

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

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

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

◆ writePageRef()

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

◆ writeString() [1/2]

out writeString ( lastPart ,
keepSpaces  )

References lastPart.

◆ writeString() [2/2]

out writeString ( part ,
keepSpaces  )

◆ writeTypeConstraints()

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

Definition at line 5851 of file util.cpp.

5852{
5853 if (al.empty()) return;
5854 ol.startConstraintList(theTranslator->trTypeConstraints());
5855 for (const Argument &a : al)
5856 {
5858 ol.parseText(a.name);
5859 ol.endConstraintParam();
5861 linkifyText(TextGeneratorOLImpl(ol),d,nullptr,nullptr,a.type);
5862 ol.endConstraintType();
5864 ol.generateDoc(d->docFile(),d->docLine(),d,nullptr,a.docs,TRUE,FALSE,
5865 QCString(),FALSE,FALSE,Config_getBool(MARKDOWN_SUPPORT));
5866 ol.endConstraintDocs();
5867 }
5868 ol.endConstraintList();
5869}
virtual int docLine() const =0
void endConstraintType()
Definition outputlist.h:713
void endConstraintList()
Definition outputlist.h:719
void startConstraintParam()
Definition outputlist.h:707
void startConstraintDocs()
Definition outputlist.h:715
void startConstraintType()
Definition outputlist.h:711
void endConstraintDocs()
Definition outputlist.h:717
void generateDoc(const QCString &fileName, int startLine, const Definition *ctx, const MemberDef *md, const QCString &docStr, bool indexWords, bool isExample, const QCString &exampleName, bool singleLine, bool linkFromIndex, bool markdownSupport)
void endConstraintParam()
Definition outputlist.h:709
void startConstraintList(const QCString &header)
Definition outputlist.h:705
Implements TextGeneratorIntf for an OutputDocInterface stream.
Definition util.h:77
void linkifyText(const TextGeneratorIntf &out, const Definition *scope, const FileDef *fileScope, const Definition *self, const QCString &text, bool autoBreak, bool external, bool keepSpaces, int indentLevel)
Definition util.cpp:904

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

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

Variable Documentation

◆ constScope

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

Definition at line 531 of file util.cpp.

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

Referenced by removeRedundantWhiteSpace().

◆ else

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

Definition at line 973 of file util.cpp.

◆ found

bool found =FALSE

Definition at line 984 of file util.cpp.

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

◆ g_charAroundSpace

CharAroundSpace g_charAroundSpace
static

Definition at line 575 of file util.cpp.

Referenced by removeRedundantWhiteSpace().

◆ g_extLookup

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

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

5517{
5518// language parser parser option
5519 { "idl", "c", SrcLangExt::IDL, ".idl" },
5520 { "java", "c", SrcLangExt::Java, ".java"},
5521 { "javascript", "c", SrcLangExt::JS, ".js" },
5522 { "csharp", "c", SrcLangExt::CSharp, ".cs" },
5523 { "d", "c", SrcLangExt::D, ".d" },
5524 { "php", "c", SrcLangExt::PHP, ".php" },
5525 { "objective-c", "c", SrcLangExt::ObjC, ".m" },
5526 { "c", "c", SrcLangExt::Cpp, ".c" },
5527 { "c++", "c", SrcLangExt::Cpp, ".cpp" },
5528 { "slice", "c", SrcLangExt::Slice, ".ice" },
5529 { "python", "python", SrcLangExt::Python, ".py" },
5530 { "fortran", "fortran", SrcLangExt::Fortran, ".f" },
5531 { "fortranfree", "fortranfree", SrcLangExt::Fortran, ".f90" },
5532 { "fortranfixed", "fortranfixed", SrcLangExt::Fortran, ".f" },
5533 { "vhdl", "vhdl", SrcLangExt::VHDL, ".vhdl"},
5534 { "xml", "xml", SrcLangExt::XML, ".xml" },
5535 { "sql", "sql", SrcLangExt::SQL, ".sql" },
5536 { "md", "md", SrcLangExt::Markdown, ".md" },
5537 { "lex", "lex", SrcLangExt::Lex, ".l" },
5538};

Referenced by getLanguageFromCodeLang(), and updateLanguageMapping().

◆ g_matchArgsMutex

std::mutex g_matchArgsMutex
static

Definition at line 1823 of file util.cpp.

Referenced by matchArgument2().

◆ g_usedNames

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

Definition at line 3934 of file util.cpp.

Referenced by convertNameToFile().

◆ g_usedNamesCount

int g_usedNamesCount =1
static

Definition at line 3936 of file util.cpp.

Referenced by convertNameToFile().

◆ g_usedNamesMutex

std::mutex g_usedNamesMutex
static

Definition at line 3935 of file util.cpp.

Referenced by convertNameToFile().

◆ hex

const char* hex = "0123456789ABCDEF"
static

Definition at line 97 of file util.cpp.

◆ lastPart

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

Definition at line 1099 of file util.cpp.

Referenced by writeString().

◆ matchWord

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

Definition at line 981 of file util.cpp.

Referenced by if().

◆ maxInheritanceDepth

const int maxInheritanceDepth = 100000

Definition at line 156 of file util.cpp.

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

◆ operatorScope

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

Definition at line 534 of file util.cpp.

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

Referenced by removeRedundantWhiteSpace().

◆ skipIndex

skipIndex =index=newIndex+matchLen

Definition at line 1095 of file util.cpp.

Referenced by if(), and linkifyText().

◆ virtualScope

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

Definition at line 533 of file util.cpp.

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

Referenced by removeRedundantWhiteSpace().

◆ volatileScope

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

Definition at line 532 of file util.cpp.

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

Referenced by removeRedundantWhiteSpace().

◆ word