Doxygen
Loading...
Searching...
No Matches
util.h File Reference

A bunch of utility functions. More...

#include <memory>
#include <unordered_map>
#include <algorithm>
#include <functional>
#include <fstream>
#include <variant>
#include <string_view>
#include <ctype.h>
#include "types.h"
#include "docparser.h"
#include "containers.h"
#include "outputgen.h"
#include "regex.h"
#include "conceptdef.h"
#include "construct.h"
+ Include dependency graph for util.h:
+ This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

class  TextGeneratorIntf
 Abstract interface for a hyperlinked text fragment. More...
 
class  TextGeneratorOLImpl
 Implements TextGeneratorIntf for an OutputDocInterface stream. More...
 
struct  GetDefInput
 
struct  GetDefResult
 
struct  SelectionBlock
 
struct  SelectionMarkerInfo
 
struct  KeywordSubstitution
 
struct  ColoredImgDataItem
 Data associated with a HSV colored image. More...
 

Typedefs

using SelectionBlockList = std::vector<SelectionBlock>
 
using KeywordSubstitutionList = std::vector<KeywordSubstitution>
 

Functions

QCString langToString (SrcLangExt lang)
 Returns a string representation of lang.
 
QCString getLanguageSpecificSeparator (SrcLangExt lang, bool classScope=FALSE)
 Returns the scope separator to use given the programming language lang.
 
void linkifyText (const TextGeneratorIntf &ol, const Definition *scope, const FileDef *fileScope, const Definition *self, const QCString &text, bool autoBreak=FALSE, bool external=TRUE, bool keepSpaces=FALSE, int indentLevel=0)
 
QCString fileToString (const QCString &name, bool filter=FALSE, bool isSourceCode=FALSE)
 
GetDefResult getDefs (const GetDefInput &input)
 
QCString getFileFilter (const QCString &name, bool isSourceCode)
 
bool resolveRef (const QCString &scName, const QCString &name, bool inSeeBlock, const Definition **resContext, const MemberDef **resMember, bool lookForSpecializations=TRUE, const FileDef *currentFile=nullptr, bool checkScope=FALSE)
 
bool resolveLink (const QCString &scName, const QCString &lr, bool inSeeBlock, const Definition **resContext, QCString &resAnchor, const QCString &prefix=QCString())
 
void generateFileRef (OutputList &ol, const QCString &, const QCString &linkTxt=QCString())
 
void writePageRef (OutputList &ol, const QCString &cn, const QCString &mn)
 
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 &, ArgumentList &, bool forceNameOverwrite=FALSE)
 
QCString substituteClassNames (const QCString &s)
 
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)
 
FileDeffindFileDef (const FileNameLinkedMap *fnMap, const QCString &n, bool &ambig)
 
QCString findFilePath (const QCString &file, bool &ambig)
 
QCString showFileDefMatches (const FileNameLinkedMap *fnMap, const QCString &n)
 
EntryType guessSection (const QCString &name)
 
bool isId (int c)
 
bool isIdJS (int c)
 
QCString removeRedundantWhiteSpace (const QCString &s)
 
QCString inlineArgListToDoc (const ArgumentList &al)
 
QCString argListToString (const ArgumentList &al, bool useCanonicalType=FALSE, bool showDefVals=TRUE)
 
QCString tempArgListToString (const ArgumentList &al, SrcLangExt lang, bool includeDefaults=true)
 
QCString generateMarker (int id)
 
void writeExamples (OutputList &ol, const ExampleList &el)
 
QCString stripAnonymousNamespaceScope (const QCString &s)
 
QCString stripFromPath (const QCString &path)
 
QCString stripFromIncludePath (const QCString &path)
 
bool rightScopeMatch (const QCString &scope, const QCString &name)
 
bool leftScopeMatch (const QCString &scope, const QCString &name)
 
QCString substituteKeywords (const QCString &s, const KeywordSubstitutionList &keywords)
 
QCString substituteKeywords (const QCString &s, const QCString &title, const QCString &projName, const QCString &projNum, const QCString &projBrief)
 
int getPrefixIndex (const QCString &name)
 
QCString removeAnonymousScopes (const QCString &s)
 
QCString replaceAnonymousScopes (const QCString &s, const QCString &replacement=QCString())
 
QCString convertNameToFile (const QCString &name, bool allowDots=FALSE, bool allowUnderscore=FALSE)
 
QCString generateAnonymousAnchor (const QCString &fileName, int count)
 
void extractNamespaceName (const QCString &scopeName, QCString &className, QCString &namespaceName, bool allowEmptyClass=FALSE)
 
QCString insertTemplateSpecifierInScope (const QCString &scope, const QCString &templ)
 
QCString stripScope (const QCString &name)
 
QCString convertToId (const QCString &s)
 
QCString correctId (const QCString &s)
 
QCString convertToHtml (const QCString &s, bool keepEntities=TRUE)
 
QCString convertToXML (const QCString &s, bool keepEntities=FALSE)
 
QCString convertToJSString (const QCString &s)
 
QCString getOverloadDocs ()
 
void addMembersToMemberGroup (MemberList *ml, MemberGroupList *pMemberGroups, const Definition *context)
 
int extractClassNameFromType (const QCString &type, int &pos, QCString &name, QCString &templSpec, SrcLangExt=SrcLangExt::Unknown)
 
QCString normalizeNonTemplateArgumentsInString (const QCString &name, const Definition *context, const ArgumentList &formalArgs)
 
QCString substituteTemplateArgumentsInString (const QCString &name, const ArgumentList &formalArgs, const ArgumentList *actualArgs)
 
QCString stripTemplateSpecifiersFromScope (const QCString &fullName, bool parentOnly=TRUE, QCString *lastScopeStripped=nullptr, QCString scopeName=QCString(), bool allowArtificial=true)
 
QCString resolveTypeDef (const Definition *d, const QCString &name, const Definition **typedefContext=nullptr)
 
QCString mergeScopes (const QCString &leftScope, const QCString &rightScope)
 
int getScopeFragment (const QCString &s, int p, int *l)
 
void addRefItem (const RefItemVector &sli, const QCString &key, const QCString &prefix, const QCString &name, const QCString &title, const QCString &args, const Definition *scope)
 
PageDefaddRelatedPage (const QCString &name, const QCString &ptitle, const QCString &doc, const QCString &fileName, int docLine, int startLine, const RefItemVector &sli=RefItemVector(), GroupDef *gd=nullptr, const TagInfo *tagInfo=nullptr, bool xref=FALSE, SrcLangExt lang=SrcLangExt::Unknown)
 
bool getCaseSenseNames ()
 
QCString escapeCharsInString (const QCString &name, bool allowDots, bool allowUnderscore=FALSE)
 
QCString unescapeCharsInString (const QCString &s)
 
void addGroupListToTitle (OutputList &ol, const Definition *d)
 
QCString linkToText (SrcLangExt lang, const QCString &link, bool isFileName)
 
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)
 
int computeQualifiedIndex (const QCString &name)
 Return the index of the last :: in the string name that is still before the first <.
 
void addDirPrefix (QCString &fileName)
 
QCString relativePathToRoot (const QCString &name)
 
QCString determineAbsoluteIncludeName (const QCString &curFile, const QCString &incFileName)
 
void createSubDirs (const Dir &d)
 
void clearSubDirs (const Dir &d)
 
QCString removeLongPathMarker (QCString path)
 
QCString stripPath (const QCString &s)
 
bool containsWord (const QCString &s, const char *word)
 returns TRUE iff string s contains word w
 
bool findAndRemoveWord (QCString &s, 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 &parser)
 
SrcLangExt getLanguageFromFileName (const QCString &fileName, SrcLangExt defLang=SrcLangExt::Cpp)
 
SrcLangExt getLanguageFromCodeLang (QCString &fileName)
 Routine to handle the language attribute of the \code command.
 
QCString getFileNameExtension (const QCString &fn)
 
void initDefaultExtensionMapping ()
 
void addCodeOnlyMappings ()
 
bool checkIfTypedef (const Definition *scope, const FileDef *fileScope, const QCString &n)
 
QCString parseCommentAsText (const Definition *scope, const MemberDef *member, const QCString &doc, const QCString &fileName, int lineNr)
 
bool transcodeCharacterStringToUTF8 (std::string &input, const char *inputEncoding)
 
QCString recodeString (const QCString &str, const char *fromEncoding, const char *toEncoding)
 
void writeTypeConstraints (OutputList &ol, const Definition *d, const ArgumentList &al)
 
QCString convertCharEntitiesToUTF8 (const QCString &s)
 
void stackTrace ()
 
bool readInputFile (const QCString &fileName, std::string &contents, bool filter=TRUE, bool isSourceCode=FALSE)
 read a file name fileName and optionally filter and transcode it
 
QCString filterTitle (const QCString &title)
 
bool patternMatch (const FileInfo &fi, const StringVector &patList)
 
QCString externalLinkTarget (const bool parent=false)
 
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)
 
int nextUtf8CharPosition (const QCString &utf8Str, uint32_t len, uint32_t startPos)
 
void writeMarkerList (OutputList &ol, const std::string &markerText, size_t numMarkers, std::function< void(size_t)> replaceFunc)
 
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.
 
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.
 
QCString processMarkup (const QCString &s)
 
bool protectionLevelVisible (Protection prot)
 
QCString stripIndentation (const QCString &s)
 
void stripIndentationVerbatim (QCString &doc, const int indentationLevel)
 
QCString getDotImageExtension ()
 
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 ()
 
bool openOutputFile (const QCString &outFile, std::ofstream &f)
 
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 &s, const std::string &delimiter)
 create a string where the string in the vector are joined by the given delimiter
 
bool recognizeFixedForm (const QCString &contents, FortranFormat format)
 
FortranFormat convertFileNameFortranParserCode (QCString fn)
 
QCString integerToAlpha (int n, bool upper=true)
 
QCString integerToRoman (int n, bool upper=true)
 
QCString getEncoding (const FileInfo &fi)
 
QCString fixSpaces (const QCString &s)
 
QCString detab (const QCString &s, size_t &refIndent)
 
QCString getProjectId ()
 
QCString projectLogoFile ()
 
void mergeMemberOverrideOptions (MemberDefMutable *md1, MemberDefMutable *md2)
 
size_t updateColumnCount (const char *s, size_t col)
 

Detailed Description

A bunch of utility functions.

Definition in file util.h.

Typedef Documentation

◆ KeywordSubstitutionList

Definition at line 241 of file util.h.

◆ SelectionBlockList

using SelectionBlockList = std::vector<SelectionBlock>

Definition at line 176 of file util.h.

Function Documentation

◆ addCodeOnlyMappings()

void addCodeOnlyMappings ( )

Definition at line 5543 of file util.cpp.

5544{
5545 updateLanguageMapping(".xml", "xml");
5546 updateLanguageMapping(".sql", "sql");
5547}
bool updateLanguageMapping(const QCString &extension, const QCString &language)
Definition util.cpp:5444

References updateLanguageMapping().

Referenced by generateOutput().

◆ addDirPrefix()

void addDirPrefix ( QCString & fileName)

◆ addGroupListToTitle()

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

◆ addHtmlExtensionIfMissing()

void addHtmlExtensionIfMissing ( QCString & fName)

Definition at line 5243 of file util.cpp.

5244{
5245 if (fName.isEmpty()) return;
5246 int i_fs = fName.findRev('/');
5247 int i_bs = fName.findRev('\\');
5248 int i = fName.find('.',std::max({ i_fs, i_bs ,0})); // search for . after path part
5249 if (i==-1)
5250 {
5252 }
5253}
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 4448 of file util.cpp.

4451{
4452 ASSERT(context!=nullptr);
4453 //printf("addMemberToMemberGroup() context=%s\n",qPrint(context->name()));
4454 if (ml==nullptr) return;
4455
4456 struct MoveMemberInfo
4457 {
4458 MoveMemberInfo(MemberDef *md,MemberGroup *mg,const RefItemVector &rv)
4459 : memberDef(md), memberGroup(mg), sli(rv) {}
4460 MemberDef *memberDef;
4461 MemberGroup *memberGroup;
4462 RefItemVector sli;
4463 };
4464 std::vector<MoveMemberInfo> movedMembers;
4465
4466 for (const auto &md : *ml)
4467 {
4468 if (md->isEnumerate()) // insert enum value of this enum into groups
4469 {
4470 for (const auto &fmd : md->enumFieldList())
4471 {
4472 int groupId=fmd->getMemberGroupId();
4473 if (groupId!=-1)
4474 {
4475 auto it = Doxygen::memberGroupInfoMap.find(groupId);
4477 {
4478 const auto &info = it->second;
4479 auto mg_it = std::find_if(pMemberGroups->begin(),
4480 pMemberGroups->end(),
4481 [&groupId](const auto &g)
4482 { return g->groupId()==groupId; }
4483 );
4484 MemberGroup *mg_ptr = nullptr;
4485 if (mg_it==pMemberGroups->end())
4486 {
4487 auto mg = std::make_unique<MemberGroup>(
4488 context,
4489 groupId,
4490 info->header,
4491 info->doc,
4492 info->docFile,
4493 info->docLine,
4494 ml->container());
4495 mg_ptr = mg.get();
4496 pMemberGroups->push_back(std::move(mg));
4497 }
4498 else
4499 {
4500 mg_ptr = (*mg_it).get();
4501 }
4502 mg_ptr->insertMember(fmd); // insert in member group
4504 if (fmdm)
4505 {
4506 fmdm->setMemberGroup(mg_ptr);
4507 }
4508 }
4509 }
4510 }
4511 }
4512 int groupId=md->getMemberGroupId();
4513 if (groupId!=-1)
4514 {
4515 auto it = Doxygen::memberGroupInfoMap.find(groupId);
4517 {
4518 const auto &info = it->second;
4519 auto mg_it = std::find_if(pMemberGroups->begin(),
4520 pMemberGroups->end(),
4521 [&groupId](const auto &g)
4522 { return g->groupId()==groupId; }
4523 );
4524 MemberGroup *mg_ptr = nullptr;
4525 if (mg_it==pMemberGroups->end())
4526 {
4527 auto mg = std::make_unique<MemberGroup>(
4528 context,
4529 groupId,
4530 info->header,
4531 info->doc,
4532 info->docFile,
4533 info->docLine,
4534 ml->container());
4535 mg_ptr = mg.get();
4536 pMemberGroups->push_back(std::move(mg));
4537 }
4538 else
4539 {
4540 mg_ptr = (*mg_it).get();
4541 }
4542 movedMembers.emplace_back(md,mg_ptr,info->m_sli);
4543 }
4544 }
4545 }
4546
4547 // move the members to their group
4548 for (const auto &mmi : movedMembers)
4549 {
4550 ml->remove(mmi.memberDef); // remove from member list
4551 mmi.memberGroup->insertMember(mmi.memberDef->resolveAlias()); // insert in member group
4552 mmi.memberGroup->setRefItems(mmi.sli);
4553 MemberDefMutable *rmdm = toMemberDefMutable(mmi.memberDef);
4554 if (rmdm)
4555 {
4556 rmdm->setMemberGroup(mmi.memberGroup);
4557 }
4558 }
4559}
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 5146 of file util.cpp.

5149{
5150 //printf("addRefItem(sli=%d,key=%s,prefix=%s,name=%s,title=%s,args=%s)\n",(int)sli.size(),key,prefix,name,title,args);
5151 if (!key.isEmpty() && key[0]!='@') // check for @ to skip anonymous stuff (see bug427012)
5152 {
5153 for (RefItem *item : sli)
5154 {
5155 item->setPrefix(prefix);
5156 item->setScope(scope);
5157 item->setName(name);
5158 item->setTitle(title);
5159 item->setArgs(args);
5160 item->setGroup(key);
5161 }
5162 }
5163}
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 = RefItemVector(),
GroupDef * gd = nullptr,
const TagInfo * tagInfo = nullptr,
bool xref = FALSE,
SrcLangExt lang = SrcLangExt::Unknown )

Definition at line 5016 of file util.cpp.

5027{
5028 PageDef *pd=nullptr;
5029 //printf("addRelatedPage(name=%s gd=%p)\n",qPrint(name),gd);
5030 QCString title=ptitle.stripWhiteSpace();
5031 bool newPage = true;
5032 if ((pd=Doxygen::pageLinkedMap->find(name)) && !pd->isReference())
5033 {
5034 if (!xref && !title.isEmpty() && pd->title()!=pd->name() && pd->title()!=title)
5035 {
5036 warn(fileName,startLine,"multiple use of page label '%s' with different titles, (other occurrence: %s, line: %d)",
5037 qPrint(name),qPrint(pd->docFile()),pd->getStartBodyLine());
5038 }
5039 if (!title.isEmpty() && pd->title()==pd->name()) // pd has no real title yet
5040 {
5041 pd->setTitle(title);
5043 if (si)
5044 {
5045 si->setTitle(title);
5046 }
5047 }
5048 // append documentation block to the page.
5049 pd->setDocumentation(doc,fileName,docLine);
5050 //printf("Adding page docs '%s' pi=%p name=%s\n",qPrint(doc),pd,name);
5051 // append (x)refitems to the page.
5052 pd->setRefItems(sli);
5053 newPage = false;
5054 }
5055
5056 if (newPage) // new page
5057 {
5058 QCString baseName=name;
5059 if (baseName.endsWith(".tex"))
5060 baseName=baseName.left(baseName.length()-4);
5061 else if (baseName.right(Doxygen::htmlFileExtension.length())==Doxygen::htmlFileExtension)
5062 baseName=baseName.left(baseName.length()-Doxygen::htmlFileExtension.length());
5063
5064 //printf("Appending page '%s'\n",qPrint(baseName));
5065 if (pd) // replace existing page
5066 {
5067 pd->setDocumentation(doc,fileName,docLine);
5069 pd->setShowLineNo(FALSE);
5070 pd->setNestingLevel(0);
5071 pd->setPageScope(nullptr);
5072 pd->setTitle(title);
5073 pd->setReference(QCString());
5074 }
5075 else // newPage
5076 {
5077 pd = Doxygen::pageLinkedMap->add(baseName,
5078 createPageDef(fileName,docLine,baseName,doc,title));
5079 }
5080 pd->setBodySegment(startLine,startLine,-1);
5081
5082 pd->setRefItems(sli);
5083 pd->setLanguage(lang);
5084
5085 if (tagInfo)
5086 {
5087 pd->setReference(tagInfo->tagName);
5088 pd->setFileName(tagInfo->fileName);
5089 }
5090
5091 if (gd) gd->addPage(pd);
5092
5093 if (pd->hasTitle())
5094 {
5095 //outputList->writeTitle(pi->name,pi->title);
5096
5097 // a page name is a label as well!
5098 QCString file;
5099 QCString orgFile;
5100 int line = -1;
5101 if (gd)
5102 {
5103 file=gd->getOutputFileBase();
5104 orgFile=gd->getOutputFileBase();
5105 }
5106 else
5107 {
5108 file=pd->getOutputFileBase();
5109 orgFile=pd->docFile();
5110 line = pd->getStartBodyLine();
5111 }
5112 const SectionInfo *si = SectionManager::instance().find(pd->name());
5113 if (si)
5114 {
5115 if (!si->ref().isEmpty()) // we are from a tag file
5116 {
5118 file,-1,pd->title(),SectionType::Page,0,pd->getReference());
5119 }
5120 else if (si->lineNr() != -1)
5121 {
5122 warn(orgFile,line,"multiple use of section label '%s', (first occurrence: %s, line %d)",qPrint(pd->name()),qPrint(si->fileName()),si->lineNr());
5123 }
5124 else
5125 {
5126 warn(orgFile,line,"multiple use of section label '%s', (first occurrence: %s)",qPrint(pd->name()),qPrint(si->fileName()));
5127 }
5128 }
5129 else
5130 {
5132 file,-1,pd->title(),SectionType::Page,0,pd->getReference());
5133 //printf("si->label='%s' si->definition=%s si->fileName='%s'\n",
5134 // qPrint(si->label),si->definition?si->definition->name().data():"<none>",
5135 // qPrint(si->fileName));
5136 //printf(" SectionInfo: sec=%p sec->fileName=%s\n",si,qPrint(si->fileName));
5137 //printf("Adding section key=%s si->fileName=%s\n",qPrint(pageName),qPrint(si->fileName));
5138 }
5139 }
5140 }
5141 return pd;
5142}
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
Find an object given the key.
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:504
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())
Replace an existing section with a new one Return a non-owning pointer to the newly added section.
Definition section.h:154
SectionInfo * add(const SectionInfo &si)
Add a new section given the data of an existing section.
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:59
std::unique_ptr< PageDef > createPageDef(const QCString &f, int l, const QCString &n, const QCString &d, const QCString &t)
Definition pagedef.cpp:79
const char * qPrint(const char *s)
Definition qcstring.h:661
#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:3858

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, qPrint(), 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 = FALSE,
bool showDefVals = TRUE )

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(), findGlobalMember(), findMember(), SymbolResolver::Private::getResolvedSymbol(), matchArguments2(), mergeArguments(), and substituteTemplateArgumentsInString().

◆ checkBlocks()

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

Definition at line 6849 of file util.cpp.

6850{
6851 if (s.isEmpty()) return;
6852
6853 const char *p = s.data();
6854 char c = 0;
6855 while ((c=*p))
6856 {
6857 if (c==markerInfo.markerChar) // potential start of marker
6858 {
6859 if (qstrncmp(p,markerInfo.beginStr,markerInfo.beginLen)==0) // start of begin marker
6860 {
6861 size_t len = markerInfo.beginLen;
6862 bool negate = *(p+len)=='!';
6863 if (negate) len++;
6864 p += len;
6865 QCString marker;
6866 while (*p)
6867 {
6868 if (markerInfo.closeLen==0 && *p=='\n') // matching end of line
6869 {
6870 warn(fileName,-1,"Remaining begin replacement with marker '%s'",qPrint(marker));
6871 break;
6872 }
6873 else if (markerInfo.closeLen!= 0 && qstrncmp(p,markerInfo.closeStr,markerInfo.closeLen)==0) // matching marker closing
6874 {
6875 p += markerInfo.closeLen;
6876 warn(fileName,-1,"Remaining begin replacement with marker '%s'",qPrint(marker));
6877 break;
6878 }
6879 marker += *p;
6880 p++;
6881 }
6882 }
6883 else if (qstrncmp(p,markerInfo.endStr,markerInfo.endLen)==0) // start of end marker
6884 {
6885 size_t len = markerInfo.endLen;
6886 bool negate = *(p+len)=='!';
6887 if (negate) len++;
6888 p += len;
6889 QCString marker;
6890 while (*p)
6891 {
6892 if (markerInfo.closeLen==0 && *p=='\n') // matching end of line
6893 {
6894 warn(fileName,-1,"Remaining end replacement with marker '%s'",qPrint(marker));
6895 break;
6896 }
6897 else if (markerInfo.closeLen!= 0 && qstrncmp(p,markerInfo.closeStr,markerInfo.closeLen)==0) // matching marker closing
6898 {
6899 p += markerInfo.closeLen;
6900 warn(fileName,-1,"Remaining end replacement with marker '%s'",qPrint(marker));
6901 break;
6902 }
6903 marker += *p;
6904 p++;
6905 }
6906 }
6907 }
6908 p++;
6909 }
6910}
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:182
const char * closeStr
Definition util.h:185
const char * beginStr
Definition util.h:181
size_t closeLen
Definition util.h:186
const char * endStr
Definition util.h:183

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

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

◆ checkExtension()

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

Definition at line 5238 of file util.cpp.

5239{
5240 return fName.right(ext.length())==ext;
5241}

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

5654{
5655 MemberDef *bestMatch = getMemberFromSymbol(scope,fileScope,n);
5656
5657 if (bestMatch && bestMatch->isTypedef())
5658 return TRUE; // closest matching symbol is a typedef
5659 else
5660 return FALSE;
5661}
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:5601

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

Referenced by isVarWithConstructor().

◆ clearSubDirs()

void clearSubDirs ( const Dir & d)

Definition at line 4021 of file util.cpp.

4022{
4023 if (Config_getBool(CREATE_SUBDIRS))
4024 {
4025 // remove empty subdirectories
4026 int createSubdirsLevelPow2 = 1 << Config_getInt(CREATE_SUBDIRS_LEVEL);
4027 for (int l1=0;l1<16;l1++)
4028 {
4029 QCString subdir;
4030 subdir.sprintf("d%x",l1);
4031 for (int l2=0; l2 < createSubdirsLevelPow2; l2++)
4032 {
4033 QCString subsubdir;
4034 subsubdir.sprintf("d%x/d%02x",l1,l2);
4035 if (d.exists(subsubdir.str()) && d.isEmpty(subsubdir.str()))
4036 {
4037 d.rmdir(subsubdir.str());
4038 }
4039 }
4040 if (d.exists(subdir.str()) && d.isEmpty(subdir.str()))
4041 {
4042 d.rmdir(subdir.str());
4043 }
4044 }
4045 }
4046}
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:526
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 7151 of file util.cpp.

7152{
7153 int l = static_cast<int>(name.length());
7154 int lastSepPos = -1;
7155 const char *p = name.data();
7156 int i=l-2;
7157 int sharpCount=0;
7158 // --- begin optimized version of ts=name.findRev(">::");
7159 int ts = -1;
7160 while (i>=0)
7161 {
7162 if (p[i]=='>')
7163 {
7164 if (sharpCount==0 && p[i+1]==':' && p[i+2]==':')
7165 {
7166 ts=i;
7167 break;
7168 }
7169 sharpCount++;
7170 }
7171 else if (p[i]=='<')
7172 {
7173 sharpCount--;
7174 }
7175 i--;
7176 }
7177 // --- end optimized version
7178 if (ts==-1) ts=0; else p+=++ts;
7179 for (i=ts;i<l-1;i++)
7180 {
7181 char c=*p++;
7182 if (c==':' && *p==':') lastSepPos=i;
7183 if (c=='<') break;
7184 }
7185 return lastSepPos;
7186}

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

Referenced by addToMap(), getMemberFromSymbol(), SymbolResolver::Private::getResolvedSymbolRec(), and SymbolResolver::Private::getResolvedTypeRec().

◆ containsWord()

bool containsWord ( const QCString & s,
const char * word )

returns TRUE iff string s contains word w

Definition at line 5309 of file util.cpp.

5310{
5311 if (str.isEmpty() || word==nullptr) return false;
5312 static const reg::Ex re(R"(\a+)");
5313 std::string s = str.str();
5314 for (reg::Iterator it(s,re) ; it!=reg::Iterator() ; ++it)
5315 {
5316 if (it->str()==word) return true;
5317 }
5318 return false;
5319}
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 & s)

Definition at line 4398 of file util.cpp.

4399{
4400 if (str.isEmpty()) return QCString();
4401
4402 std::string s = str.data();
4403 static const reg::Ex re(R"(&\a\w*;)");
4404 reg::Iterator it(s,re);
4406
4407 GrowBuf growBuf;
4408 size_t p=0, i=0, l=0;
4409 for (; it!=end ; ++it)
4410 {
4411 const auto &match = *it;
4412 p = match.position();
4413 l = match.length();
4414 if (p>i)
4415 {
4416 growBuf.addStr(s.substr(i,p-i));
4417 }
4418 QCString entity(match.str());
4420 const char *code=nullptr;
4421 if (symType!=HtmlEntityMapper::Sym_Unknown && (code=HtmlEntityMapper::instance().utf8(symType)))
4422 {
4423 growBuf.addStr(code);
4424 }
4425 else
4426 {
4427 growBuf.addStr(entity);
4428 }
4429 i=p+l;
4430 }
4431 growBuf.addStr(s.substr(i));
4432 growBuf.addChar(0);
4433 //printf("convertCharEntitiesToUTF8(%s)->%s\n",qPrint(s),growBuf.get());
4434 return growBuf.get();
4435}
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 6723 of file util.cpp.

6724{
6726 QCString parserName = Doxygen::parserManager->getParserName(ext);
6727
6728 if (parserName == "fortranfixed") return FortranFormat::Fixed;
6729 else if (parserName == "fortranfree") return FortranFormat::Free;
6730
6732}
static ParserManager * parserManager
Definition doxygen.h:131
QCString getFileNameExtension(const QCString &fn)
Definition util.cpp:5591

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

3859{
3860 if (name.isEmpty()) return name;
3861 bool shortNames = Config_getBool(SHORT_NAMES);
3862 bool createSubdirs = Config_getBool(CREATE_SUBDIRS);
3863 QCString result;
3864 if (shortNames) // use short names only
3865 {
3866 std::lock_guard<std::mutex> lock(g_usedNamesMutex);
3867 auto kv = g_usedNames.find(name.str());
3868 uint32_t num=0;
3869 if (kv!=g_usedNames.end())
3870 {
3871 num = kv->second;
3872 }
3873 else
3874 {
3875 num = g_usedNamesCount;
3876 g_usedNames.emplace(name.str(),g_usedNamesCount++);
3877 }
3878 result.sprintf("a%05d",num);
3879 }
3880 else // long names
3881 {
3882 result=escapeCharsInString(name,allowDots,allowUnderscore);
3883 size_t resultLen = result.length();
3884 if (resultLen>=128) // prevent names that cannot be created!
3885 {
3886 // third algorithm based on MD5 hash
3887 uint8_t md5_sig[16];
3888 char sigStr[33];
3889 MD5Buffer(result.data(),static_cast<unsigned int>(resultLen),md5_sig);
3890 MD5SigToString(md5_sig,sigStr);
3891 result=result.left(128-32)+sigStr;
3892 }
3893 }
3894 if (createSubdirs)
3895 {
3896 int l1Dir=0,l2Dir=0;
3897 int createSubdirsLevel = Config_getInt(CREATE_SUBDIRS_LEVEL);
3898 int createSubdirsBitmaskL2 = (1<<createSubdirsLevel)-1;
3899
3900 // compute md5 hash to determine sub directory to use
3901 uint8_t md5_sig[16];
3902 MD5Buffer(result.data(),static_cast<unsigned int>(result.length()),md5_sig);
3903 l1Dir = md5_sig[14] & 0xf;
3904 l2Dir = md5_sig[15] & createSubdirsBitmaskL2;
3905
3906 result.prepend(QCString().sprintf("d%x/d%02x/",l1Dir,l2Dir));
3907 }
3908 //printf("*** convertNameToFile(%s)->%s\n",qPrint(name),qPrint(result));
3909 return result;
3910}
QCString & prepend(const char *s)
Definition qcstring.h:407
static int g_usedNamesCount
Definition util.cpp:3850
QCString escapeCharsInString(const QCString &name, bool allowDots, bool allowUnderscore)
Definition util.cpp:3684
static std::mutex g_usedNamesMutex
Definition util.cpp:3849
static std::unordered_map< std::string, int > g_usedNames
Definition util.cpp:3848

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

6562{
6563 bool extractPrivate = Config_getBool(EXTRACT_PRIVATE);
6564
6565 // default representing 1-1 mapping
6566 *outListType1=inListType;
6567 *outListType2=MemberListType::Invalid();
6568
6569 if (inProt==Protection::Public)
6570 {
6571 if (inListType.isPrivate())
6572 {
6573 *outListType1=MemberListType::Invalid();
6574 }
6575 }
6576 else if (inProt==Protection::Protected)
6577 {
6578 if (inListType.isPrivate() || inListType.isPublic())
6579 {
6580 *outListType1=MemberListType::Invalid();
6581 }
6582 else if (inListType.isProtected())
6583 {
6584 *outListType2=inListType.toPublic();
6585 }
6586 }
6587 else if (inProt==Protection::Private)
6588 {
6589 if (inListType.isPublic() || inListType.isProtected())
6590 {
6591 *outListType1=MemberListType::Invalid();
6592 }
6593 else if (inListType.isPrivate())
6594 {
6595 if (extractPrivate)
6596 {
6597 *outListType1=inListType.toPublic();
6598 *outListType2=inListType.toProtected();
6599 }
6600 else
6601 {
6602 *outListType1=MemberListType::Invalid();
6603 }
6604 }
6605 }
6606
6607 //printf("convertProtectionLevel(type=%s prot=%d): %s,%s\n",
6608 // qPrint(inListType.to_string()),inProt,qPrint(outListType1->to_string()),qPrint(outListType2->to_string()));
6609}
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 4317 of file util.cpp.

4318{
4319 if (s.isEmpty()) return s;
4320 GrowBuf growBuf;
4321 const char *p=s.data();
4322 char c = 0;
4323 while ((c=*p++))
4324 {
4325 switch (c)
4326 {
4327 case '<': growBuf.addStr("&lt;"); break;
4328 case '>': growBuf.addStr("&gt;"); break;
4329 case '&': if (keepEntities)
4330 {
4331 const char *e=p;
4332 char ce = 0;
4333 while ((ce=*e++))
4334 {
4335 if (ce==';' || (!(isId(ce) || ce=='#'))) break;
4336 }
4337 if (ce==';') // found end of an entity
4338 {
4339 // copy entry verbatim
4340 growBuf.addChar(c);
4341 while (p<e) growBuf.addChar(*p++);
4342 }
4343 else
4344 {
4345 growBuf.addStr("&amp;");
4346 }
4347 }
4348 else
4349 {
4350 growBuf.addStr("&amp;");
4351 }
4352 break;
4353 case '\'': growBuf.addStr("&#39;"); break;
4354 case '"': growBuf.addStr("&quot;"); break;
4355 default:
4356 {
4357 uint8_t uc = static_cast<uint8_t>(c);
4358 if (uc<32 && !isspace(c))
4359 {
4360 growBuf.addStr("&#x24");
4361 growBuf.addChar(hex[uc>>4]);
4362 growBuf.addChar(hex[uc&0xF]);
4363 growBuf.addChar(';');
4364 }
4365 else
4366 {
4367 growBuf.addChar(c);
4368 }
4369 }
4370 break;
4371 }
4372 }
4373 growBuf.addChar(0);
4374 return growBuf.get();
4375}
static constexpr auto hex
bool isId(int c)
Definition util.h:202

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

4227{
4228 if (s.isEmpty()) return s;
4229 GrowBuf growBuf;
4230 const char *p = s.data();
4231 char c = 0;
4232 bool first = true;
4233 while ((c=*p++))
4234 {
4235 char encChar[4];
4236 if ((c>='0' && c<='9') || (c>='a' && c<='z') || (c>='A' && c<='Z') || c=='-' || c==':' || c=='.')
4237 { // any permissive character except _
4238 if (first && c>='0' && c<='9') growBuf.addChar('a'); // don't start with a digit
4239 growBuf.addChar(c);
4240 }
4241 else
4242 {
4243 encChar[0]='_';
4244 encChar[1]=hex[static_cast<unsigned char>(c)>>4];
4245 encChar[2]=hex[static_cast<unsigned char>(c)&0xF];
4246 encChar[3]=0;
4247 growBuf.addStr(encChar);
4248 }
4249 first=FALSE;
4250 }
4251 growBuf.addChar(0);
4252 return growBuf.get();
4253}

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

4378{
4379 if (s.isEmpty()) return s;
4380 GrowBuf growBuf;
4381 const char *p=s.data();
4382 char c = 0;
4383 while ((c=*p++))
4384 {
4385 switch (c)
4386 {
4387 case '"': growBuf.addStr("\\\""); break;
4388 case '\\': if (*p=='u' && *(p+1)=='{') growBuf.addStr("\\");
4389 else growBuf.addStr("\\\\");
4390 break;
4391 default: growBuf.addChar(c); break;
4392 }
4393 }
4394 growBuf.addChar(0);
4395 return convertCharEntitiesToUTF8(growBuf.get());
4396}
QCString convertCharEntitiesToUTF8(const QCString &str)
Definition util.cpp:4398

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

4267{
4268 if (s.isEmpty()) return s;
4269 GrowBuf growBuf;
4270 const char *p = s.data();
4271 char c = 0;
4272 while ((c=*p++))
4273 {
4274 switch (c)
4275 {
4276 case '<': growBuf.addStr("&lt;"); break;
4277 case '>': growBuf.addStr("&gt;"); break;
4278 case '&': if (keepEntities)
4279 {
4280 const char *e=p;
4281 char ce = 0;
4282 while ((ce=*e++))
4283 {
4284 if (ce==';' || (!(isId(ce) || ce=='#'))) break;
4285 }
4286 if (ce==';') // found end of an entity
4287 {
4288 // copy entry verbatim
4289 growBuf.addChar(c);
4290 while (p<e) growBuf.addChar(*p++);
4291 }
4292 else
4293 {
4294 growBuf.addStr("&amp;");
4295 }
4296 }
4297 else
4298 {
4299 growBuf.addStr("&amp;");
4300 }
4301 break;
4302 case '\'': growBuf.addStr("&apos;"); break;
4303 case '"': growBuf.addStr("&quot;"); break;
4304 case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8:
4305 case 11: case 12: case 13: case 14: case 15: case 16: case 17: case 18:
4306 case 19: case 20: case 21: case 22: case 23: case 24: case 25: case 26:
4307 case 27: case 28: case 29: case 30: case 31:
4308 break; // skip invalid XML characters (see http://www.w3.org/TR/2000/REC-xml-20001006#NT-Char)
4309 default: growBuf.addChar(c); break;
4310 }
4311 }
4312 growBuf.addChar(0);
4313 return growBuf.get();
4314}

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(), htmlAttribsToString(), EclipseHelp::initialize(), Qhp::initialize(), XmlDocVisitor::operator()(), XmlDocVisitor::operator()(), 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 4259 of file util.cpp.

4260{
4261 if (s.isEmpty()) return s;
4262 return "a" + s;
4263}

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

6258{
6259 QCString result = url;
6260 if (!relPath.isEmpty() && !isURL(url))
6261 {
6262 result.prepend(relPath);
6263 }
6264 return result;
6265}
bool isURL(const QCString &url)
Checks whether the given url starts with a supported protocol.
Definition util.cpp:6245

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

6038{
6039 QCString url;
6040 if (!ref.isEmpty())
6041 {
6042 url = externalRef(relPath,ref,href);
6043 }
6044 if (!targetFileName.isEmpty())
6045 {
6046 QCString fn = targetFileName;
6047 if (ref.isEmpty())
6048 {
6049 if (!anchor.isEmpty() && isLocalFile)
6050 {
6051 fn=""; // omit file name for local links
6052 }
6053 else
6054 {
6055 url = relPath;
6056 }
6057 }
6058 url+=fn;
6059 }
6060 if (!anchor.isEmpty()) url+="#"+anchor;
6061 //printf("createHtmlUrl(relPath=%s,local=%d,target=%s,anchor=%s)=%s\n",qPrint(relPath),isLocalFile,qPrint(targetFileName),qPrint(anchor),qPrint(url));
6062 return url;
6063}
QCString externalRef(const QCString &relPath, const QCString &ref, bool href)
Definition util.cpp:6065

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

3995{
3996 if (Config_getBool(CREATE_SUBDIRS))
3997 {
3998 // create up to 4096 subdirectories
3999 int createSubdirsLevelPow2 = 1 << Config_getInt(CREATE_SUBDIRS_LEVEL);
4000 for (int l1=0; l1<16; l1++)
4001 {
4002 QCString subdir;
4003 subdir.sprintf("d%x",l1);
4004 if (!d.exists(subdir.str()) && !d.mkdir(subdir.str()))
4005 {
4006 term("Failed to create output directory '%s'\n",qPrint(subdir));
4007 }
4008 for (int l2=0; l2<createSubdirsLevelPow2; l2++)
4009 {
4010 QCString subsubdir;
4011 subsubdir.sprintf("d%x/d%02x",l1,l2);
4012 if (!d.exists(subsubdir.str()) && !d.mkdir(subsubdir.str()))
4013 {
4014 term("Failed to create output directory '%s'\n",qPrint(subsubdir));
4015 }
4016 }
4017 }
4018 }
4019}
bool mkdir(const std::string &path, bool acceptsAbsPath=true) const
Definition dir.cpp:295
#define term(fmt,...)
Definition message.h:94

References Config_getBool, Config_getInt, Dir::exists(), Dir::mkdir(), qPrint(), 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().

◆ detab()

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

Definition at line 7047 of file util.cpp.

7048{
7049 int tabSize = Config_getInt(TAB_SIZE);
7050 size_t size = s.length();
7051 GrowBuf out(size);
7052 const char *data = s.data();
7053 size_t i=0;
7054 int col=0;
7055 constexpr auto doxy_nbsp = "&_doxy_nbsp;"; // doxygen escape command for UTF-8 nbsp
7056 const int maxIndent=1000000; // value representing infinity
7057 int minIndent=maxIndent;
7058 bool skip = false;
7059 while (i<size)
7060 {
7061 char c = data[i++];
7062 switch(c)
7063 {
7064 case '\t': // expand tab
7065 {
7066 int stop = tabSize - (col%tabSize);
7067 //printf("expand at %d stop=%d\n",col,stop);
7068 col+=stop;
7069 while (stop--) out.addChar(' ');
7070 }
7071 break;
7072 case '\\':
7073 if (data[i] == '\\') // escaped command -> ignore
7074 {
7075 out.addChar(c);
7076 out.addChar(data[i++]);
7077 col+=2;
7078 }
7079 else if (i+5<size && qstrncmp(&data[i],"iskip",5)==0) // \iskip command
7080 {
7081 i+=5;
7082 skip = true;
7083 }
7084 else if (i+8<size && qstrncmp(&data[i],"endiskip",8)==0) // \endiskip command
7085 {
7086 i+=8;
7087 skip = false;
7088 }
7089 else // some other command
7090 {
7091 out.addChar(c);
7092 col++;
7093 }
7094 break;
7095 case '\n': // reset column counter
7096 out.addChar(c);
7097 col=0;
7098 break;
7099 case ' ': // increment column counter
7100 out.addChar(c);
7101 col++;
7102 break;
7103 default: // non-whitespace => update minIndent
7104 if (c<0 && i<size) // multibyte sequence
7105 {
7106 // special handling of the UTF-8 nbsp character 0xC2 0xA0
7107 int nb = isUTF8NonBreakableSpace(data);
7108 if (nb>0)
7109 {
7110 out.addStr(doxy_nbsp);
7111 i+=nb-1;
7112 }
7113 else
7114 {
7115 int bytes = getUTF8CharNumBytes(c);
7116 for (int j=0;j<bytes-1 && c;j++)
7117 {
7118 out.addChar(c);
7119 c = data[i++];
7120 }
7121 out.addChar(c);
7122 }
7123 }
7124 else
7125 {
7126 out.addChar(c);
7127 }
7128 if (!skip && col<minIndent) minIndent=col;
7129 col++;
7130 }
7131 }
7132 if (minIndent!=maxIndent) refIndent=minIndent; else refIndent=0;
7133 out.addChar(0);
7134 //printf("detab(\n%s\n)=[\n%s\n]\n",qPrint(s),qPrint(out.get()));
7135 return out.get();
7136}
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 3954 of file util.cpp.

3955{
3956 bool searchIncludes = Config_getBool(SEARCH_INCLUDES);
3957 QCString absIncFileName = incFileName;
3958 FileInfo fi(curFile.str());
3959 if (fi.exists())
3960 {
3961 QCString absName = QCString(fi.dirPath(TRUE))+"/"+incFileName;
3962 FileInfo fi2(absName.str());
3963 if (fi2.exists())
3964 {
3965 absIncFileName=fi2.absFilePath();
3966 }
3967 else if (searchIncludes) // search in INCLUDE_PATH as well
3968 {
3969 const StringVector &includePath = Config_getList(INCLUDE_PATH);
3970 for (const auto &incPath : includePath)
3971 {
3972 FileInfo fi3(incPath);
3973 if (fi3.exists() && fi3.isDir())
3974 {
3975 absName = QCString(fi3.absFilePath())+"/"+incFileName;
3976 //printf("trying absName=%s\n",qPrint(absName));
3977 FileInfo fi4(absName.str());
3978 if (fi4.exists())
3979 {
3980 absIncFileName=fi4.absFilePath();
3981 break;
3982 }
3983 //printf( "absIncFileName = %s\n", qPrint(absIncFileName) );
3984 }
3985 }
3986 }
3987 //printf( "absIncFileName = %s\n", qPrint(absIncFileName) );
3988 }
3989 return absIncFileName;
3990}
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 = FALSE )

Definition at line 3684 of file util.cpp.

3685{
3686 if (name.isEmpty()) return name;
3687 bool caseSenseNames = getCaseSenseNames();
3688 bool allowUnicodeNames = Config_getBool(ALLOW_UNICODE_NAMES);
3689 GrowBuf growBuf;
3690 signed char c = 0;
3691 const char *p=name.data();
3692 while ((c=*p++)!=0)
3693 {
3694 switch(c)
3695 {
3696 case '_': if (allowUnderscore) growBuf.addChar('_'); else growBuf.addStr("__"); break;
3697 case '-': growBuf.addChar('-'); break;
3698 case ':': growBuf.addStr("_1"); break;
3699 case '/': growBuf.addStr("_2"); break;
3700 case '<': growBuf.addStr("_3"); break;
3701 case '>': growBuf.addStr("_4"); break;
3702 case '*': growBuf.addStr("_5"); break;
3703 case '&': growBuf.addStr("_6"); break;
3704 case '|': growBuf.addStr("_7"); break;
3705 case '.': if (allowDots) growBuf.addChar('.'); else growBuf.addStr("_8"); break;
3706 case '!': growBuf.addStr("_9"); break;
3707 case ',': growBuf.addStr("_00"); break;
3708 case ' ': growBuf.addStr("_01"); break;
3709 case '{': growBuf.addStr("_02"); break;
3710 case '}': growBuf.addStr("_03"); break;
3711 case '?': growBuf.addStr("_04"); break;
3712 case '^': growBuf.addStr("_05"); break;
3713 case '%': growBuf.addStr("_06"); break;
3714 case '(': growBuf.addStr("_07"); break;
3715 case ')': growBuf.addStr("_08"); break;
3716 case '+': growBuf.addStr("_09"); break;
3717 case '=': growBuf.addStr("_0a"); break;
3718 case '$': growBuf.addStr("_0b"); break;
3719 case '\\': growBuf.addStr("_0c"); break;
3720 case '@': growBuf.addStr("_0d"); break;
3721 case ']': growBuf.addStr("_0e"); break;
3722 case '[': growBuf.addStr("_0f"); break;
3723 case '#': growBuf.addStr("_0g"); break;
3724 case '"': growBuf.addStr("_0h"); break;
3725 case '~': growBuf.addStr("_0i"); break;
3726 case '\'': growBuf.addStr("_0j"); break;
3727 case ';': growBuf.addStr("_0k"); break;
3728 case '`': growBuf.addStr("_0l"); break;
3729 default:
3730 if (c<0)
3731 {
3732 bool doEscape = true;
3733 if (allowUnicodeNames)
3734 {
3735 int charLen = getUTF8CharNumBytes(c);
3736 if (charLen>0)
3737 {
3738 growBuf.addStr(p-1,charLen);
3739 p+=charLen;
3740 doEscape = false;
3741 }
3742 }
3743 if (doEscape) // not a valid unicode char or escaping needed
3744 {
3745 char ids[5];
3746 unsigned char id = static_cast<unsigned char>(c);
3747 ids[0]='_';
3748 ids[1]='x';
3749 ids[2]=hex[id>>4];
3750 ids[3]=hex[id&0xF];
3751 ids[4]=0;
3752 growBuf.addStr(ids);
3753 }
3754 }
3755 else if (caseSenseNames || !isupper(c))
3756 {
3757 growBuf.addChar(c);
3758 }
3759 else
3760 {
3761 growBuf.addChar('_');
3762 growBuf.addChar(static_cast<char>(tolower(c)));
3763 }
3764 break;
3765 }
3766 }
3767 growBuf.addChar(0);
3768 return growBuf.get();
3769}
bool getCaseSenseNames()
Definition util.cpp:3674

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 = false)

Definition at line 6021 of file util.cpp.

6022{
6023 bool extLinksInWindow = Config_getBool(EXT_LINKS_IN_WINDOW);
6024 if (extLinksInWindow)
6025 return "target=\"_blank\" ";
6026 else if (parent)
6027 return "target=\"_parent\" ";
6028 else
6029 return "";
6030}
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:1310

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

6066{
6067 QCString result;
6068 if (!ref.isEmpty())
6069 {
6070 auto it = Doxygen::tagDestinationMap.find(ref.str());
6072 {
6073 result = it->second;
6074 size_t l = result.length();
6075 if (!relPath.isEmpty() && l>0 && result.at(0)=='.')
6076 { // relative path -> prepend relPath.
6077 result.prepend(relPath);
6078 l+=relPath.length();
6079 }
6080 if (l>0 && result.at(l-1)!='/') result+='/';
6081 if (!href) result.append("\" ");
6082 }
6083 }
6084 else
6085 {
6086 result = relPath;
6087 }
6088 return result;
6089}
static StringMap tagDestinationMap
Definition doxygen.h:116
char & at(size_t i)
Returns a reference to the character at index i.
Definition qcstring.h:567
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().

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

4567{
4568 static const reg::Ex re_norm(R"(\a[\w:]*)");
4569 static const reg::Ex re_fortran(R"(\a[\w:()=]*)");
4570 const reg::Ex *re = &re_norm;
4571
4572 name.clear();
4573 templSpec.clear();
4574 if (type.isEmpty()) return -1;
4575 size_t typeLen=type.length();
4576 if (typeLen>0)
4577 {
4578 if (lang == SrcLangExt::Fortran)
4579 {
4580 if (type[pos]==',') return -1;
4581 if (!type.lower().startsWith("type"))
4582 {
4583 re = &re_fortran;
4584 }
4585 }
4586 std::string s = type.str();
4587 reg::Iterator it(s,*re,static_cast<int>(pos));
4589
4590 if (it!=end)
4591 {
4592 const auto &match = *it;
4593 size_t i = match.position();
4594 size_t l = match.length();
4595 size_t ts = i+l;
4596 size_t te = ts;
4597 size_t tl = 0;
4598
4599 while (ts<typeLen && type[static_cast<uint32_t>(ts)]==' ') ts++,tl++; // skip any whitespace
4600 if (ts<typeLen && type[static_cast<uint32_t>(ts)]=='<') // assume template instance
4601 {
4602 // locate end of template
4603 te=ts+1;
4604 int brCount=1;
4605 while (te<typeLen && brCount!=0)
4606 {
4607 if (type[static_cast<uint32_t>(te)]=='<')
4608 {
4609 if (te<typeLen-1 && type[static_cast<uint32_t>(te)+1]=='<') te++; else brCount++;
4610 }
4611 if (type[static_cast<uint32_t>(te)]=='>')
4612 {
4613 if (te<typeLen-1 && type[static_cast<uint32_t>(te)+1]=='>') te++; else brCount--;
4614 }
4615 te++;
4616 }
4617 }
4618 name = match.str();
4619 if (te>ts)
4620 {
4621 templSpec = QCString(type).mid(ts,te-ts);
4622 tl+=te-ts;
4623 pos=static_cast<int>(i+l+tl);
4624 }
4625 else // no template part
4626 {
4627 pos=static_cast<int>(i+l);
4628 }
4629 //printf("extractClassNameFromType([in] type=%s,[out] pos=%d,[out] name=%s,[out] templ=%s)=TRUE i=%d\n",
4630 // qPrint(type),pos,qPrint(name),qPrint(templSpec),i);
4631 return static_cast<int>(i);
4632 }
4633 }
4634 pos = static_cast<int>(typeLen);
4635 //printf("extractClassNameFromType([in] type=%s,[out] pos=%d,[out] name=%s,[out] templ=%s)=FALSE\n",
4636 // qPrint(type),pos,qPrint(name),qPrint(templSpec));
4637 return -1;
4638}
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 6505 of file util.cpp.

6506{
6507 std::string s = docs.str();
6508 static const reg::Ex re(R"(\[([ inout,]+)\])");
6509 reg::Iterator it(s,re);
6511 if (it!=end)
6512 {
6513 const auto &match = *it;
6514 size_t p = match.position();
6515 size_t l = match.length();
6516 if (p==0 && l>2)
6517 {
6518 // make dir the part inside [...] without separators
6519 std::string dir = match[1].str();
6520 // strip , and ' ' from dir
6521 dir.erase(std::remove_if(dir.begin(),dir.end(),
6522 [](const char c) { return c==' ' || c==','; }
6523 ),dir.end());
6524 unsigned char ioMask=0;
6525 size_t inIndex = dir.find( "in");
6526 size_t outIndex = dir.find("out");
6527 if ( inIndex!=std::string::npos) dir.erase( inIndex,2),ioMask|=(1<<0);
6528 if (outIndex!=std::string::npos) dir.erase(outIndex,3),ioMask|=(1<<1);
6529 if (dir.empty() && ioMask!=0) // only in and/or out attributes found
6530 {
6531 docs = s.substr(l); // strip attributes
6532 if (ioMask==((1<<0)|(1<<1))) return "[in,out]";
6533 else if (ioMask==(1<<0)) return "[in]";
6534 else if (ioMask==(1<<1)) return "[out]";
6535 }
6536 }
6537 }
6538 return "";
6539}

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

4054{
4055 int i=0, p=0;
4056 QCString clName=scopeName;
4057 NamespaceDef *nd = nullptr;
4058 if (!clName.isEmpty() && (nd=getResolvedNamespace(clName)) && getClass(clName)==nullptr)
4059 { // the whole name is a namespace (and not a class)
4060 namespaceName=nd->name();
4061 className.clear();
4062 goto done;
4063 }
4064 p=static_cast<int>(clName.length())-2;
4065 while (p>=0 && (i=clName.findRev("::",p))!=-1)
4066 // see if the first part is a namespace (and not a class)
4067 {
4068 //printf("Trying %s\n",qPrint(clName.left(i)));
4069 if (i>0 && (nd=getResolvedNamespace(clName.left(i))) && getClass(clName.left(i))==nullptr)
4070 {
4071 //printf("found!\n");
4072 namespaceName=nd->name();
4073 className=clName.right(clName.length()-i-2);
4074 goto done;
4075 }
4076 p=i-2; // try a smaller piece of the scope
4077 }
4078 //printf("not found!\n");
4079
4080 // not found, so we just have to guess.
4081 className=scopeName;
4082 namespaceName.clear();
4083
4084done:
4085 if (className.isEmpty() && !namespaceName.isEmpty() && !allowEmptyClass)
4086 {
4087 // class and namespace with the same name, correct to return the class.
4088 className=namespaceName;
4089 namespaceName.clear();
4090 }
4091 //printf("extractNamespace '%s' => '%s|%s'\n",qPrint(scopeName),
4092 // qPrint(className),qPrint(namespaceName));
4093 if (className.endsWith("-p"))
4094 {
4095 className = className.left(className.length()-2);
4096 }
4097 return;
4098}
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 '%s' not found\n",qPrint(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 '%s' for reading\n",qPrint(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:5841

References addTerminalCharIfMissing(), err, FileInfo::exists(), QCString::isEmpty(), FileInfo::isFile(), qPrint(), readInputFile(), and QCString::str().

Referenced by createDVIFile(), extractBoundingBox(), getConvertLatexMacro(), HtmlGenerator::init(), LatexGenerator::init(), LayoutDocManager::parse(), FileDefImpl::parseSource(), parseTagFile(), DocParser::readTextFileByName(), readTextFileByName(), runPlantumlContent(), FileDefImpl::writeSourceBody(), HtmlGenerator::writeStyleInfo(), and writeXMLCodeBlock().

◆ fileVisibleInIndex()

bool fileVisibleInIndex ( const FileDef * fd,
bool & genSourceFile )

Definition at line 6416 of file util.cpp.

6417{
6418 bool allExternals = Config_getBool(ALLEXTERNALS);
6419 bool isDocFile = fd->isDocumentationFile();
6420 genSourceFile = !isDocFile && fd->generateSourceFile();
6421 return ( ((allExternals && fd->isLinkable()) ||
6423 ) &&
6424 !isDocFile
6425 );
6426}
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().

◆ filterTitle()

QCString filterTitle ( const QCString & title)

Definition at line 5920 of file util.cpp.

5921{
5922 std::string tf;
5923 std::string t = title.str();
5924 static const reg::Ex re(R"(%[a-z_A-Z]+)");
5925 reg::Iterator it(t,re);
5927 size_t p = 0;
5928 for (; it!=end ; ++it)
5929 {
5930 const auto &match = *it;
5931 size_t i = match.position();
5932 size_t l = match.length();
5933 if (i>p) tf+=t.substr(p,i-p);
5934 tf+=match.str().substr(1); // skip %
5935 p=i+l;
5936 }
5937 tf+=t.substr(p);
5938 return QCString(tf);
5939}

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

5326{
5327 static reg::Ex re(R"(\s*(<\a+>)\s*)");
5328 std::string s = sentence.str();
5329 reg::Iterator it(s,re);
5331 std::string result;
5332 bool found=false;
5333 size_t p=0;
5334 for ( ; it!=end ; ++it)
5335 {
5336 const auto match = *it;
5337 std::string part = match[1].str();
5338 if (part!=word)
5339 {
5340 size_t i = match.position();
5341 size_t l = match.length();
5342 result+=s.substr(p,i-p);
5343 result+=match.str();
5344 p=i+l;
5345 }
5346 else
5347 {
5348 found=true;
5349 size_t i = match[1].position();
5350 size_t l = match[1].length();
5351 result+=s.substr(p,i-p);
5352 p=i+l;
5353 }
5354 }
5355 result+=s.substr(p);
5356 sentence = QCString(result).simplifyWhiteSpace();
5357 return found;
5358}
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 3262 of file util.cpp.

3263{
3264 ambig=FALSE;
3265 if (n.isEmpty()) return nullptr;
3266
3267
3268 const int maxAddrSize = 20;
3269 char addr[maxAddrSize];
3270 qsnprintf(addr,maxAddrSize,"%p:",reinterpret_cast<const void*>(fnMap));
3271 QCString key = addr;
3272 key+=n;
3273
3274 std::lock_guard<std::mutex> lock(g_findFileDefMutex);
3275 FindFileCacheElem *cachedResult = g_findFileDefCache.find(key.str());
3276 //printf("key=%s cachedResult=%p\n",qPrint(key),cachedResult);
3277 if (cachedResult)
3278 {
3279 ambig = cachedResult->isAmbig;
3280 //printf("cached: fileDef=%p\n",cachedResult->fileDef);
3281 return cachedResult->fileDef;
3282 }
3283 else
3284 {
3285 cachedResult = g_findFileDefCache.insert(key.str(),FindFileCacheElem(nullptr,FALSE));
3286 }
3287
3288 QCString name=Dir::cleanDirPath(n.str());
3289 QCString path;
3290 if (name.isEmpty()) return nullptr;
3291 int slashPos=std::max(name.findRev('/'),name.findRev('\\'));
3292 if (slashPos!=-1)
3293 {
3294 path=removeLongPathMarker(name.left(slashPos+1));
3295 name=name.right(name.length()-slashPos-1);
3296 }
3297 if (name.isEmpty()) return nullptr;
3298 const FileName *fn = fnMap->find(name);
3299 if (fn)
3300 {
3301 //printf("fn->size()=%zu\n",fn->size());
3302 if (fn->size()==1)
3303 {
3304 const std::unique_ptr<FileDef> &fd = fn->front();
3305 bool isSamePath = Portable::fileSystemIsCaseSensitive() ?
3306 fd->getPath().right(path.length())==path :
3307 fd->getPath().right(path.length()).lower()==path.lower();
3308 if (path.isEmpty() || isSamePath)
3309 {
3310 cachedResult->fileDef = fd.get();
3311 return fd.get();
3312 }
3313 }
3314 else // file name alone is ambiguous
3315 {
3316 int count=0;
3317 FileDef *lastMatch=nullptr;
3318 QCString pathStripped = stripFromIncludePath(path);
3319 for (const auto &fd_p : *fn)
3320 {
3321 FileDef *fd = fd_p.get();
3322 QCString fdStripPath = stripFromIncludePath(fd->getPath());
3323 if (path.isEmpty() || fdStripPath.right(pathStripped.length())==pathStripped)
3324 {
3325 count++;
3326 lastMatch=fd;
3327 }
3328 }
3329
3330 ambig=(count>1);
3331 cachedResult->isAmbig = ambig;
3332 cachedResult->fileDef = lastMatch;
3333 return lastMatch;
3334 }
3335 }
3336 else
3337 {
3338 //printf("not found!\n");
3339 }
3340 return nullptr;
3341}
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:3252
FileDef * fileDef
Definition util.cpp:3254
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:3260
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 3345 of file util.cpp.

3346{
3347 ambig=false;
3348 QCString result;
3349 bool found=false;
3350 if (!found)
3351 {
3352 FileInfo fi(file.str());
3353 if (fi.exists())
3354 {
3355 result=fi.absFilePath();
3356 found=true;
3357 }
3358 }
3359 if (!found)
3360 {
3361 const StringVector &examplePathList = Config_getList(EXAMPLE_PATH);
3362 for (const auto &s : examplePathList)
3363 {
3364 std::string absFileName = s+(Portable::pathSeparator()+file).str();
3365 FileInfo fi(absFileName);
3366 if (fi.exists())
3367 {
3368 result=fi.absFilePath();
3369 found=true;
3370 }
3371 }
3372 }
3373
3374 if (!found)
3375 {
3376 // as a fallback we also look in the exampleNameDict
3378 if (fd && !ambig)
3379 {
3380 result=fd->absFilePath();
3381 }
3382 }
3383 return result;
3384}
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:3262

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

6990{
6992 return reg::search(s,match,re) ? static_cast<int>(match.position()) : -1;
6993}
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 6981 of file util.cpp.

6982{
6983 auto it = std::find(sv.begin(),sv.end(),s);
6984 return it!=sv.end() ? static_cast<int>(it-sv.begin()) : -1;
6985}

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

◆ fixSpaces()

QCString fixSpaces ( const QCString & s)
inline

Definition at line 464 of file util.h.

464{ return substitute(s," ","&#160;"); }
QCString substitute(const QCString &s, const QCString &src, const QCString &dst)
substitute all occurrences of src in s by dst
Definition qcstring.cpp:477

References substitute().

Referenced by renderQuickLinksAsTabs(), renderQuickLinksAsTree(), writeClassMemberIndexFiltered(), writeFileMemberIndexFiltered(), writeModuleMemberIndexFiltered(), writeNamespaceMemberIndexFiltered(), and writeUserGroupStubPage().

◆ generateAnonymousAnchor()

QCString generateAnonymousAnchor ( const QCString & fileName,
int count )

Definition at line 3912 of file util.cpp.

3913{
3914 QCString fn = stripFromPath(fileName)+":"+QCString().setNum(count);
3915 const int sig_size=16;
3916 uint8_t md5_sig[sig_size];
3917 MD5Buffer(fn.data(),static_cast<unsigned int>(fn.length()),md5_sig);
3918 char result[sig_size*3+2];
3919 char *p = result;
3920 *p++='@';
3921 for (int i=0;i<sig_size;i++)
3922 {
3923 static const char oct[]="01234567";
3924 uint8_t byte = md5_sig[i];
3925 *p++=oct[(byte>>6)&7];
3926 *p++=oct[(byte>>3)&7];
3927 *p++=oct[(byte>>0)&7];
3928 }
3929 *p='\0';
3930 return result;
3931}
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 & linkTxt = QCString() )

Definition at line 3234 of file util.cpp.

3235{
3236 //printf("generateFileRef(%s,%s)\n",name,text);
3237 QCString linkText = text.isEmpty() ? text : name;
3238 //FileInfo *fi;
3239 bool ambig = false;
3241 if (fd && fd->isLinkable())
3242 // link to documented input file
3243 ol.writeObjectLink(fd->getReference(),fd->getOutputFileBase(),QCString(),linkText);
3244 else
3245 ol.docify(linkText);
3246}
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().

◆ getCaseSenseNames()

bool getCaseSenseNames ( )

Definition at line 3674 of file util.cpp.

3675{
3676 auto caseSenseNames = Config_getEnum(CASE_SENSE_NAMES);
3677
3678 if (caseSenseNames == CASE_SENSE_NAMES_t::YES) return true;
3679 else if (caseSenseNames == CASE_SENSE_NAMES_t::NO) return false;
3681}
#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 2742 of file util.cpp.

2743{
2744 if (false) // set this to true to try the old and new routine side-by-side and compare the results
2745 {
2746 printf("@@ ------ getDefsOld start\n");
2747 GetDefResult result = getDefsOld(input);
2748 printf("@@ ------ getDefsOld end\n");
2749 printf("@@ ------ getDefsNew start\n");
2750 GetDefResult newResult = getDefsNew(input);
2751 printf("@@ ------ getDefsNew end\n");
2752 if (result.found!=newResult.found ||
2753 result.md!=newResult.md ||
2754 result.cd!=newResult.cd ||
2755 result.fd!=newResult.fd ||
2756 result.nd!=newResult.nd ||
2757 result.gd!=newResult.gd
2758 )
2759 {
2760 printf("@@ getDefsOld(scName=%s, mbName=%s, args=%s, forceEmptyScope=%d "
2761 "currentFile=%s checkCV=%d)=%d md=%s (%p) cd=%s fd=%s nd=%s gd=%s\n",
2762 qPrint(input.scopeName), qPrint(input.memberName), qPrint(input.args),
2763 input.forceEmptyScope, qPrint(input.currentFile?input.currentFile->name():QCString()),
2764 input.checkCV,
2765 result.found,
2766 qPrint(result.md ? result.md->name() : QCString()),
2767 (void*)result.md,
2768 qPrint(result.cd ? result.cd->name() : QCString()),
2769 qPrint(result.fd ? result.fd->name() : QCString()),
2770 qPrint(result.nd ? result.nd->name() : QCString()),
2771 qPrint(result.gd ? result.gd->name() : QCString())
2772 );
2773 printf("@@ ------ getDefsOld start\n");
2774 printf("@@ getDefsNew(scName=%s, mbName=%s, args=%s, forceEmptyScope=%d "
2775 "currentFile=%s checkCV=%d)=%d md=%s (%p) cd=%s fd=%s nd=%s gd=%s\n",
2776 qPrint(input.scopeName), qPrint(input.memberName), qPrint(input.args),
2777 input.forceEmptyScope, qPrint(input.currentFile?input.currentFile->name():QCString()),
2778 input.checkCV,
2779 newResult.found,
2780 qPrint(newResult.md ? newResult.md->name() : QCString()),
2781 (void*)newResult.md,
2782 qPrint(newResult.cd ? newResult.cd->name() : QCString()),
2783 qPrint(newResult.fd ? newResult.fd->name() : QCString()),
2784 qPrint(newResult.nd ? newResult.nd->name() : QCString()),
2785 qPrint(newResult.gd ? newResult.gd->name() : QCString())
2786 );
2787 }
2788 return result; // use return newResult to use the result of the new routine
2789 }
2790 else // do one of the two getDefs routines (comment out the other one)
2791 {
2792 return getDefsNew(input);
2793 }
2794}
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:2268
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().

◆ getDotImageExtension()

QCString getDotImageExtension ( )

Definition at line 6616 of file util.cpp.

6617{
6618 QCString imgExt = Config_getEnumAsString(DOT_IMAGE_FORMAT);
6619 int i= imgExt.find(':'); // strip renderer part when using e.g. 'png:cairo:gd' as format
6620 return i==-1 ? imgExt : imgExt.left(i);
6621}
#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 6007 of file util.cpp.

6008{
6009 InputFileEncoding elem;
6010 auto getter = [](const InputFileEncoding &e) { return e.pattern; };
6011 if (genericPatternMatch(fi,Doxygen::inputFileEncodingList,elem,getter)) // check for file specific encoding
6012 {
6013 return elem.encoding;
6014 }
6015 else // fall back to default encoding
6016 {
6017 return Config_getString(INPUT_ENCODING);
6018 }
6019}
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:5944

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

◆ getLanguageFromCodeLang()

SrcLangExt getLanguageFromCodeLang ( QCString & fileName)

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

Definition at line 5567 of file util.cpp.

5568{
5569 // try the extension
5570 auto lang = getLanguageFromFileName(fileName, SrcLangExt::Unknown);
5571 if (lang == SrcLangExt::Unknown)
5572 {
5573 // try the language names
5574 QCString langName = fileName.lower();
5575 if (langName.at(0)=='.') langName = langName.mid(1);
5576 auto it = std::find_if(g_lang2extMap.begin(),g_lang2extMap.end(),
5577 [&langName](const auto &info) { return info.langName==langName; });
5578 if (it != g_lang2extMap.end())
5579 {
5580 lang = it->parserId;
5581 fileName = it->defExt;
5582 }
5583 else // default to C++
5584 {
5585 return SrcLangExt::Cpp;
5586 }
5587 }
5588 return lang;
5589}
@ Unknown
Definition types.h:43
SrcLangExt getLanguageFromFileName(const QCString &fileName, SrcLangExt defLang)
Definition util.cpp:5549
static std::vector< Lang2ExtMap > g_lang2extMap
Definition util.cpp:5420

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 = SrcLangExt::Cpp )

Definition at line 5549 of file util.cpp.

5550{
5551 FileInfo fi(fileName.str());
5552 // we need only the part after the last ".", newer implementations of FileInfo have 'suffix()' for this.
5553 QCString extName = QCString(fi.extension(FALSE)).lower();
5554 if (extName.isEmpty()) extName=".no_extension";
5555 if (extName.at(0)!='.') extName.prepend(".");
5556 auto it = g_extLookup.find(extName.str());
5557 if (it!=g_extLookup.end()) // listed extension
5558 {
5559 //printf("getLanguageFromFileName(%s)=%x\n",qPrint(fi.extension()),*pVal);
5560 return it->second;
5561 }
5562 //printf("getLanguageFromFileName(%s) not found!\n",qPrint(fileName));
5563 return defLang; // not listed => assume C-ish language.
5564}
static std::unordered_map< std::string, SrcLangExt > g_extLookup
Definition util.cpp:5410

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

Referenced by MemberDefImpl::_writeMultiLineInitializer(), convertCppComments(), DocRef::DocRef(), FileDefImpl::FileDefImpl(), generateExampleDocs(), getLanguageFromCodeLang(), guessSection(), ClassDefImpl::IMPL::init(), 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()

◆ getOverloadDocs()

QCString getOverloadDocs ( )

Returns the standard string that is generated when the \overload command is used.

Definition at line 4440 of file util.cpp.

4441{
4442 return theTranslator->trOverloadText();
4443 //"This is an overloaded member function, "
4444 // "provided for convenience. It differs from the above "
4445 // "function only in what argument(s) it accepts.";
4446}
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 3590 of file util.cpp.

3591{
3592 if (name.isEmpty()) return 0;
3593 const StringVector &sl = Config_getList(IGNORE_PREFIX);
3594 for (const auto &s : sl)
3595 {
3596 const char *ps=s.c_str();
3597 const char *pd=name.data();
3598 int i=0;
3599 while (*ps!=0 && *pd!=0 && *ps==*pd) ps++,pd++,i++;
3600 if (*ps==0 && *pd!=0)
3601 {
3602 return i;
3603 }
3604 }
3605 return 0;
3606}

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

7139{
7140 QCString projectCookie = Config_getString(HTML_PROJECT_COOKIE);
7141 if (projectCookie.isEmpty()) return QCString();
7142 uint8_t md5_sig[16];
7143 char sigStr[34];
7144 MD5Buffer(projectCookie.data(),static_cast<unsigned int>(projectCookie.length()),md5_sig);
7145 MD5SigToString(md5_sig,sigStr);
7146 sigStr[32]='_'; sigStr[33]=0;
7147 return sigStr;
7148}

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

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

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

4970{
4971 int sl=static_cast<int>(s.length());
4972 int sp=p;
4973 int count=0;
4974 bool done=false;
4975 if (sp>=sl) return -1;
4976 while (sp<sl)
4977 {
4978 char c=s.at(sp);
4979 if (c==':') sp++,p++; else break;
4980 }
4981 while (sp<sl)
4982 {
4983 char c=s.at(sp);
4984 switch (c)
4985 {
4986 case ':': // found next part
4987 goto found;
4988 case '<': // skip template specifier
4989 count=1;sp++;
4990 done=false;
4991 while (sp<sl && !done)
4992 {
4993 // TODO: deal with << and >> operators!
4994 c=s.at(sp++);
4995 switch(c)
4996 {
4997 case '<': count++; break;
4998 case '>': count--; if (count==0) done=true; break;
4999 default: break;
5000 }
5001 }
5002 break;
5003 default:
5004 sp++;
5005 break;
5006 }
5007 }
5008found:
5009 *l=sp-p;
5010 //printf("getScopeFragment(%s,%d)=%s\n",qPrint(s),p,qPrint(s.mid(p,*l)));
5011 return p;
5012}

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(), computeClassRelations(), FileDefImpl::FileDefImpl(), FileDefImpl::generateSourceFile(), ClassDefImpl::IMPL::init(), parseMain(), parseMain(), Preprocessor::processFile(), setFileName(), and warnUndocumentedNamespaces().

◆ initDefaultExtensionMapping()

void initDefaultExtensionMapping ( )

Definition at line 5476 of file util.cpp.

5477{
5478 // NOTE: when adding an extension, also add the extension in config.xml
5479 // extension parser id
5480 updateLanguageMapping(".dox", "c");
5481 updateLanguageMapping(".txt", "c"); // see bug 760836
5482 updateLanguageMapping(".doc", "c");
5483 updateLanguageMapping(".c", "c");
5484 updateLanguageMapping(".C", "c");
5485 updateLanguageMapping(".cc", "c");
5486 updateLanguageMapping(".CC", "c");
5487 updateLanguageMapping(".cxx", "c");
5488 updateLanguageMapping(".cpp", "c");
5489 updateLanguageMapping(".c++", "c");
5490 updateLanguageMapping(".cxxm", "c"); // C++20 modules
5491 updateLanguageMapping(".cppm", "c"); // C++20 modules
5492 updateLanguageMapping(".ccm", "c"); // C++20 modules
5493 updateLanguageMapping(".c++m", "c"); // C++20 modules
5494 updateLanguageMapping(".ii", "c");
5495 updateLanguageMapping(".ixx", "c");
5496 updateLanguageMapping(".ipp", "c");
5497 updateLanguageMapping(".i++", "c");
5498 updateLanguageMapping(".inl", "c");
5499 updateLanguageMapping(".h", "c");
5500 updateLanguageMapping(".H", "c");
5501 updateLanguageMapping(".hh", "c");
5502 updateLanguageMapping(".HH", "c");
5503 updateLanguageMapping(".hxx", "c");
5504 updateLanguageMapping(".hpp", "c");
5505 updateLanguageMapping(".h++", "c");
5506 updateLanguageMapping(".idl", "idl");
5507 updateLanguageMapping(".ddl", "idl");
5508 updateLanguageMapping(".odl", "idl");
5509 updateLanguageMapping(".java", "java");
5510 //updateLanguageMapping(".as", "javascript"); // not officially supported
5511 //updateLanguageMapping(".js", "javascript"); // not officially supported
5512 updateLanguageMapping(".cs", "csharp");
5513 updateLanguageMapping(".d", "d");
5514 updateLanguageMapping(".php", "php");
5515 updateLanguageMapping(".php4", "php");
5516 updateLanguageMapping(".php5", "php");
5517 updateLanguageMapping(".inc", "php");
5518 updateLanguageMapping(".phtml", "php");
5519 updateLanguageMapping(".m", "objective-c");
5520 updateLanguageMapping(".M", "objective-c");
5521 updateLanguageMapping(".mm", "c"); // see bug746361
5522 updateLanguageMapping(".py", "python");
5523 updateLanguageMapping(".pyw", "python");
5524 updateLanguageMapping(".f", "fortran");
5525 updateLanguageMapping(".for", "fortran");
5526 updateLanguageMapping(".f90", "fortran");
5527 updateLanguageMapping(".f95", "fortran");
5528 updateLanguageMapping(".f03", "fortran");
5529 updateLanguageMapping(".f08", "fortran");
5530 updateLanguageMapping(".f18", "fortran");
5531 updateLanguageMapping(".vhd", "vhdl");
5532 updateLanguageMapping(".vhdl", "vhdl");
5533 updateLanguageMapping(".ucf", "vhdl");
5534 updateLanguageMapping(".qsf", "vhdl");
5535 updateLanguageMapping(".md", "md");
5536 updateLanguageMapping(".markdown", "md");
5537 updateLanguageMapping(".ice", "slice");
5538 updateLanguageMapping(".l", "lex");
5539 updateLanguageMapping(".doxygen_lex_c", "c"); // this is a placeholder so we can map initializations
5540 // in the lex scanning to cpp
5541}

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

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

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

◆ insertTemplateSpecifierInScope()

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

Definition at line 4100 of file util.cpp.

4101{
4102 QCString result=scope;
4103 if (!templ.isEmpty() && scope.find('<')==-1)
4104 {
4105 int si=0, pi=0;
4106 ClassDef *cd=nullptr;
4107 while (
4108 (si=scope.find("::",pi))!=-1 && !getClass(scope.left(si)+templ) &&
4109 ((cd=getClass(scope.left(si)))==nullptr || cd->templateArguments().empty())
4110 )
4111 {
4112 //printf("Tried '%s'\n",qPrint((scope.left(si)+templ)));
4113 pi=si+2;
4114 }
4115 if (si==-1) // not nested => append template specifier
4116 {
4117 result+=templ;
4118 }
4119 else // nested => insert template specifier before after first class name
4120 {
4121 result=scope.left(si) + templ + scope.right(scope.length()-si);
4122 }
4123 }
4124 //printf("insertTemplateSpecifierInScope('%s','%s')=%s\n",
4125 // qPrint(scope),qPrint(templ),qPrint(result));
4126 return result;
4127}
bool empty() const
Definition arguments.h:92
A abstract class representing of a compound symbol.
Definition classdef.h:104
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 = true )

Definition at line 7009 of file util.cpp.

7010{
7011 QCString result;
7012 int residual = n;
7013
7014 char modVal[2];
7015 modVal[1] = 0;
7016 while (residual > 0)
7017 {
7018 modVal[0] = (upper ? 'A': 'a') + (residual-1)%26;
7019 result = modVal + result;
7020 residual = (residual-1) / 26;
7021 }
7022 return result;
7023}

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

◆ integerToRoman()

QCString integerToRoman ( int n,
bool upper = true )

Definition at line 7025 of file util.cpp.

7026{
7027 static const char *str_romans_upper[] = { "M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I" };
7028 static const char *str_romans_lower[] = { "m", "cm", "d", "cd", "c", "xc", "l", "xl", "x", "ix", "v", "iv", "i" };
7029 static const int values[] = { 1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1 };
7030 static const char **str_romans = upper ? str_romans_upper : str_romans_lower;
7031
7032 QCString result;
7033 int residual = n;
7034
7035 for (int i = 0; i < 13; ++i)
7036 {
7037 while (residual - values[i] >= 0)
7038 {
7039 result += str_romans[i];
7040 residual -= values[i];
7041 }
7042 }
7043
7044 return result;
7045}

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

◆ isId()

◆ isIdJS()

bool isIdJS ( int c)
inline

Definition at line 206 of file util.h.

207{
208 return c>=128 || c<0 || isalnum(c);
209}

Referenced by SearchTerm::termEncoded().

◆ isURL()

bool isURL ( const QCString & url)

Checks whether the given url starts with a supported protocol.

Definition at line 6245 of file util.cpp.

6246{
6247 static const std::unordered_set<std::string> schemes = {
6248 "http", "https", "ftp", "ftps", "sftp", "file", "news", "irc", "ircs"
6249 };
6250 QCString loc_url = url.stripWhiteSpace();
6251 int colonPos = loc_url.find(':');
6252 return colonPos!=-1 && schemes.find(loc_url.left(colonPos).str())!=schemes.end();
6253}

References QCString::find(), QCString::left(), QCString::str(), and QCString::stripWhiteSpace().

Referenced by correctURL(), Markdown::Private::processLink(), and renderQuickLinksAsJs().

◆ join()

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

create a string where the string in the vector are joined by the given delimiter

Definition at line 6996 of file util.cpp.

6997{
6998 std::string result;
6999 bool first=true;
7000 for (const auto &s : sv)
7001 {
7002 if (!first) result+=delimiter;
7003 first=false;
7004 result+=s;
7005 }
7006 return result;
7007}

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

◆ langToString()

QCString langToString ( SrcLangExt lang)

Returns a string representation of lang.

Definition at line 6203 of file util.cpp.

6204{
6205 switch(lang)
6206 {
6207 case SrcLangExt::Unknown: return "Unknown";
6208 case SrcLangExt::IDL: return "IDL";
6209 case SrcLangExt::Java: return "Java";
6210 case SrcLangExt::CSharp: return "C#";
6211 case SrcLangExt::D: return "D";
6212 case SrcLangExt::PHP: return "PHP";
6213 case SrcLangExt::ObjC: return "Objective-C";
6214 case SrcLangExt::Cpp: return "C++";
6215 case SrcLangExt::JS: return "JavaScript";
6216 case SrcLangExt::Python: return "Python";
6217 case SrcLangExt::Fortran: return "Fortran";
6218 case SrcLangExt::VHDL: return "VHDL";
6219 case SrcLangExt::XML: return "XML";
6220 case SrcLangExt::SQL: return "SQL";
6221 case SrcLangExt::Markdown: return "Markdown";
6222 case SrcLangExt::Slice: return "Slice";
6223 case SrcLangExt::Lex: return "Lex";
6224 }
6225 return "Unknown";
6226}
@ 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(), 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 6182 of file util.cpp.

6183{
6184 int result = 1;
6185
6186 // find the character positions of the first marker
6187 int m1 = text.find(marker);
6188 if (m1==-1) return result;
6189
6190 // find start line positions for the markers
6191 bool found=false;
6192 int p=0, i=0;
6193 while (!found && (i=text.find('\n',p))!=-1)
6194 {
6195 found = (p<=m1 && m1<i); // found the line with the start marker
6196 p=i+1;
6197 result++;
6198 }
6199 return result;
6200}

References QCString::find(), and found.

Referenced by readIncludeFile().

◆ linkifyText()

void linkifyText ( const TextGeneratorIntf & ol,
const Definition * scope,
const FileDef * fileScope,
const Definition * self,
const QCString & text,
bool autoBreak = FALSE,
bool external = TRUE,
bool keepSpaces = FALSE,
int indentLevel = 0 )

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
skipIndex
Definition util.cpp:1095

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

3101{
3102 //bool optimizeOutputJava = Config_getBool(OPTIMIZE_OUTPUT_JAVA);
3103 QCString result=link;
3104 if (!result.isEmpty())
3105 {
3106 // replace # by ::
3107 result=substitute(result,"#","::");
3108 // replace . by ::
3109 if (!isFileName && result.find('<')==-1) result=substitute(result,".","::",3);
3110 // strip leading :: prefix if present
3111 if (result.at(0)==':' && result.at(1)==':')
3112 {
3113 result=result.right(result.length()-2);
3114 }
3116 if (sep!="::")
3117 {
3118 result=substitute(result,"::",sep);
3119 }
3120 }
3121 //printf("linkToText(%s,lang=%d)=%s\n",qPrint(link),lang,qPrint(result));
3122 return result;
3123}
QCString getLanguageSpecificSeparator(SrcLangExt lang, bool classScope)
Returns the scope separator to use given the programming language lang.
Definition util.cpp:6229

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

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

References Doxygen::mainPage.

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

◆ 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}
This class represents an function or template argument list.
Definition arguments.h:60
Argument & front()
Definition arguments.h:98
size_t size() const
Definition arguments.h:93
#define AUTO_TRACE(...)
Definition docnode.cpp:46
#define MATCH
Definition util.cpp:1826
QCString argListToString(const ArgumentList &al, bool useCanonicalType, bool showDefVals)
Definition util.cpp:1174
#define NOMATCH
Definition util.cpp:1827
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(), combineDeclarationAndDefinition(), computeMemberRelationsForBaseClass(), ClassDefImpl::containsOverload(), findGlobalMember(), findMember(), findMembersWithSpecificName(), getDefsOld(), SymbolResolver::Private::getResolvedSymbol(), GroupDefImpl::insertMember(), matchCanonicalTypes(), ClassDefImpl::mergeMembersFromBaseClasses(), transferFunctionReferences(), and transferRelatedFunctionDocumentation().

◆ mergeArguments()

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

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}
#define AUTO_TRACE_ADD(...)
Definition docnode.cpp:47
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().

◆ mergeMemberOverrideOptions()

void mergeMemberOverrideOptions ( MemberDefMutable * md1,
MemberDefMutable * md2 )

Definition at line 7188 of file util.cpp.

7189{
7190 if (Config_getBool(CALL_GRAPH) !=md1->hasCallGraph()) md2->overrideCallGraph(md1->hasCallGraph());
7191 if (Config_getBool(CALLER_GRAPH)!=md1->hasCallerGraph()) md2->overrideCallerGraph(md1->hasCallerGraph());
7192 if (Config_getBool(CALL_GRAPH) !=md2->hasCallGraph()) md1->overrideCallGraph( md2->hasCallGraph());
7193 if (Config_getBool(CALLER_GRAPH)!=md2->hasCallerGraph()) md1->overrideCallerGraph(md2->hasCallerGraph());
7194
7195 if (Config_getBool(SHOW_ENUM_VALUES) !=md1->hasEnumValues()) md2->overrideEnumValues(md1->hasEnumValues());
7196 if (Config_getBool(SHOW_ENUM_VALUES) !=md2->hasEnumValues()) md1->overrideEnumValues( md2->hasEnumValues());
7197
7198 if (Config_getBool(REFERENCED_BY_RELATION)!=md1->hasReferencedByRelation()) md2->overrideReferencedByRelation(md1->hasReferencedByRelation());
7199 if (Config_getBool(REFERENCES_RELATION) !=md1->hasReferencesRelation()) md2->overrideReferencesRelation(md1->hasReferencesRelation());
7200 if (Config_getBool(REFERENCED_BY_RELATION)!=md2->hasReferencedByRelation()) md1->overrideReferencedByRelation(md2->hasReferencedByRelation());
7201 if (Config_getBool(REFERENCES_RELATION) !=md2->hasReferencesRelation()) md1->overrideReferencesRelation(md2->hasReferencesRelation());
7202
7203 if (Config_getBool(INLINE_SOURCES)!=md1->hasInlineSource()) md2->overrideInlineSource(md1->hasInlineSource());
7204 if (Config_getBool(INLINE_SOURCES)!=md2->hasInlineSource()) md1->overrideInlineSource(md2->hasInlineSource());
7205}
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().

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

4935{
4936 // case leftScope=="A" rightScope=="A::B" => result = "A::B"
4937 if (leftScopeMatch(rightScope,leftScope)) return rightScope;
4938 QCString result;
4939 int i=0,p=static_cast<int>(leftScope.length());
4940
4941 // case leftScope=="A::B" rightScope=="B::C" => result = "A::B::C"
4942 // case leftScope=="A::B" rightScope=="B" => result = "A::B"
4943 bool found=FALSE;
4944 while ((i=leftScope.findRev("::",p))>0)
4945 {
4946 if (leftScopeMatch(rightScope,leftScope.right(leftScope.length()-i-2)))
4947 {
4948 result = leftScope.left(i+2)+rightScope;
4949 found=TRUE;
4950 }
4951 p=i-1;
4952 }
4953 if (found) return result;
4954
4955 // case leftScope=="A" rightScope=="B" => result = "A::B"
4956 result=leftScope;
4957 if (!result.isEmpty() && !rightScope.isEmpty()) result+="::";
4958 result+=rightScope;
4959 return result;
4960}
bool leftScopeMatch(const QCString &scope, const QCString &name)
Definition util.cpp:892

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

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

◆ nextUtf8CharPosition()

int nextUtf8CharPosition ( const QCString & utf8Str,
uint32_t len,
uint32_t startPos )

◆ normalizeNonTemplateArgumentsInString()

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

Definition at line 4640 of file util.cpp.

4644{
4645 // skip until <
4646 int p=name.find('<');
4647 if (p==-1) return name;
4648 p++;
4649 QCString result = name.left(p);
4650
4651 std::string s = name.mid(p).str();
4652 static const reg::Ex re(R"([\a:][\w:]*)");
4653 reg::Iterator it(s,re);
4655 size_t pi=0;
4656 // for each identifier in the template part (e.g. B<T> -> T)
4657 for (; it!=end ; ++it)
4658 {
4659 const auto &match = *it;
4660 size_t i = match.position();
4661 size_t l = match.length();
4662 result += s.substr(pi,i-pi);
4663 QCString n(match.str());
4664 bool found=FALSE;
4665 for (const Argument &formArg : formalArgs)
4666 {
4667 if (formArg.name == n)
4668 {
4669 found=TRUE;
4670 break;
4671 }
4672 }
4673 if (!found)
4674 {
4675 // try to resolve the type
4676 SymbolResolver resolver;
4677 const ClassDef *cd = resolver.resolveClass(context,n);
4678 if (cd)
4679 {
4680 result+=cd->name();
4681 }
4682 else
4683 {
4684 result+=n;
4685 }
4686 }
4687 else
4688 {
4689 result+=n;
4690 }
4691 pi=i+l;
4692 }
4693 result+=s.substr(pi);
4694 //printf("normalizeNonTemplateArgumentInString(%s)=%s\n",qPrint(name),qPrint(result));
4695 return removeRedundantWhiteSpace(result);
4696}
Helper class to find a class definition or check if A symbol is accessible in a given scope.
const ClassDef * resolveClass(const Definition *scope, const QCString &name, bool maybeUnlinkable=false, bool mayBeHidden=false)
Find the class definition matching name within the scope set.

References end(), FALSE, QCString::find(), 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 6623 of file util.cpp.

6624{
6625 assert(!f.is_open());
6626 bool fileOpened=FALSE;
6627 bool writeToStdout=outFile=="-";
6628 if (writeToStdout) // write to stdout
6629 {
6630 f.basic_ios<char>::rdbuf(std::cout.rdbuf());
6631 fileOpened = true;
6632 }
6633 else // write to file
6634 {
6635 FileInfo fi(outFile.str());
6636 if (fi.exists()) // create a backup
6637 {
6638 Dir dir;
6639 FileInfo backup(fi.filePath()+".bak");
6640 if (backup.exists()) // remove existing backup
6641 dir.remove(backup.filePath());
6642 dir.rename(fi.filePath(),fi.filePath()+".bak");
6643 }
6644 f = Portable::openOutputStream(outFile);
6645 fileOpened = f.is_open();
6646 }
6647 return fileOpened;
6648}
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 * member,
const QCString & doc,
const QCString & fileName,
int lineNr )

Definition at line 5707 of file util.cpp.

5709{
5710 if (doc.isEmpty()) return "";
5711 //printf("parseCommentAsText(%s)\n",qPrint(doc));
5712 TextStream t;
5713 auto parser { createDocParser() };
5714 auto ast { validatingParseDoc(*parser.get(),
5715 fileName,lineNr,
5716 scope,md,doc,FALSE,FALSE,
5717 QCString(),FALSE,FALSE,Config_getBool(MARKDOWN_SUPPORT)) };
5718 auto astImpl = dynamic_cast<const DocNodeAST*>(ast.get());
5719 if (astImpl)
5720 {
5721 TextDocVisitor visitor(t);
5722 std::visit(visitor,astImpl->root);
5723 }
5724 QCString result = convertCharEntitiesToUTF8(t.str().c_str()).stripWhiteSpace();
5725 int i=0;
5726 int charCnt=0;
5727 int l=static_cast<int>(result.length());
5728 while ((i=nextUTF8CharPosition(result,l,i))<l)
5729 {
5730 charCnt++;
5731 if (charCnt>=80) break;
5732 }
5733 if (charCnt>=80) // try to truncate the string
5734 {
5735 while ((i=nextUTF8CharPosition(result,l,i))<l && charCnt<100)
5736 {
5737 charCnt++;
5738 if (result.at(i)==',' ||
5739 result.at(i)=='.' ||
5740 result.at(i)=='!' ||
5741 result.at(i)=='?' ||
5742 result.at(i)=='}') // good for UTF-16 characters and } otherwise also a good point to stop the string
5743 {
5744 i++; // we want to be "behind" last inspected character
5745 break;
5746 }
5747 }
5748 }
5749 if ( i < l) result=result.left(i)+"...";
5750 return result.data();
5751}
Class representing the abstract syntax tree of a documentation block.
Definition docnode.h:1446
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:5663

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

6001{
6002 std::string elem;
6003 auto getter = [](std::string s) { return QCString(s); };
6004 return genericPatternMatch(fi,patList,elem,getter);
6005}

References genericPatternMatch().

Referenced by checkAndOpenFile(), and readDir().

◆ processMarkup()

QCString processMarkup ( const QCString & s)

◆ projectLogoFile()

QCString projectLogoFile ( )

Definition at line 3495 of file util.cpp.

3496{
3497 QCString projectLogo = Config_getString(PROJECT_LOGO);
3498 if (!projectLogo.isEmpty())
3499 {
3500 // check for optional width= and height= specifier
3501 int wi = projectLogo.find(" width=");
3502 if (wi!=-1) // and strip them
3503 {
3504 projectLogo = projectLogo.left(wi);
3505 }
3506 int hi = projectLogo.find(" height=");
3507 if (hi!=-1)
3508 {
3509 projectLogo = projectLogo.left(hi);
3510 }
3511 }
3512 //printf("projectlogo='%s'\n",qPrint(projectLogo));
3513 return projectLogo;
3514}

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

Referenced by copyLogo(), and substituteKeywords().

◆ protectionLevelVisible()

◆ readInputFile()

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

read a file name fileName and optionally filter and transcode it

Definition at line 5841 of file util.cpp.

5842{
5843 // try to open file
5844 FileInfo fi(fileName.str());
5845 if (!fi.exists()) return FALSE;
5846 QCString filterName = getFileFilter(fileName,isSourceCode);
5847 if (filterName.isEmpty() || !filter)
5848 {
5849 std::ifstream f = Portable::openInputStream(fileName,true);
5850 if (!f.is_open())
5851 {
5852 err("could not open file %s\n",qPrint(fileName));
5853 return FALSE;
5854 }
5855 // read the file
5856 contents.resize(fi.size());
5857 f.read(contents.data(),fi.size());
5858 if (f.fail())
5859 {
5860 err("problems while reading file %s\n",qPrint(fileName));
5861 return FALSE;
5862 }
5863 }
5864 else
5865 {
5866 QCString cmd=filterName+" \""+fileName+"\"";
5867 Debug::print(Debug::ExtCmd,0,"Executing popen(`%s`)\n",qPrint(cmd));
5868 FILE *f=Portable::popen(cmd,"r");
5869 if (!f)
5870 {
5871 err("could not execute filter %s\n",qPrint(filterName));
5872 return FALSE;
5873 }
5874 const int bufSize=4096;
5875 char buf[bufSize];
5876 int numRead = 0;
5877 while ((numRead=static_cast<int>(fread(buf,1,bufSize,f)))>0)
5878 {
5879 //printf(">>>>>>>>Reading %d bytes\n",numRead);
5880 contents.append(buf,numRead);
5881 }
5883 Debug::print(Debug::FilterOutput, 0, "Filter output\n");
5884 Debug::print(Debug::FilterOutput,0,"-------------\n%s\n-------------\n",qPrint(contents));
5885 }
5886
5887 if (contents.size()>=2 &&
5888 static_cast<uint8_t>(contents[0])==0xFF &&
5889 static_cast<uint8_t>(contents[1])==0xFE // Little endian BOM
5890 ) // UCS-2LE encoded file
5891 {
5892 transcodeCharacterBuffer(fileName,contents,"UCS-2LE","UTF-8");
5893 }
5894 else if (contents.size()>=2 &&
5895 static_cast<uint8_t>(contents[0])==0xFE &&
5896 static_cast<uint8_t>(contents[1])==0xFF // big endian BOM
5897 ) // UCS-2BE encoded file
5898 {
5899 transcodeCharacterBuffer(fileName,contents,"UCS-2BE","UTF-8");
5900 }
5901 else if (contents.size()>=3 &&
5902 static_cast<uint8_t>(contents[0])==0xEF &&
5903 static_cast<uint8_t>(contents[1])==0xBB &&
5904 static_cast<uint8_t>(contents[2])==0xBF
5905 ) // UTF-8 encoded file
5906 {
5907 contents.erase(0,3); // remove UTF-8 BOM: no translation needed
5908 }
5909 else // transcode according to the INPUT_ENCODING setting
5910 {
5911 // do character transcoding if needed.
5912 transcodeCharacterBuffer(fileName,contents,getEncoding(fi),"UTF-8");
5913 }
5914
5915 filterCRLF(contents);
5916 return true;
5917}
@ FilterOutput
Definition debug.h:37
@ ExtCmd
Definition debug.h:35
static void print(DebugMask mask, int prio, const char *fmt,...)
Definition debug.cpp:81
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:5805
QCString getEncoding(const FileInfo &fi)
Definition util.cpp:6007
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(), qPrint(), FileInfo::size(), QCString::str(), and transcodeCharacterBuffer().

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

◆ recodeString()

QCString recodeString ( const QCString & str,
const char * fromEncoding,
const char * toEncoding )

◆ recognizeFixedForm()

bool recognizeFixedForm ( const QCString & contents,
FortranFormat format )

Definition at line 6670 of file util.cpp.

6671{
6672 int column=0;
6673 bool skipLine=FALSE;
6674
6675 if (format == FortranFormat::Fixed) return TRUE;
6676 if (format == FortranFormat::Free) return FALSE;
6677
6678 int tabSize=Config_getInt(TAB_SIZE);
6679 size_t sizCont = contents.length();
6680 for (size_t i=0;i<sizCont;i++)
6681 {
6682 column++;
6683
6684 switch(contents.at(i))
6685 {
6686 case '\n':
6687 column=0;
6688 skipLine=FALSE;
6689 break;
6690 case '\t':
6691 column += tabSize-1;
6692 break;
6693 case ' ':
6694 break;
6695 case '\000':
6696 return FALSE;
6697 case '#':
6698 skipLine=TRUE;
6699 break;
6700 case 'C':
6701 case 'c':
6702 if (column==1)
6703 {
6704 return !keyWordsFortranC(contents.data()+i);
6705 }
6706 // fallthrough
6707 case '*':
6708 if (column==1) return TRUE;
6709 if (skipLine) break;
6710 return FALSE;
6711 case '!':
6712 if (column!=6) skipLine=TRUE;
6713 break;
6714 default:
6715 if (skipLine) break;
6716 if (column>=7) return TRUE;
6717 return FALSE;
6718 }
6719 }
6720 return FALSE;
6721}
static bool keyWordsFortranC(const char *contents)
Definition util.cpp:6650

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

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

◆ relativePathToRoot()

QCString relativePathToRoot ( const QCString & name)

Definition at line 3933 of file util.cpp.

3934{
3935 QCString result;
3936 if (Config_getBool(CREATE_SUBDIRS))
3937 {
3938 if (name.isEmpty())
3939 {
3940 return REL_PATH_TO_ROOT;
3941 }
3942 else
3943 {
3944 int i = name.findRev('/');
3945 if (i!=-1)
3946 {
3947 result=REL_PATH_TO_ROOT;
3948 }
3949 }
3950 }
3951 return result;
3952}
#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 6913 of file util.cpp.

6914{
6915 std::string out;
6916 out.reserve(s.length());
6917 const char *p=s.data();
6918 if (p)
6919 {
6920 char c = 0;
6921 while ((c=*p++))
6922 {
6923 if (c=='\n')
6924 {
6925 const char *e = p;
6926 while (*e==' ' || *e=='\t') e++;
6927 if (*e=='\n')
6928 {
6929 p=e;
6930 }
6931 else out+=c;
6932 }
6933 else
6934 {
6935 out+=c;
6936 }
6937 }
6938 }
6939 //printf("removeEmptyLines(%s)=%s\n",qPrint(s),qPrint(out));
6940 return out;
6941}

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(), addVariableToClass(), argListToString(), 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 = QCString() )

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

6119{
6120 if (str.isEmpty()) return QCString();
6121 std::string result;
6122 std::string s=str.str();
6123 static const reg::Ex re(R"(##[0-9A-Fa-f][0-9A-Fa-f])");
6124 reg::Iterator it(s,re);
6126 int hue = Config_getInt(HTML_COLORSTYLE_HUE);
6127 int sat = Config_getInt(HTML_COLORSTYLE_SAT);
6128 int gamma = Config_getInt(HTML_COLORSTYLE_GAMMA);
6129 size_t sl=s.length();
6130 size_t p=0;
6131 for (; it!=end ; ++it)
6132 {
6133 const auto &match = *it;
6134 size_t i = match.position();
6135 size_t l = match.length();
6136 if (i>p) result+=s.substr(p,i-p);
6137 std::string lumStr = match.str().substr(2);
6138#define HEXTONUM(x) (((x)>='0' && (x)<='9') ? ((x)-'0') : \
6139 ((x)>='a' && (x)<='f') ? ((x)-'a'+10) : \
6140 ((x)>='A' && (x)<='F') ? ((x)-'A'+10) : 0)
6141
6142 double r = 0,g = 0,b = 0;
6143 int level = HEXTONUM(lumStr[0])*16+HEXTONUM(lumStr[1]);
6144 ColoredImage::hsl2rgb(hue/360.0,sat/255.0,
6145 pow(level/255.0,gamma/100.0),&r,&g,&b);
6146 int red = static_cast<int>(r*255.0);
6147 int green = static_cast<int>(g*255.0);
6148 int blue = static_cast<int>(b*255.0);
6149 char colStr[8];
6150 colStr[0]='#';
6151 colStr[1]=hex[red>>4];
6152 colStr[2]=hex[red&0xf];
6153 colStr[3]=hex[green>>4];
6154 colStr[4]=hex[green&0xf];
6155 colStr[5]=hex[blue>>4];
6156 colStr[6]=hex[blue&0xf];
6157 colStr[7]=0;
6158 //printf("replacing %s->%s (level=%d)\n",qPrint(lumStr),colStr,level);
6159 result+=colStr;
6160 p=i+l;
6161 }
6162 if (p<sl) result+=s.substr(p);
6163 return QCString(result);
6164}
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,
const QCString & prefix = QCString() )

Definition at line 3126 of file util.cpp.

3133{
3134 *resContext=nullptr;
3135
3136 QCString linkRef=lr;
3137 QCString linkRefWithoutTemplates = stripTemplateSpecifiersFromScope(linkRef,FALSE);
3138 //printf("ResolveLink linkRef=%s\n",qPrint(lr));
3139 const FileDef *fd = nullptr;
3140 const GroupDef *gd = nullptr;
3141 const PageDef *pd = nullptr;
3142 const ClassDef *cd = nullptr;
3143 const DirDef *dir = nullptr;
3144 const ConceptDef *cnd = nullptr;
3145 const NamespaceDef *nd = nullptr;
3146 const SectionInfo *si = nullptr;
3147 bool ambig = false;
3148 if (linkRef.isEmpty()) // no reference name!
3149 {
3150 return FALSE;
3151 }
3152 else if ((pd=Doxygen::pageLinkedMap->find(linkRef))) // link to a page
3153 {
3154 gd = pd->getGroupDef();
3155 if (gd)
3156 {
3157 if (!pd->name().isEmpty()) si=SectionManager::instance().find(pd->name());
3158 *resContext=gd;
3159 if (si) resAnchor = si->label();
3160 }
3161 else
3162 {
3163 *resContext=pd;
3164 }
3165 return TRUE;
3166 }
3167 else if ((si=SectionManager::instance().find(prefix+linkRef)))
3168 {
3169 *resContext=si->definition();
3170 resAnchor = si->label();
3171 return TRUE;
3172 }
3173 else if ((pd=Doxygen::exampleLinkedMap->find(linkRef))) // link to an example
3174 {
3175 *resContext=pd;
3176 return TRUE;
3177 }
3178 else if ((gd=Doxygen::groupLinkedMap->find(linkRef))) // link to a group
3179 {
3180 *resContext=gd;
3181 return TRUE;
3182 }
3183 else if ((fd=findFileDef(Doxygen::inputNameLinkedMap,linkRef,ambig)) // file link
3184 && fd->isLinkable())
3185 {
3186 *resContext=fd;
3187 return TRUE;
3188 }
3189 else if ((cd=getClass(linkRef))) // class link
3190 {
3191 *resContext=cd;
3192 resAnchor=cd->anchor();
3193 return TRUE;
3194 }
3195 else if ((cd=getClass(linkRefWithoutTemplates))) // C#/Java generic class link
3196 {
3197 *resContext=cd;
3198 resAnchor=cd->anchor();
3199 return TRUE;
3200 }
3201 else if ((cd=getClass(linkRef+"-p"))) // Obj-C protocol link
3202 {
3203 *resContext=cd;
3204 resAnchor=cd->anchor();
3205 return TRUE;
3206 }
3207 else if ((cnd=getConcept(linkRef))) // C++20 concept definition
3208 {
3209 *resContext=cnd;
3210 resAnchor=cnd->anchor();
3211 return TRUE;
3212 }
3213 else if ((nd=Doxygen::namespaceLinkedMap->find(linkRef)))
3214 {
3215 *resContext=nd;
3216 return TRUE;
3217 }
3218 else if ((dir=Doxygen::dirLinkedMap->find(FileInfo(linkRef.str()).absFilePath()+"/"))
3219 && dir->isLinkable()) // TODO: make this location independent like filedefs
3220 {
3221 *resContext=dir;
3222 return TRUE;
3223 }
3224 else // probably a member reference
3225 {
3226 const MemberDef *md = nullptr;
3227 bool res = resolveRef(scName,lr,TRUE,resContext,&md);
3228 if (md) resAnchor=md->anchor();
3229 return res;
3230 }
3231}
virtual QCString anchor() const =0
A model of a directory symbol.
Definition dirdef.h:110
static NamespaceLinkedMap * namespaceLinkedMap
Definition doxygen.h:115
static PageLinkedMap * exampleLinkedMap
Definition doxygen.h:99
static DirLinkedMap * dirLinkedMap
Definition doxygen.h:129
static GroupLinkedMap * groupLinkedMap
Definition doxygen.h:114
std::string absFilePath() const
Definition fileinfo.cpp:101
A model of a group of symbols.
Definition groupdef.h:52
virtual const GroupDef * getGroupDef() const =0
QCString label() const
Definition section.h:68
Definition * definition() const
Definition section.h:76
ConceptDef * getConcept(const QCString &n)
bool resolveRef(const QCString &scName, const QCString &name, bool inSeeBlock, const Definition **resContext, const MemberDef **resMember, bool lookForSpecialization, const FileDef *currentFile, bool checkScope)
Definition util.cpp:2877
QCString stripTemplateSpecifiersFromScope(const QCString &fullName, bool parentOnly, QCString *pLastScopeStripped, QCString scopeName, bool allowArtificial)
Definition util.cpp:4867

References FileInfo::absFilePath(), Definition::anchor(), SectionInfo::definition(), Doxygen::dirLinkedMap, Doxygen::exampleLinkedMap, FALSE, LinkedMap< T, Hash, KeyEqual, Map >::find(), findFileDef(), getClass(), getConcept(), PageDef::getGroupDef(), Doxygen::groupLinkedMap, Doxygen::inputNameLinkedMap, SectionManager::instance(), QCString::isEmpty(), Definition::isLinkable(), SectionInfo::label(), 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,
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 2877 of file util.cpp.

2886{
2887 AUTO_TRACE("scope={} name={} inSeeBlock={}",scName,name,inSeeBlock);
2888 //printf("resolveRef(scope=%s,name=%s,inSeeBlock=%d)\n",qPrint(scName),qPrint(name),inSeeBlock);
2889 QCString tsName = name;
2890 //bool memberScopeFirst = tsName.find('#')!=-1;
2891 QCString fullName = substitute(tsName,"#","::");
2892 if (fullName.find("anonymous_namespace{")==-1)
2893 {
2894 fullName = removeRedundantWhiteSpace(substitute(fullName,".","::",3));
2895 }
2896 else
2897 {
2898 fullName = removeRedundantWhiteSpace(fullName);
2899 }
2900
2901 int bracePos=findParameterList(fullName);
2902 int endNamePos=bracePos!=-1 ? bracePos : static_cast<int>(fullName.length());
2903 int scopePos=fullName.findRev("::",endNamePos);
2904 bool explicitScope = fullName.startsWith("::") && // ::scope or #scope
2905 (scopePos>2 || // ::N::A
2906 tsName.startsWith("::") || // ::foo in local scope
2907 scName==nullptr // #foo in global scope
2908 );
2909 bool allowTypeOnly=false;
2910
2911 // default result values
2912 *resContext=nullptr;
2913 *resMember=nullptr;
2914
2915 if (bracePos==-1) // simple name
2916 {
2917 // the following if() was commented out for releases in the range
2918 // 1.5.2 to 1.6.1, but has been restored as a result of bug report 594787.
2919 if (!inSeeBlock && scopePos==-1 && isLowerCase(tsName))
2920 { // link to lower case only name => do not try to autolink
2921 AUTO_TRACE_ADD("false");
2922 return FALSE;
2923 }
2924
2925 ClassDef *cd=nullptr;
2926 NamespaceDef *nd=nullptr;
2927 ConceptDef *cnd=nullptr;
2928
2929 //printf("scName=%s fullName=%s\n",qPrint(scName),qPrint(fullName));
2930
2931 // check if this is a class or namespace reference
2932 if (scName!=fullName && getScopeDefs(scName,fullName,cd,cnd,nd))
2933 {
2934 //printf("found scopeDef\n");
2935 if (cd) // scope matches that of a class
2936 {
2937 *resContext = cd;
2938 }
2939 else if (cnd)
2940 {
2941 *resContext = cnd;
2942 }
2943 else // scope matches that of a namespace
2944 {
2945 ASSERT(nd!=nullptr);
2946 *resContext = nd;
2947 }
2948 AUTO_TRACE_ADD("true");
2949 return TRUE;
2950 }
2951 else if (scName==fullName || (!inSeeBlock && scopePos==-1))
2952 // nothing to link => output plain text
2953 {
2954 //printf("found scName=%s fullName=%s scName==fullName=%d "
2955 // "inSeeBlock=%d scopePos=%d!\n",
2956 // qPrint(scName),qPrint(fullName),scName==fullName,inSeeBlock,scopePos);
2957
2958 // at this point we have a bare word that is not a class or namespace
2959 // we should also allow typedefs or enums to be linked, but not for instance member
2960 // functions, otherwise 'Foo' would always link to the 'Foo()' constructor instead of the
2961 // 'Foo' class. So we use this flag as a filter.
2962 allowTypeOnly=true;
2963 }
2964
2965 // continue search...
2966 }
2967
2968 // extract userscope+name
2969 QCString nameStr=fullName.left(endNamePos);
2970 if (explicitScope) nameStr=nameStr.mid(2);
2971
2972
2973 // extract arguments
2974 QCString argsStr;
2975 if (bracePos!=-1) argsStr=fullName.right(fullName.length()-bracePos);
2976
2977 // strip template specifier
2978 // TODO: match against the correct partial template instantiation
2979 int templPos=nameStr.find('<');
2980 bool tryUnspecializedVersion = FALSE;
2981 if (templPos!=-1 && nameStr.find("operator")==-1)
2982 {
2983 int endTemplPos=nameStr.findRev('>');
2984 if (endTemplPos!=-1)
2985 {
2986 if (!lookForSpecialization)
2987 {
2988 nameStr=nameStr.left(templPos)+nameStr.right(nameStr.length()-endTemplPos-1);
2989 }
2990 else
2991 {
2992 tryUnspecializedVersion = TRUE;
2993 }
2994 }
2995 }
2996
2997 QCString scopeStr=scName;
2998 if (nameStr.length()>scopeStr.length() && leftScopeMatch(scopeStr,nameStr))
2999 {
3000 nameStr=nameStr.mid(scopeStr.length()+2);
3001 }
3002
3003 const GroupDef *gd = nullptr;
3004 const ConceptDef *cnd = nullptr;
3005
3006 // check if nameStr is a member or global.
3007 //printf("getDefs(scope=%s,name=%s,args=%s checkScope=%d)\n",
3008 // qPrint(scopeStr), qPrint(nameStr), qPrint(argsStr),checkScope);
3009 GetDefInput input(scopeStr,nameStr,argsStr);
3010 input.forceEmptyScope = explicitScope;
3011 input.currentFile = currentFile;
3012 input.checkCV = true;
3013 GetDefResult result = getDefs(input);
3014 if (result.found)
3015 {
3016 //printf("after getDefs checkScope=%d nameStr=%s\n",checkScope,qPrint(nameStr));
3017 if (checkScope && result.md && result.md->getOuterScope()==Doxygen::globalScope &&
3018 !result.md->isStrongEnumValue() &&
3019 (!scopeStr.isEmpty() || nameStr.find("::")>0))
3020 {
3021 // we did find a member, but it is a global one while we were explicitly
3022 // looking for a scoped variable. See bug 616387 for an example why this check is needed.
3023 // note we do need to support autolinking to "::symbol" hence the >0
3024 //printf("not global member!\n");
3025 *resContext=nullptr;
3026 *resMember=nullptr;
3027 AUTO_TRACE_ADD("false");
3028 return FALSE;
3029 }
3030 //printf("after getDefs md=%p cd=%p fd=%p nd=%p gd=%p\n",md,cd,fd,nd,gd);
3031 if (result.md) {
3032 if (!allowTypeOnly || result.md->isTypedef() || result.md->isEnumerate())
3033 {
3034 *resMember=result.md;
3035 *resContext=result.md;
3036 }
3037 else // md is not a type, but we explicitly expect one
3038 {
3039 *resContext=nullptr;
3040 *resMember=nullptr;
3041 AUTO_TRACE_ADD("false");
3042 return FALSE;
3043 }
3044 }
3045 else if (result.cd) *resContext=result.cd;
3046 else if (result.nd) *resContext=result.nd;
3047 else if (result.fd) *resContext=result.fd;
3048 else if (result.gd) *resContext=result.gd;
3049 else { *resContext=nullptr; *resMember=nullptr; return FALSE; }
3050 //printf("member=%s (md=%p) anchor=%s linkable()=%d context=%s\n",
3051 // qPrint(md->name()), md, qPrint(md->anchor()), md->isLinkable(), qPrint((*resContext)->name()));
3052 AUTO_TRACE_ADD("true");
3053 return TRUE;
3054 }
3055 else if (inSeeBlock && !nameStr.isEmpty() && (gd=Doxygen::groupLinkedMap->find(nameStr)))
3056 { // group link
3057 *resContext=gd;
3058 AUTO_TRACE_ADD("true");
3059 return TRUE;
3060 }
3061 else if ((cnd=Doxygen::conceptLinkedMap->find(nameStr)))
3062 {
3063 *resContext=cnd;
3064 AUTO_TRACE_ADD("true");
3065 return TRUE;
3066 }
3067 else if (tsName.find('.')!=-1) // maybe a link to a file
3068 {
3069 bool ambig = false;
3070 const FileDef *fd=findFileDef(Doxygen::inputNameLinkedMap,tsName,ambig);
3071 if (fd && !ambig)
3072 {
3073 *resContext=fd;
3074 AUTO_TRACE_ADD("true");
3075 return TRUE;
3076 }
3077 }
3078
3079 if (tryUnspecializedVersion)
3080 {
3081 bool b = resolveRef(scName,name,inSeeBlock,resContext,resMember,FALSE,nullptr,checkScope);
3082 AUTO_TRACE_ADD("{}",b);
3083 return b;
3084 }
3085 if (bracePos!=-1) // Try without parameters as well, could be a constructor invocation
3086 {
3087 *resContext=getClass(fullName.left(bracePos));
3088 if (*resContext)
3089 {
3090 AUTO_TRACE_ADD("true");
3091 return TRUE;
3092 }
3093 }
3094 //printf("resolveRef: %s not found!\n",qPrint(name));
3095
3096 AUTO_TRACE_ADD("false");
3097 return FALSE;
3098}
virtual Definition * getOuterScope() const =0
static ConceptLinkedMap * conceptLinkedMap
Definition doxygen.h:98
static NamespaceDefMutable * globalScope
Definition doxygen.h:121
virtual bool isStrongEnumValue() const =0
virtual bool isEnumerate() const =0
static bool isLowerCase(QCString &s)
Definition util.cpp:2865
GetDefResult getDefs(const GetDefInput &input)
Definition util.cpp:2742
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)
Definition util.cpp:2810

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

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

◆ resolveTypeDef()

QCString resolveTypeDef ( const Definition * d,
const QCString & name,
const Definition ** typedefContext = nullptr )

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}
The common base class of all entity definitions found in the sources.
Definition definition.h:76
virtual DefType definitionType() const =0
virtual const Definition * findInnerCompound(const QCString &name) const =0
static MemberNameLinkedMap * functionNameLinkedMap
Definition doxygen.h:112
static MemberNameLinkedMap * memberNameLinkedMap
Definition doxygen.h:111
virtual QCString typeString() const =0
virtual bool isRelated() const =0
virtual QCString argsString() const =0
Ordered dictionary of MemberName objects.
Definition membername.h:63
int isAccessibleFrom(const Definition *scope, const Definition *item)
Checks if symbol item is accessible from within scope.
#define AUTO_TRACE_EXIT(...)
Definition docnode.cpp:48
QCString resolveTypeDef(const Definition *context, const QCString &qualifiedName, const Definition **typedefContext)
Definition util.cpp:384
int getScopeFragment(const QCString &s, int p, int *l)
Definition util.cpp:4969

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

6737{
6738 if (s.isEmpty()) return s;
6739
6740 // helper to find the end of a block
6741 auto skipBlock = [&markerInfo](const char *p,const SelectionBlock &blk)
6742 {
6743 char c = 0;
6744 while ((c=*p))
6745 {
6746 if (c==markerInfo.markerChar && qstrncmp(p,markerInfo.endStr,markerInfo.endLen)==0) // end marker
6747 {
6748 size_t len = markerInfo.endLen;
6749 bool negate = *(p+markerInfo.endLen)=='!';
6750 if (negate) len++;
6751 size_t blkNameLen = qstrlen(blk.name);
6752 if (qstrncmp(p+len,blk.name,blkNameLen)==0 && // matching marker name
6753 qstrncmp(p+len+blkNameLen,markerInfo.closeStr,markerInfo.closeLen)==0) // matching marker closing
6754 {
6755 //printf("Found end marker %s enabled=%d negate=%d\n",blk.name,blk.enabled,negate);
6756 return p+len+blkNameLen+markerInfo.closeLen;
6757 }
6758 else // not the right marker id
6759 {
6760 p++;
6761 }
6762 }
6763 else // not and end marker
6764 {
6765 p++;
6766 }
6767 }
6768 return p;
6769 };
6770
6771 QCString result;
6772 result.reserve(s.length());
6773 const char *p = s.data();
6774 char c = 0;
6775 while ((c=*p))
6776 {
6777 if (c==markerInfo.markerChar) // potential start of marker
6778 {
6779 if (qstrncmp(p,markerInfo.beginStr,markerInfo.beginLen)==0) // start of begin marker
6780 {
6781 bool found = false;
6782 size_t len = markerInfo.beginLen;
6783 bool negate = *(p+len)=='!';
6784 if (negate) len++;
6785 for (const auto &blk : blockList)
6786 {
6787 size_t blkNameLen = qstrlen(blk.name);
6788 if (qstrncmp(p+len,blk.name,blkNameLen)==0 && // matching marker name
6789 qstrncmp(p+len+blkNameLen,markerInfo.closeStr,markerInfo.closeLen)==0) // matching marker closing
6790 {
6791 bool blockEnabled = blk.enabled!=negate;
6792 //printf("Found start marker %s enabled=%d negate=%d\n",blk.name,blk.enabled,negate);
6793 p+=len+blkNameLen+markerInfo.closeLen;
6794 if (!blockEnabled) // skip until the end of the block
6795 {
6796 //printf("skipping block\n");
6797 p=skipBlock(p,blk);
6798 }
6799 found=true;
6800 break;
6801 }
6802 }
6803 if (!found) // unknown marker id
6804 {
6805 result+=c;
6806 p++;
6807 }
6808 }
6809 else if (qstrncmp(p,markerInfo.endStr,markerInfo.endLen)==0) // start of end marker
6810 {
6811 bool found = false;
6812 size_t len = markerInfo.endLen;
6813 bool negate = *(p+len)=='!';
6814 if (negate) len++;
6815 for (const auto &blk : blockList)
6816 {
6817 size_t blkNameLen = qstrlen(blk.name);
6818 if (qstrncmp(p+len,blk.name,blkNameLen)==0 && // matching marker name
6819 qstrncmp(p+len+blkNameLen,markerInfo.closeStr,markerInfo.closeLen)==0) // matching marker closing
6820 {
6821 //printf("Found end marker %s enabled=%d negate=%d\n",blk.name,blk.enabled,negate);
6822 p+=len+blkNameLen+markerInfo.closeLen;
6823 found=true;
6824 break;
6825 }
6826 }
6827 if (!found) // unknown marker id
6828 {
6829 result+=c;
6830 p++;
6831 }
6832 }
6833 else // not a start or end marker
6834 {
6835 result+=c;
6836 p++;
6837 }
6838 }
6839 else // not a marker character
6840 {
6841 result+=c;
6842 p++;
6843 }
6844 }
6845 //printf("====\n%s\n-----\n%s\n~~~~\n",qPrint(s),qPrint(result));
6846 return result;
6847}
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().

◆ showFileDefMatches()

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

Definition at line 3388 of file util.cpp.

3389{
3390 QCString result;
3391 QCString name=n;
3392 QCString path;
3393 int slashPos=std::max(name.findRev('/'),name.findRev('\\'));
3394 if (slashPos!=-1)
3395 {
3396 path=name.left(slashPos+1);
3397 name=name.right(name.length()-slashPos-1);
3398 }
3399 const FileName *fn=fnMap->find(name);
3400 if (fn)
3401 {
3402 bool first = true;
3403 for (const auto &fd : *fn)
3404 {
3405 if (path.isEmpty() || fd->getPath().right(path.length())==path)
3406 {
3407 if (!first) result += "\n";
3408 else first = false;
3409 result+=" "+fd->absFilePath();
3410 }
3411 }
3412 }
3413 return result;
3414}

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

6963{
6964 StringVector result;
6965 reg::Iterator iter(s, delimiter);
6967 size_t p=0;
6968 for ( ; iter != end; ++iter)
6969 {
6970 const auto &match = *iter;
6971 size_t i=match.position();
6972 size_t l=match.length();
6973 if (i>p) result.push_back(s.substr(p,i-p));
6974 p=i+l;
6975 }
6976 if (p<s.length()) result.push_back(s.substr(p));
6977 return result;
6978}

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

6946{
6947 StringVector result;
6948 size_t prev = 0, pos = 0, len = s.length();
6949 do
6950 {
6951 pos = s.find(delimiter, prev);
6952 if (pos == std::string::npos) pos = len;
6953 if (pos>prev) result.push_back(s.substr(prev,pos-prev));
6954 prev = pos + delimiter.length();
6955 }
6956 while (pos<len && prev<len);
6957 return result;
6958}

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

5778{
5779#ifdef TRACINGSUPPORT
5780 void *backtraceFrames[128];
5781 int frameCount = backtrace(backtraceFrames, 128);
5782 const size_t cmdLen = 40960;
5783 static char cmd[cmdLen];
5784 char *p = cmd;
5785 p += qsnprintf(p,cmdLen,"/usr/bin/atos -p %d ", (int)getpid());
5786 for (int x = 0; x < frameCount; x++)
5787 {
5788 p += qsnprintf(p,cmdLen,"%p ", backtraceFrames[x]);
5789 }
5790 fprintf(stderr,"========== STACKTRACE START ==============\n");
5791 if (FILE *fp = Portable::popen(cmd, "r"))
5792 {
5793 char resBuf[512];
5794 while (size_t len = fread(resBuf, 1, sizeof(resBuf), fp))
5795 {
5796 fwrite(resBuf, 1, len, stderr);
5797 }
5798 Portable::pclose(fp);
5799 }
5800 fprintf(stderr,"============ STACKTRACE END ==============\n");
5801 //fprintf(stderr,"%s\n", frameStrings[x]);
5802#endif
5803}

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(), buildNamespaceList(), computeTemplateClassRelations(), extractClassName(), findGroupScope(), findUsingDeclImports(), findUsingDirectives(), MemberDefImpl::getClassDefOfAnonymousType(), and resolveClassNestingRelations().

◆ stripExtension()

QCString stripExtension ( const QCString & fName)

Definition at line 5265 of file util.cpp.

5266{
5268}
QCString stripExtensionGeneral(const QCString &fName, const QCString &ext)
Definition util.cpp:5255

References Doxygen::htmlFileExtension, and stripExtensionGeneral().

Referenced by anonymous_namespace{tagreader.cpp}::TagFileParser::buildLists(), ClassDefImpl::IMPL::init(), 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()

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

6282{
6283 if (s.isEmpty()) return s; // empty string -> we're done
6284
6285 //printf("stripIndentation:\n%s\n------\n",qPrint(s));
6286 // compute minimum indentation over all lines
6287 const char *p=s.data();
6288 char c=0;
6289 int indent=0;
6290 int minIndent=1000000; // "infinite"
6291 bool searchIndent=TRUE;
6292 int tabSize=Config_getInt(TAB_SIZE);
6293 while ((c=*p++))
6294 {
6295 if (c=='\t') indent+=tabSize - (indent%tabSize);
6296 else if (c=='\n') indent=0,searchIndent=TRUE;
6297 else if (c==' ') indent++;
6298 else if (searchIndent)
6299 {
6300 searchIndent=FALSE;
6301 if (indent<minIndent) minIndent=indent;
6302 }
6303 }
6304
6305 // no indent to remove -> we're done
6306 if (minIndent==0) return substitute(s,"@ilinebr","\\ilinebr");
6307
6308 // remove minimum indentation for each line
6309 TextStream result;
6310 p=s.data();
6311 indent=0;
6312 while ((c=*p++))
6313 {
6314 if (c=='\n') // start of new line
6315 {
6316 indent=0;
6317 result << c;
6318 }
6319 else if (indent<minIndent) // skip until we reach minIndent
6320 {
6321 if (c=='\t')
6322 {
6323 int newIndent = indent+tabSize-(indent%tabSize);
6324 int i=newIndent;
6325 while (i>minIndent) // if a tab crosses the minIndent boundary fill the rest with spaces
6326 {
6327 result << ' ';
6328 i--;
6329 }
6330 indent=newIndent;
6331 }
6332 else // space
6333 {
6334 indent++;
6335 }
6336 }
6337 else if (c=='\\' && qstrncmp(p,"ilinebr ",8)==0)
6338 // we also need to remove the indentation after a \ilinebr command at the end of a line
6339 {
6340 result << "\\ilinebr ";
6341 p+=8;
6342 int skipAmount=0;
6343 for (int j=0;j<minIndent;j++) if (*(p+j)==' ') skipAmount++; // test to see if we have the indent
6344 if (skipAmount==minIndent)
6345 {
6346 p+=skipAmount; // remove the indent
6347 }
6348 }
6349 else if (c=='@' && qstrncmp(p,"ilinebr",7)==0)
6350 {
6351 result << "\\ilinebr";
6352 p+=7;
6353 }
6354 else // copy anything until the end of the line
6355 {
6356 result << c;
6357 }
6358 }
6359
6360 //printf("stripIndentation: result=\n%s\n------\n",qPrint(result.str()));
6361
6362 return result.str();
6363}

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

6367{
6368 //printf("stripIndentationVerbatim(level=%d):\n%s\n------\n",indentationLevel,qPrint(doc));
6369 if (indentationLevel <= 0 || doc.isEmpty()) return; // nothing to strip
6370
6371 // by stripping content the string will only become shorter so we write the results
6372 // back into the input string and then resize it at the end.
6373 char c = 0;
6374 const char *src = doc.data();
6375 char *dst = doc.rawData();
6376 bool insideIndent = false; // skip the initial line from stripping
6377 int cnt = 0;
6378 while ((c=*src++))
6379 {
6380 // invariant: dst<=src
6381 switch(c)
6382 {
6383 case '\n':
6384 *dst++ = c;
6385 insideIndent = true;
6386 cnt = indentationLevel;
6387 break;
6388 case ' ':
6389 if (insideIndent)
6390 {
6391 if (cnt>0) // count down the spacing until the end of the indent
6392 {
6393 cnt--;
6394 }
6395 else // reached the end of the indent, start of the part of the line to keep
6396 {
6397 insideIndent = false;
6398 *dst++ = c;
6399 }
6400 }
6401 else // part after indent, copy to the output
6402 {
6403 *dst++ = c;
6404 }
6405 break;
6406 default:
6407 insideIndent = false;
6408 *dst++ = c;
6409 break;
6410 }
6411 }
6412 doc.resize(static_cast<uint32_t>(dst-doc.data()));
6413 //printf("stripIndentationVerbatim: result=\n%s\n------\n",qPrint(doc));
6414}
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().

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

5369{
5370 if (s.isEmpty()) return QCString();
5371 const char *p = s.data();
5372
5373 // search for leading empty lines
5374 int i=0,li=-1,l=static_cast<int>(s.length());
5375 char c = 0;
5376 while ((c=*p))
5377 {
5378 if (c==' ' || c=='\t' || c=='\r') i++,p++;
5379 else if (c=='\\' && qstrncmp(p,"\\ilinebr",8)==0) i+=8,li=i,p+=8;
5380 else if (c=='\n') i++,li=i,docLine++,p++;
5381 else break;
5382 }
5383
5384 // search for trailing empty lines
5385 int b=l-1,bi=-1;
5386 p=s.data()+b;
5387 while (b>=0)
5388 {
5389 c=*p;
5390 if (c==' ' || c=='\t' || c=='\r') b--,p--;
5391 else if (c=='r' && b>=7 && qstrncmp(p-7,"\\ilinebr",8)==0) bi=b-7,b-=8,p-=8;
5392 else if (c=='>' && b>=11 && qstrncmp(p-11,"\\ilinebr<br>",12)==0) bi=b-11,b-=12,p-=12;
5393 else if (c=='\n') bi=b,b--,p--;
5394 else break;
5395 }
5396
5397 // return whole string if no leading or trailing lines where found
5398 if (li==-1 && bi==-1) return s;
5399
5400 // return substring
5401 if (bi==-1) bi=l;
5402 if (li==-1) li=0;
5403 if (bi<=li) return QCString(); // only empty lines
5404 //printf("docLine='%s' len=%d li=%d bi=%d\n",qPrint(s),s.length(),li,bi);
5405 return s.mid(li,bi-li);
5406}

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

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

◆ stripPath()

QCString stripPath ( const QCString & s)

Definition at line 5292 of file util.cpp.

5293{
5294 QCString result=s;
5295 int i=result.findRev('/');
5296 if (i!=-1)
5297 {
5298 result=result.mid(i+1);
5299 }
5300 i=result.findRev('\\');
5301 if (i!=-1)
5302 {
5303 result=result.mid(i+1);
5304 }
5305 return result;
5306}

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

4134{
4135 QCString result = name;
4136 int l = static_cast<int>(result.length());
4137 int p = 0;
4138 bool done = FALSE;
4139 bool skipBracket=FALSE; // if brackets do not match properly, ignore them altogether
4140 int count=0;
4141 int round=0;
4142
4143 do
4144 {
4145 p=l-1; // start at the end of the string
4146 while (p>=0 && count>=0)
4147 {
4148 char c=result.at(p);
4149 switch (c)
4150 {
4151 case ':':
4152 // only exit in the case of ::
4153 //printf("stripScope(%s)=%s\n",name,qPrint(result.right(l-p-1)));
4154 if (p>0 && result.at(p-1)==':' && (count==0 || skipBracket))
4155 {
4156 return result.right(l-p-1);
4157 }
4158 p--;
4159 break;
4160 case '>':
4161 if (skipBracket) // we don't care about brackets
4162 {
4163 p--;
4164 }
4165 else // count open/close brackets
4166 {
4167 if (p>0 && result.at(p-1)=='>') // skip >> operator
4168 {
4169 p-=2;
4170 break;
4171 }
4172 count=1;
4173 //printf("pos < = %d\n",p);
4174 p--;
4175 bool foundMatch=false;
4176 while (p>=0 && !foundMatch)
4177 {
4178 c=result.at(p--);
4179 switch (c)
4180 {
4181 case ')':
4182 round++;
4183 break;
4184 case '(':
4185 round--;
4186 break;
4187 case '>': // ignore > inside (...) to support e.g. (sizeof(T)>0) inside template parameters
4188 if (round==0) count++;
4189 break;
4190 case '<':
4191 if (round==0)
4192 {
4193 if (p>0)
4194 {
4195 if (result.at(p-1) == '<') // skip << operator
4196 {
4197 p--;
4198 break;
4199 }
4200 }
4201 count--;
4202 foundMatch = count==0;
4203 }
4204 break;
4205 default:
4206 //printf("c=%c count=%d\n",c,count);
4207 break;
4208 }
4209 }
4210 }
4211 //printf("pos > = %d\n",p+1);
4212 break;
4213 default:
4214 p--;
4215 }
4216 }
4217 done = count==0 || skipBracket; // reparse if brackets do not match
4218 skipBracket=TRUE;
4219 }
4220 while (!done); // if < > unbalanced repeat ignoring them
4221 //printf("stripScope(%s)=%s\n",name,name);
4222 return name;
4223}

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

Referenced by DotClassGraph::addClass(), DocRef::DocRef(), generateJSLink(), getCanonicalTypeForIdentifier(), DefinitionImpl::IMPL::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 4867 of file util.cpp.

4872{
4873 //printf("stripTemplateSpecifiersFromScope(name=%s,scopeName=%s)\n",qPrint(fullName),qPrint(scopeName));
4874 int i=fullName.find('<');
4875 if (i==-1) return fullName;
4876 QCString result;
4877 int p=0;
4878 int l=static_cast<int>(fullName.length());
4879 while (i!=-1)
4880 {
4881 //printf("1:result+=%s\n",qPrint(fullName.mid(p,i-p)));
4882 int e=i+1;
4883 int count=1;
4884 int round=0;
4885 while (e<l && count>0)
4886 {
4887 char c=fullName.at(e++);
4888 switch (c)
4889 {
4890 case '(': round++; break;
4891 case ')': if (round>0) round--; break;
4892 case '<': if (round==0) count++; break;
4893 case '>': if (round==0) count--; break;
4894 default:
4895 break;
4896 }
4897 }
4898 int si= fullName.find("::",e);
4899
4900 if (parentOnly && si==-1) break;
4901 // we only do the parent scope, so we stop here if needed
4902
4903 result+=fullName.mid(p,i-p);
4904 //printf(" trying %s\n",qPrint(mergeScopes(scopeName,result+fullName.mid(i,e-i))));
4905 ClassDef *cd = getClass(mergeScopes(scopeName,result+fullName.mid(i,e-i)));
4906 if (cd!=nullptr && (allowArtificial || !cd->isArtificial()))
4907 {
4908 result+=fullName.mid(i,e-i);
4909 //printf(" 2:result+=%s\n",qPrint(fullName.mid(i,e-i-1)));
4910 }
4911 else if (pLastScopeStripped)
4912 {
4913 //printf(" last stripped scope '%s'\n",qPrint(fullName.mid(i,e-i)));
4914 *pLastScopeStripped=fullName.mid(i,e-i);
4915 }
4916 p=e;
4917 i=fullName.find('<',p);
4918 }
4919 result+=fullName.right(l-p);
4920 //printf("3:result+=%s\n",qPrint(fullName.right(l-p)));
4921 //printf("end result=%s\n",qPrint(result));
4922 return result;
4923}
virtual bool isArtificial() const =0
QCString mergeScopes(const QCString &leftScope, const QCString &rightScope)
Definition util.cpp:4934

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

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

◆ substituteClassNames()

QCString substituteClassNames ( const QCString & s)

◆ substituteKeywords() [1/2]

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

Definition at line 3418 of file util.cpp.

3419{
3420 std::string substRes;
3421 const char *p = s.data();
3422 if (p)
3423 {
3424 // reserve some room for expansion
3425 substRes.reserve(s.length()+1024);
3426 char c = 0;
3427 while ((c=*p))
3428 {
3429 bool found = false;
3430 if (c=='$')
3431 {
3432 for (const auto &kw : keywords)
3433 {
3434 size_t keyLen = qstrlen(kw.keyword);
3435 if (qstrncmp(p,kw.keyword,keyLen)==0)
3436 {
3437 const char *startArg = p+keyLen;
3438 bool expectParam = std::holds_alternative<KeywordSubstitution::GetValueWithParam>(kw.getValueVariant);
3439 //printf("%s: expectParam=%d *startArg=%c\n",kw.keyword,expectParam,*startArg);
3440 if (expectParam && *startArg=='(') // $key(value)
3441 {
3442 size_t j=1;
3443 const char *endArg = nullptr;
3444 while ((c=*(startArg+j)) && c!=')' && c!='\n' && c!=0) j++;
3445 if (c==')') endArg=startArg+j;
3446 if (endArg)
3447 {
3448 QCString value = QCString(startArg+1).left(endArg-startArg-1);
3449 auto &&getValue = std::get<KeywordSubstitution::GetValueWithParam>(kw.getValueVariant);
3450 substRes+=getValue(value).str();
3451 p=endArg+1;
3452 //printf("found '%s'->'%s'\n",kw.keyword,qPrint(getValue(value)));
3453 }
3454 else
3455 {
3456 //printf("missing argument\n");
3457 p+=keyLen;
3458 }
3459 }
3460 else if (!expectParam) // $key
3461 {
3462 auto &&getValue = std::get<KeywordSubstitution::GetValue>(kw.getValueVariant);
3463 substRes+=getValue().str();
3464 //printf("found '%s'->'%s'\n",kw.keyword,qPrint(getValue()));
3465 p+=keyLen;
3466 }
3467 found = true;
3468 break;
3469 }
3470 }
3471 }
3472 if (!found) // copy
3473 {
3474 substRes+=c;
3475 p++;
3476 }
3477 }
3478 }
3479 return substRes;
3480}

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

3563{
3564 return substituteKeywords(s,
3565 {
3566 // keyword value getter
3567 { "$title", [&]() { return !title.isEmpty() ? title : projName; } },
3568 { "$datetime", [&]() { return dateToString(DateTimeType::DateTime); } },
3569 { "$date", [&]() { return dateToString(DateTimeType::Date); } },
3570 { "$time", [&]() { return dateToString(DateTimeType::Time); } },
3571 { "$year", [&]() { return yearToString(); } },
3572 { "$doxygenversion", [&]() { return getDoxygenVersion(); } },
3573 { "$projectname", [&]() { return projName; } },
3574 { "$projectnumber", [&]() { return projNum; } },
3575 { "$projectbrief", [&]() { return projBrief; } },
3576 { "$projectlogo", [&]() { return stripPath(projectLogoFile()); } },
3577 { "$logosize", [&]() { return projectLogoSize(); } },
3578 { "$projecticon", [&]() { return stripPath(Config_getString(PROJECT_ICON)); } },
3579 { "$langISO", [&]() { return theTranslator->trISOLang(); } },
3580 { "$showdate", [&](const QCString &fmt) { return showDate(fmt); } }
3581 });
3582}
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
Definition trace.h:153
QCString stripPath(const QCString &s)
Definition util.cpp:5292
QCString substituteKeywords(const QCString &s, const KeywordSubstitutionList &keywords)
Definition util.cpp:3418
QCString projectLogoFile()
Definition util.cpp:3495
static QCString projectLogoSize()
Definition util.cpp:3516
static QCString showDate(const QCString &fmt)
Definition util.cpp:3482

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

4709{
4710 AUTO_TRACE("name={} formalArgs={} actualArgs={}",nm,argListToString(formalArgs),actualArgs ? argListToString(*actualArgs) : QCString());
4711 if (formalArgs.empty()) return nm;
4712 QCString result;
4713
4714 static const reg::Ex re(R"(\a\w*)");
4715 std::string name = nm.str();
4716 reg::Iterator it(name,re);
4718 size_t p=0;
4719
4720 for (; it!=end ; ++it)
4721 {
4722 const auto &match = *it;
4723 size_t i = match.position();
4724 size_t l = match.length();
4725 if (i>p) result += name.substr(p,i-p);
4726 QCString n(match.str());
4728 if (actualArgs)
4729 {
4730 actIt = actualArgs->begin();
4731 }
4732 //printf(": name=%s\n",qPrint(name));
4733
4734 // if n is a template argument, then we substitute it
4735 // for its template instance argument.
4736 bool found=FALSE;
4737 for (auto formIt = formalArgs.begin();
4738 formIt!=formalArgs.end() && !found;
4739 ++formIt
4740 )
4741 {
4742 Argument formArg = *formIt;
4743 Argument actArg;
4744 if (actualArgs && actIt!=actualArgs->end())
4745 {
4746 actArg = *actIt;
4747 }
4748 if (formArg.type.startsWith("class ") && formArg.name.isEmpty())
4749 {
4750 formArg.name = formArg.type.mid(6);
4751 formArg.type = "class";
4752 }
4753 else if (formArg.type.startsWith("typename ") && formArg.name.isEmpty())
4754 {
4755 formArg.name = formArg.type.mid(9);
4756 formArg.type = "typename";
4757 }
4758 else if (formArg.type.startsWith("class...")) // match 'class... name' to 'name...'
4759 {
4760 formArg.name += "...";
4761 formArg.type = formArg.type.left(5)+formArg.type.mid(8);
4762 }
4763 else if (formArg.type.startsWith("typename...")) // match 'typename... name' to 'name...'
4764 {
4765 formArg.name += "...";
4766 formArg.type = formArg.type.left(8)+formArg.type.mid(11);
4767 }
4768 //printf(": n=%s formArg->type='%s' formArg->name='%s' formArg->defval='%s' actArg->type='%s' actArg->name='%s' \n",
4769 // qPrint(n),qPrint(formArg.type),qPrint(formArg.name),qPrint(formArg.defval),qPrint(actArg.type),qPrint(actArg.name));
4770 if (formArg.type=="class" || formArg.type=="typename" || formArg.type.startsWith("template"))
4771 {
4772 if (formArg.name==n && actualArgs && actIt!=actualArgs->end() && !actArg.type.isEmpty()) // base class is a template argument
4773 {
4774 static constexpr auto hasRecursion = [](const QCString &prefix,const QCString &nameArg,const QCString &subst) -> bool
4775 {
4776 int ii=0;
4777 int pp=0;
4778
4779 ii = subst.find('<');
4780 //printf("prefix='%s' subst='%s'\n",qPrint(prefix.mid(prefix.length()-ii-2,ii+1)),qPrint(subst.left(ii+1)));
4781 if (ii!=-1 && static_cast<int>(prefix.length())>=ii+2 && prefix.mid(prefix.length()-ii-2,ii+1)==subst.left(ii+1))
4782 {
4783 return true; // don't replace 'A< ' with 'A< A<...', see issue #10951
4784 }
4785
4786 while ((ii=subst.find(nameArg,pp))!=-1)
4787 {
4788 bool beforeNonWord = ii==0 || !isId(subst.at(ii-1));
4789 bool afterNonWord = subst.length()==ii+nameArg.length() || !isId(subst.at(ii+nameArg.length()));
4790 if (beforeNonWord && afterNonWord)
4791 {
4792 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
4793 }
4794 pp=ii+static_cast<int>(nameArg.length());
4795 }
4796 return false;
4797 };
4798 // replace formal argument with the actual argument of the instance
4799 AUTO_TRACE_ADD("result={} n={} type={} hasRecursion={}",result,n,actArg.type,hasRecursion(result,n,actArg.type));
4800 if (!hasRecursion(result,n,actArg.type))
4801 // the scope guard is to prevent recursive lockup for
4802 // template<class A> class C : public<A::T>,
4803 // where A::T would become A::T::T here,
4804 // since n==A and actArg->type==A::T
4805 // see bug595833 for an example
4806 //
4807 // Also prevent recursive substitution if n is part of actArg.type, i.e.
4808 // n='A' in argType='S< A >' would produce 'S< S< A > >'
4809 {
4810 if (actArg.name.isEmpty())
4811 {
4812 result += actArg.type;
4813 }
4814 else
4815 // for case where the actual arg is something like "unsigned int"
4816 // the "int" part is in actArg->name.
4817 {
4818 result += actArg.type+" "+actArg.name;
4819 }
4820 found=TRUE;
4821 }
4822 }
4823 else if (formArg.name==n &&
4824 (actualArgs==nullptr || actIt==actualArgs->end()) &&
4825 !formArg.defval.isEmpty() &&
4826 formArg.defval!=nm /* to prevent recursion */
4827 )
4828 {
4829 result += substituteTemplateArgumentsInString(formArg.defval,formalArgs,actualArgs);
4830 found=TRUE;
4831 }
4832 }
4833 else if (formArg.name==n &&
4834 (actualArgs==nullptr || actIt==actualArgs->end()) &&
4835 !formArg.defval.isEmpty() &&
4836 formArg.defval!=nm /* to prevent recursion */
4837 )
4838 {
4839 result += substituteTemplateArgumentsInString(formArg.defval,formalArgs,actualArgs);
4840 found=TRUE;
4841 }
4842 if (actualArgs && actIt!=actualArgs->end())
4843 {
4844 actIt++;
4845 }
4846 }
4847 if (!found)
4848 {
4849 result += n;
4850 }
4851 p=i+l;
4852 }
4853 result+=name.substr(p);
4854 result=result.simplifyWhiteSpace();
4855 AUTO_TRACE_EXIT("result={}",result);
4856 return result.stripWhiteSpace();
4857}
typename Vec::const_iterator const_iterator
Definition arguments.h:64
QCString substituteTemplateArgumentsInString(const QCString &nm, const ArgumentList &formalArgs, const ArgumentList *actualArgs)
Definition util.cpp:4705

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 includeDefaults = true )

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(), findTemplateInstanceRelation(), makeQualifiedNameWithTemplateParameters(), searchTemplateSpecs(), and writeDefArgumentList().

◆ 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
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)
int qstricmp(const char *s1, const char *s2)
Definition qcstring.cpp:442

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

◆ unescapeCharsInString()

QCString unescapeCharsInString ( const QCString & s)

Definition at line 3771 of file util.cpp.

3772{
3773 if (s.isEmpty()) return s;
3774 bool caseSenseNames = getCaseSenseNames();
3775 QCString result;
3776 const char *p = s.data();
3777 if (p)
3778 {
3779 char c = 0;
3780 while ((c=*p++))
3781 {
3782 if (c=='_') // 2 or 3 character escape
3783 {
3784 switch (*p)
3785 {
3786 case '_': result+=c; p++; break; // __ -> '_'
3787 case '1': result+=':'; p++; break; // _1 -> ':'
3788 case '2': result+='/'; p++; break; // _2 -> '/'
3789 case '3': result+='<'; p++; break; // _3 -> '<'
3790 case '4': result+='>'; p++; break; // _4 -> '>'
3791 case '5': result+='*'; p++; break; // _5 -> '*'
3792 case '6': result+='&'; p++; break; // _6 -> '&'
3793 case '7': result+='|'; p++; break; // _7 -> '|'
3794 case '8': result+='.'; p++; break; // _8 -> '.'
3795 case '9': result+='!'; p++; break; // _9 -> '!'
3796 case '0': // 3 character escape
3797 switch (*(p+1))
3798 {
3799 case '0': result+=','; p+=2; break; // _00 -> ','
3800 case '1': result+=' '; p+=2; break; // _01 -> ' '
3801 case '2': result+='{'; p+=2; break; // _02 -> '{'
3802 case '3': result+='}'; p+=2; break; // _03 -> '}'
3803 case '4': result+='?'; p+=2; break; // _04 -> '?'
3804 case '5': result+='^'; p+=2; break; // _05 -> '^'
3805 case '6': result+='%'; p+=2; break; // _06 -> '%'
3806 case '7': result+='('; p+=2; break; // _07 -> '('
3807 case '8': result+=')'; p+=2; break; // _08 -> ')'
3808 case '9': result+='+'; p+=2; break; // _09 -> '+'
3809 case 'a': result+='='; p+=2; break; // _0a -> '='
3810 case 'b': result+='$'; p+=2; break; // _0b -> '$'
3811 case 'c': result+='\\'; p+=2; break;// _0c -> '\'
3812 case 'd': result+='@'; p+=2; break; // _0d -> '@'
3813 case 'e': result+=']'; p+=2; break; // _0e -> ']'
3814 case 'f': result+='['; p+=2; break; // _0f -> '['
3815 case 'g': result+='#'; p+=2; break; // _0g -> '#'
3816 case 'h': result+='"'; p+=2; break; // _0h -> '"'
3817 case 'i': result+='~'; p+=2; break; // _0i -> '~'
3818 case 'j': result+='\''; p+=2; break;// _0j -> '\'
3819 case 'k': result+=';'; p+=2; break; // _0k -> ';'
3820 case 'l': result+='`'; p+=2; break; // _0l -> '`'
3821 default: // unknown escape, just pass underscore character as-is
3822 result+=c;
3823 break;
3824 }
3825 break;
3826 default:
3827 if (!caseSenseNames && c>='a' && c<='z') // lower to upper case escape, _a -> 'A'
3828 {
3829 result+=static_cast<char>(toupper(*p));
3830 p++;
3831 }
3832 else // unknown escape, pass underscore character as-is
3833 {
3834 result+=c;
3835 }
3836 break;
3837 }
3838 }
3839 else // normal character; pass as is
3840 {
3841 result+=c;
3842 }
3843 }
3844 }
3845 return result;
3846}

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

◆ updateColumnCount()

size_t updateColumnCount ( const char * s,
size_t col )

Definition at line 7207 of file util.cpp.

7208{
7209 if (s)
7210 {
7211 const int tabSize = Config_getInt(TAB_SIZE);
7212 char c;
7213 while ((c=*s++))
7214 {
7215 switch(c)
7216 {
7217 case '\t': col+=tabSize - (col%tabSize);
7218 break;
7219 case '\n': col=0;
7220 break;
7221 default:
7222 col++;
7223 if (c<0) // multi-byte character
7224 {
7225 int numBytes = getUTF8CharNumBytes(c);
7226 for (int i=0;i<numBytes-1 && (c=*s++);i++) {} // skip over extra chars
7227 if (c==0) return col; // end of string half way a multibyte char
7228 }
7229 break;
7230 }
7231 }
7232 }
7233 return col;
7234}

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 & parser )

Definition at line 5444 of file util.cpp.

5445{
5446 QCString langName = language.lower();
5447 auto it1 = std::find_if(g_lang2extMap.begin(),g_lang2extMap.end(),
5448 [&langName](const auto &info) { return info.langName==langName; });
5449 if (it1 == g_lang2extMap.end()) return false;
5450
5451 // found the language
5452 SrcLangExt parserId = it1->parserId;
5453 QCString extName = extension.lower();
5454 if (extName.isEmpty()) return FALSE;
5455 if (extName.at(0)!='.') extName.prepend(".");
5456 auto it2 = g_extLookup.find(extName.str());
5457 if (it2!=g_extLookup.end())
5458 {
5459 g_extLookup.erase(it2); // language was already register for this ext
5460 }
5461 //printf("registering extension %s\n",qPrint(extName));
5462 g_extLookup.emplace(extName.str(),parserId);
5463 if (!Doxygen::parserManager->registerExtension(extName,it1->parserName))
5464 {
5465 err("Failed to assign extension %s to parser %s for language %s\n",
5466 extName.data(),it1->parserName,qPrint(language));
5467 }
5468 else
5469 {
5470 //msg("Registered extension %s to language parser %s...\n",
5471 // extName.data(),qPrint(language));
5472 }
5473 return TRUE;
5474}
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(), qPrint(), 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 6094 of file util.cpp.

6095{
6096 int hue = Config_getInt(HTML_COLORSTYLE_HUE);
6097 int sat = Config_getInt(HTML_COLORSTYLE_SAT);
6098 int gamma = Config_getInt(HTML_COLORSTYLE_GAMMA);
6099 while (data->name)
6100 {
6101 QCString fileName = dir+"/"+data->name;
6102 ColoredImage img(data->width,data->height,data->content,data->alpha,
6103 sat,hue,gamma);
6104 if (!img.save(fileName))
6105 {
6106 fprintf(stderr,"Warning: Cannot open file %s for writing\n",data->name);
6107 }
6108 Doxygen::indexList->addImageFile(data->name);
6109 data++;
6110 }
6111}
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:412
unsigned short height
Definition util.h:411
const unsigned char * alpha
Definition util.h:413
unsigned short width
Definition util.h:410
const char * name
Definition util.h:409

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 & el )

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 writeString(const QCString &text)
Definition outputlist.h:412
void disable(OutputType o)
void pushGeneratorState()
void popGeneratorState()
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 )

◆ writeTypeConstraints()

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

Definition at line 5755 of file util.cpp.

5756{
5757 if (al.empty()) return;
5758 ol.startConstraintList(theTranslator->trTypeConstraints());
5759 for (const Argument &a : al)
5760 {
5762 ol.parseText(a.name);
5763 ol.endConstraintParam();
5765 linkifyText(TextGeneratorOLImpl(ol),d,nullptr,nullptr,a.type);
5766 ol.endConstraintType();
5768 ol.generateDoc(d->docFile(),d->docLine(),d,nullptr,a.docs,TRUE,FALSE,
5769 QCString(),FALSE,FALSE,Config_getBool(MARKDOWN_SUPPORT));
5770 ol.endConstraintDocs();
5771 }
5772 ol.endConstraintList();
5773}
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().