My Project
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Classes | Macros | Functions | Variables
util.cpp File Reference
#include <stdlib.h>
#include <ctype.h>
#include <errno.h>
#include <math.h>
#include <limits.h>
#include "md5.h"
#include <qregexp.h>
#include <qfileinfo.h>
#include <qdir.h>
#include <qdatetime.h>
#include <qcache.h>
#include "util.h"
#include "message.h"
#include "classdef.h"
#include "filedef.h"
#include "doxygen.h"
#include "outputlist.h"
#include "defargs.h"
#include "language.h"
#include "config.h"
#include "htmlhelp.h"
#include "example.h"
#include "version.h"
#include "groupdef.h"
#include "reflist.h"
#include "pagedef.h"
#include "debug.h"
#include "searchindex.h"
#include "textdocvisitor.h"
#include "portable.h"
#include "parserintf.h"
#include "bufstr.h"
#include "image.h"
#include "growbuf.h"
#include "entry.h"
#include "arguments.h"
#include "memberlist.h"
#include "classlist.h"
#include "namespacedef.h"
#include "membername.h"
#include "filename.h"
#include "membergroup.h"
#include "dirdef.h"
#include "htmlentity.h"

Go to the source code of this file.

Classes

class  AccessStack
 
struct  AccessStack::AccessElem
 
struct  CharAroundSpace
 
struct  CharAroundSpace::CharElem
 
struct  FindFileCacheElem
 
struct  Lang2ExtMap
 
struct  Marker
 

Macros

#define ENABLE_TRACINGSUPPORT   0
 
#define ALGO_COUNT   1
 
#define ALGO_CRC16   2
 
#define ALGO_MD5   3
 
#define MAP_ALGO   ALGO_MD5
 
#define REL_PATH_TO_ROOT   "../../"
 
#define MATCH
 
#define NOMATCH
 
#define HEXTONUM(x)
 

Functions

QCString removeAnonymousScopes (const QCString &s)
 
QCString replaceAnonymousScopes (const QCString &s, const char *replacement)
 
QCString stripAnonymousNamespaceScope (const QCString &s)
 
void writePageRef (OutputDocInterface &od, const char *cn, const char *mn)
 
QCString generateMarker (int id)
 
static QCString stripFromPath (const QCString &path, QStrList &l)
 
QCString stripFromPath (const QCString &path)
 
QCString stripFromIncludePath (const QCString &path)
 
int guessSection (const char *name)
 
QCString resolveTypeDef (Definition *context, const QCString &qualifiedName, Definition **typedefContext)
 
ClassDefgetClass (const char *n)
 
NamespaceDefgetResolvedNamespace (const char *name)
 
static ClassDefgetResolvedClassRec (Definition *scope, FileDef *fileScope, const char *n, MemberDef **pTypeDef, QCString *pTemplSpec, QCString *pResolvedType)
 
int isAccessibleFromWithExpScope (Definition *scope, FileDef *fileScope, Definition *item, const QCString &explicitScopePart)
 
ClassDefnewResolveTypedef (FileDef *fileScope, MemberDef *md, MemberDef **pMemType, QCString *pTemplSpec, QCString *pResolvedType, ArgumentList *actTemplParams)
 
static QCString substTypedef (Definition *scope, FileDef *fileScope, const QCString &name, MemberDef **pTypeDef=0)
 
static DefinitionendOfPathIsUsedClass (SDict< Definition > *cl, const QCString &localName)
 
static DefinitionfollowPath (Definition *start, FileDef *fileScope, const QCString &path)
 
bool accessibleViaUsingClass (const SDict< Definition > *cl, FileDef *fileScope, Definition *item, const QCString &explicitScopePart="")
 
bool accessibleViaUsingNamespace (const NamespaceSDict *nl, FileDef *fileScope, Definition *item, const QCString &explicitScopePart="")
 
int isAccessibleFrom (Definition *scope, FileDef *fileScope, Definition *item)
 
int computeQualifiedIndex (const QCString &name)
 
static void getResolvedSymbol (Definition *scope, FileDef *fileScope, Definition *d, const QCString &explicitScopePart, ArgumentList *actTemplParams, int &minDistance, ClassDef *&bestMatch, MemberDef *&bestTypedef, QCString &bestTemplSpec, QCString &bestResolvedType)
 
ClassDefgetResolvedClass (Definition *scope, FileDef *fileScope, const char *n, MemberDef **pTypeDef, QCString *pTemplSpec, bool mayBeUnlinkable, bool mayBeHidden, QCString *pResolvedType)
 
static bool findOperator (const QCString &s, int i)
 
static bool findOperator2 (const QCString &s, int i)
 
QCString removeRedundantWhiteSpace (const QCString &s)
 
int findParameterList (const QCString &name)
 
bool rightScopeMatch (const QCString &scope, const QCString &name)
 
bool leftScopeMatch (const QCString &scope, const QCString &name)
 
void linkifyText (const TextGeneratorIntf &out, Definition *scope, FileDef *fileScope, Definition *self, const char *text, bool autoBreak, bool external, bool keepSpaces, int indentLevel)
 
void writeExample (OutputList &ol, ExampleSDict *ed)
 
QCString argListToString (ArgumentList *al, bool useCanonicalType, bool showDefVals)
 
QCString tempArgListToString (ArgumentList *al, SrcLangExt lang)
 
void setAnchors (MemberList *ml)
 
int filterCRLF (char *buf, int len)
 
static QCString getFilterFromList (const char *name, const QStrList &filterList, bool &found)
 
QCString getFileFilter (const char *name, bool isSourceCode)
 
QCString transcodeCharacterStringToUTF8 (const QCString &input)
 
QCString fileToString (const char *name, bool filter, bool isSourceCode)
 
QCString dateToString (bool includeTime)
 
QCString yearToString ()
 
int minClassDistance (const ClassDef *cd, const ClassDef *bcd, int level)
 
Protection classInheritedProtectionLevel (ClassDef *cd, ClassDef *bcd, Protection prot, int level)
 
static QCString trimTemplateSpecifiers (const QCString &namespaceName, const QCString &className, const QCString &s)
 
static int findScopePattern (const QCString &pattern, const QCString &s, int p, int *len)
 
static QCString trimScope (const QCString &name, const QCString &s)
 
void trimBaseClassScope (BaseClassList *bcl, QCString &s, int level=0)
 
static void stripIrrelevantString (QCString &target, const QCString &str)
 
void stripIrrelevantConstVolatile (QCString &s)
 
static bool matchArgument (const Argument *srcA, const Argument *dstA, const QCString &className, const QCString &namespaceName, NamespaceSDict *usingNamespaces, SDict< Definition > *usingClasses)
 
bool matchArguments (ArgumentList *srcAl, ArgumentList *dstAl, const char *cl, const char *ns, bool checkCV, NamespaceSDict *usingNamespaces, SDict< Definition > *usingClasses)
 
static QCString stripDeclKeywords (const QCString &s)
 
static QCString extractCanonicalType (Definition *d, FileDef *fs, QCString type)
 
QCString getCanonicalTemplateSpec (Definition *d, FileDef *fs, const QCString &spec)
 
static QCString getCanonicalTypeForIdentifier (Definition *d, FileDef *fs, const QCString &word, QCString *tSpec, int count=0)
 
static QCString extractCanonicalArgType (Definition *d, FileDef *fs, const Argument *arg)
 
static bool matchArgument2 (Definition *srcScope, FileDef *srcFileScope, Argument *srcA, Definition *dstScope, FileDef *dstFileScope, Argument *dstA)
 
bool matchArguments2 (Definition *srcScope, FileDef *srcFileScope, ArgumentList *srcAl, Definition *dstScope, FileDef *dstFileScope, ArgumentList *dstAl, bool checkCV)
 
void mergeArguments (ArgumentList *srcAl, ArgumentList *dstAl, bool forceNameOverwrite)
 
static void findMembersWithSpecificName (MemberName *mn, const char *args, bool checkStatics, FileDef *currentFile, bool checkCV, const char *forceTagFile, QList< MemberDef > &members)
 
bool getDefs (const QCString &scName, const QCString &mbName, const char *args, MemberDef *&md, ClassDef *&cd, FileDef *&fd, NamespaceDef *&nd, GroupDef *&gd, bool forceEmptyScope, FileDef *currentFile, bool checkCV, const char *forceTagFile)
 
static bool getScopeDefs (const char *docScope, const char *scope, ClassDef *&cd, NamespaceDef *&nd)
 
static bool isLowerCase (QCString &s)
 
bool resolveRef (const char *scName, const char *name, bool inSeeBlock, Definition **resContext, MemberDef **resMember, bool lookForSpecialization, FileDef *currentFile, bool checkScope)
 
QCString linkToText (SrcLangExt lang, const char *link, bool isFileName)
 
bool resolveLink (const char *scName, const char *lr, bool, Definition **resContext, QCString &resAnchor)
 
bool generateLink (OutputDocInterface &od, const char *clName, const char *lr, bool inSeeBlock, const char *lt)
 
void generateFileRef (OutputDocInterface &od, const char *name, const char *text)
 
static QCache< FindFileCacheElemg_findFileDefCache (5000)
 
FileDeffindFileDef (const FileNameDict *fnDict, const char *n, bool &ambig)
 
QCString showFileDefMatches (const FileNameDict *fnDict, const char *n)
 
QCString substitute (const QCString &s, const QCString &src, const QCString &dst)
 substitute all occurrences of src in s by dst
 
QCString substituteKeywords (const QCString &s, const char *title, const char *projName, const char *projNum, const char *projBrief)
 
int getPrefixIndex (const QCString &name)
 
static void initBaseClassHierarchy (BaseClassList *bcl)
 
bool classHasVisibleChildren (ClassDef *cd)
 
void initClassHierarchy (ClassSDict *cl)
 
bool hasVisibleRoot (BaseClassList *bcl)
 
QCString escapeCharsInString (const char *name, bool allowDots, bool allowUnderscore)
 
QCString convertNameToFile (const char *name, bool allowDots, bool allowUnderscore)
 
QCString relativePathToRoot (const char *name)
 
void createSubDirs (QDir &d)
 
void extractNamespaceName (const QCString &scopeName, QCString &className, QCString &namespaceName, bool allowEmptyClass)
 
QCString insertTemplateSpecifierInScope (const QCString &scope, const QCString &templ)
 
QCString stripScope (const char *name)
 
QCString convertToId (const char *s)
 
QCString convertToXML (const char *s)
 
QCString convertToHtml (const char *s, bool keepEntities)
 
QCString convertToJSString (const char *s)
 
QCString convertToLaTeX (const QCString &s, bool insideTabbing, bool keepSpaces)
 
QCString convertCharEntitiesToUTF8 (const QCString &s)
 
QCString getOverloadDocs ()
 
void addMembersToMemberGroup (MemberList *ml, MemberGroupSDict **ppMemberGroupSDict, Definition *context)
 
int extractClassNameFromType (const QCString &type, int &pos, QCString &name, QCString &templSpec, SrcLangExt lang)
 
QCString normalizeNonTemplateArgumentsInString (const QCString &name, Definition *context, const ArgumentList *formalArgs)
 
QCString substituteTemplateArgumentsInString (const QCString &name, ArgumentList *formalArgs, ArgumentList *actualArgs)
 
QList< ArgumentList > * copyArgumentLists (const QList< ArgumentList > *srcLists)
 
QCString stripTemplateSpecifiersFromScope (const QCString &fullName, bool parentOnly, QCString *pLastScopeStripped)
 
QCString mergeScopes (const QCString &leftScope, const QCString &rightScope)
 
int getScopeFragment (const QCString &s, int p, int *l)
 
PageDefaddRelatedPage (const char *name, const QCString &ptitle, const QCString &doc, QList< SectionInfo > *, const char *fileName, int startLine, const QList< ListItemInfo > *sli, GroupDef *gd, TagInfo *tagInfo, SrcLangExt lang)
 
void addRefItem (const QList< ListItemInfo > *sli, const char *key, const char *prefix, const char *name, const char *title, const char *args, Definition *scope)
 
bool recursivelyAddGroupListToTitle (OutputList &ol, Definition *d, bool root)
 
void addGroupListToTitle (OutputList &ol, Definition *d)
 
void filterLatexString (FTextStream &t, const char *str, bool insideTabbing, bool insidePre, bool insideItem, bool keepSpaces)
 
QCString latexEscapeLabelName (const char *s, bool insideTabbing)
 
QCString latexEscapeIndexChars (const char *s, bool insideTabbing)
 
QCString latexEscapePDFString (const char *s)
 
QCString rtfFormatBmkStr (const char *name)
 
bool checkExtension (const char *fName, const char *ext)
 
QCString stripExtensionGeneral (const char *fName, const char *ext)
 
QCString stripExtension (const char *fName)
 
void replaceNamespaceAliases (QCString &scope, int i)
 
QCString stripPath (const char *s)
 
bool containsWord (const QCString &s, const QCString &word)
 
bool findAndRemoveWord (QCString &s, const QCString &word)
 
QCString stripLeadingAndTrailingEmptyLines (const QCString &s, int &docLine)
 
bool updateLanguageMapping (const QCString &extension, const QCString &language)
 
void initDefaultExtensionMapping ()
 
void addCodeOnlyMappings ()
 
SrcLangExt getLanguageFromFileName (const QCString fileName)
 
MemberDefgetMemberFromSymbol (Definition *scope, FileDef *fileScope, const char *n)
 
bool checkIfTypedef (Definition *scope, FileDef *fileScope, const char *n)
 
const char * writeUtf8Char (FTextStream &t, const char *s)
 
int nextUtf8CharPosition (const QCString &utf8Str, int len, int startPos)
 
QCString parseCommentAsText (const Definition *scope, const MemberDef *md, const QCString &doc, const QCString &fileName, int lineNr)
 
static QCString expandAliasRec (const QCString s, bool allowRecursion=FALSE)
 
static int findEndOfCommand (const char *s)
 
static QCString replaceAliasArguments (const QCString &aliasValue, const QCString &argList)
 
static QCString escapeCommas (const QCString &s)
 
int countAliasArguments (const QCString argList)
 
QCString extractAliasArgs (const QCString &args, int pos)
 
QCString resolveAliasCmd (const QCString aliasCmd)
 
QCString expandAlias (const QCString &aliasName, const QCString &aliasValue)
 
void writeTypeConstraints (OutputList &ol, Definition *d, ArgumentList *al)
 
void stackTrace ()
 
static int transcodeCharacterBuffer (const char *fileName, BufStr &srcBuf, int size, const char *inputEncoding, const char *outputEncoding)
 
bool readInputFile (const char *fileName, BufStr &inBuf, bool filter, bool isSourceCode)
 read a file name fileName and optionally filter and transcode it
 
QCString filterTitle (const QCString &title)
 
bool patternMatch (const QFileInfo &fi, const QStrList *patList)
 
QCString externalLinkTarget ()
 
QCString externalRef (const QCString &relPath, const QCString &ref, bool href)
 
void writeColoredImgData (const char *dir, ColoredImgDataItem data[])
 
QCString replaceColorMarkers (const char *str)
 
bool copyFile (const QCString &src, const QCString &dest)
 
QCString extractBlock (const QCString text, const QCString marker)
 
int lineBlock (const QCString text, const QCString marker)
 
QCString langToString (SrcLangExt lang)
 
QCString getLanguageSpecificSeparator (SrcLangExt lang, bool classScope)
 
QCString correctURL (const QCString &url, const QCString &relPath)
 
bool protectionLevelVisible (Protection prot)
 
QCString stripIndentation (const QCString &s)
 
bool fileVisibleInIndex (FileDef *fd, bool &genSourceFile)
 
void addDocCrossReference (MemberDef *src, MemberDef *dst)
 
uint getUtf8Code (const QCString &s, int idx)
 Get one unicode character as an unsigned integer from utf-8 string.
 
uint getUtf8CodeToLower (const QCString &s, int idx)
 Returns one unicode character as an unsigned integer from utf-8 string, making the character lower case if it was upper case.
 
uint getUtf8CodeToUpper (const QCString &s, int idx)
 Returns one unicode character as ian unsigned interger from utf-8 string, making the character upper case if it was lower case.
 
bool namespaceHasVisibleChild (NamespaceDef *nd, bool includeClasses)
 
bool classVisibleInIndex (ClassDef *cd)
 
QCString extractDirection (QCString &docs)
 
void convertProtectionLevel (MemberListType inListType, Protection inProt, int *outListType1, int *outListType2)
 
bool mainPageHasTitle ()
 
QCString getDotImageExtension (void)
 
bool openOutputFile (const char *outFile, QFile &f)
 
void writeExtraLatexPackages (FTextStream &t)
 

Variables

const int maxInheritanceDepth = 100000
 
static QDict< MemberDefg_resolvedTypedefs
 
static QDict< Definitiong_visitedNamespaces
 
const int MAX_STACK_SIZE = 1000
 
static const char constScope [] = { 'c', 'o', 'n', 's', 't', ':' }
 
static const char virtualScope [] = { 'v', 'i', 'r', 't', 'u', 'a', 'l', ':' }
 
static const char operatorScope [] = { 'o', 'p', 'e', 'r', 'a', 't', 'o', 'r', '?', '?', '?' }
 
static CharAroundSpace g_charAroundSpace
 
static QDict< int > g_extLookup
 
static struct Lang2ExtMap g_lang2extMap []
 
static QDict< void > aliasesProcessed
 

Macro Definition Documentation

#define ALGO_COUNT   1

Definition at line 83 of file util.cpp.

#define ALGO_CRC16   2

Definition at line 84 of file util.cpp.

#define ALGO_MD5   3

Definition at line 85 of file util.cpp.

#define ENABLE_TRACINGSUPPORT   0

Definition at line 66 of file util.cpp.

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

Referenced by replaceColorMarkers().

#define MAP_ALGO   ALGO_MD5

Definition at line 89 of file util.cpp.

#define MATCH

Definition at line 3004 of file util.cpp.

Referenced by matchArgument(), matchArgument2(), matchArguments(), and matchArguments2().

#define NOMATCH

Definition at line 3005 of file util.cpp.

Referenced by matchArgument(), matchArgument2(), matchArguments(), and matchArguments2().

#define REL_PATH_TO_ROOT   "../../"

Definition at line 91 of file util.cpp.

Referenced by relativePathToRoot().

Function Documentation

bool accessibleViaUsingClass ( const SDict< Definition > *  cl,
FileDef fileScope,
Definition item,
const QCString &  explicitScopePart = "" 
)

Definition at line 808 of file util.cpp.

References followPath().

Referenced by isAccessibleFrom().

{
//printf("accessibleViaUsingClass(%p)\n",cl);
if (cl) // see if the class was imported via a using statement
{
Definition *ucd;
bool explicitScopePartEmpty = explicitScopePart.isEmpty();
for (cli.toFirst();(ucd=cli.current());++cli)
{
//printf("Trying via used class %s\n",ucd->name().data());
Definition *sc = explicitScopePartEmpty ? ucd : followPath(ucd,fileScope,explicitScopePart);
if (sc && sc==item) return TRUE;
//printf("Try via used class done\n");
}
}
return FALSE;
}
bool accessibleViaUsingNamespace ( const NamespaceSDict nl,
FileDef fileScope,
Definition item,
const QCString &  explicitScopePart = "" 
)

Definition at line 831 of file util.cpp.

References SDict< T >::find(), followPath(), Definition::getOuterScope(), NamespaceDef::getUsedNamespaces(), SDict< NamespaceDef >::Iterator, and Definition::name().

Referenced by isAccessibleFrom(), and isAccessibleFromWithExpScope().

{
static QDict<void> visitedDict;
if (nl) // check used namespaces for the class
{
int count=0;
for (nli.toFirst();(und=nli.current());++nli,count++)
{
//printf("[Trying via used namespace %s: count=%d/%d\n",und->name().data(),
// count,nl->count());
Definition *sc = explicitScopePart.isEmpty() ? und : followPath(und,fileScope,explicitScopePart);
if (sc && item->getOuterScope()==sc)
{
//printf("] found it\n");
return TRUE;
}
QCString key=und->name();
if (und->getUsedNamespaces() && visitedDict.find(key)==0)
{
visitedDict.insert(key,(void *)0x08);
if (accessibleViaUsingNamespace(und->getUsedNamespaces(),fileScope,item,explicitScopePart))
{
//printf("] found it via recursion\n");
return TRUE;
}
visitedDict.remove(key);
}
//printf("] Try via used namespace done\n");
}
}
return FALSE;
}
void addCodeOnlyMappings ( )

Definition at line 7147 of file util.cpp.

References updateLanguageMapping().

Referenced by generateOutput().

{
updateLanguageMapping(".xml", "xml");
}
void addDocCrossReference ( MemberDef src,
MemberDef dst 
)

Definition at line 8304 of file util.cpp.

References Definition::addSourceReferencedBy(), Definition::addSourceReferences(), Config_getBool, MemberDef::hasCallerGraph(), MemberDef::hasCallGraph(), MemberDef::isEnumerate(), MemberDef::isTypedef(), MemberDef::memberDeclaration(), MemberDef::memberDefinition(), and MemberDef::showInCallGraph().

{
static bool referencedByRelation = Config_getBool(REFERENCED_BY_RELATION);
static bool referencesRelation = Config_getBool(REFERENCES_RELATION);
//printf("--> addDocCrossReference src=%s,dst=%s\n",src->name().data(),dst->name().data());
if (dst->isTypedef() || dst->isEnumerate()) return; // don't add types
if ((referencedByRelation || dst->hasCallerGraph()) &&
)
{
MemberDef *mdDef = dst->memberDefinition();
if (mdDef)
{
mdDef->addSourceReferencedBy(src);
}
MemberDef *mdDecl = dst->memberDeclaration();
if (mdDecl)
{
mdDecl->addSourceReferencedBy(src);
}
}
if ((referencesRelation || src->hasCallGraph()) &&
)
{
MemberDef *mdDef = src->memberDefinition();
if (mdDef)
{
mdDef->addSourceReferences(dst);
}
MemberDef *mdDecl = src->memberDeclaration();
if (mdDecl)
{
mdDecl->addSourceReferences(dst);
}
}
}
void addGroupListToTitle ( OutputList ol,
Definition d 
)
void addMembersToMemberGroup ( MemberList ml,
MemberGroupSDict **  ppMemberGroupSDict,
Definition context 
)

Definition at line 5953 of file util.cpp.

References MemberGroupInfo::doc, MemberGroupInfo::docFile, MemberGroupInfo::docLine, MemberDef::enumFieldList(), MemberDef::getMemberGroupId(), MemberGroupInfo::header, MemberGroup::insertMember(), MemberDef::isEnumerate(), MemberGroupInfo::m_sli, Doxygen::memGrpInfoDict, SIntDict< T >::setAutoDelete(), MemberDef::setMemberGroup(), MemberGroup::setRefItems(), and MemberList::take().

{
ASSERT(context!=0);
//printf("addMemberToMemberGroup()\n");
if (ml==0) return;
MemberDef *md;
uint index;
for (index=0;(md=mli.current());)
{
if (md->isEnumerate()) // insert enum value of this enum into groups
{
if (fmdl!=0)
{
MemberListIterator fmli(*fmdl);
MemberDef *fmd;
for (fmli.toFirst();(fmd=fmli.current());++fmli)
{
int groupId=fmd->getMemberGroupId();
if (groupId!=-1)
{
//QCString *pGrpHeader = Doxygen::memberHeaderDict[groupId];
//QCString *pDocs = Doxygen::memberDocDict[groupId];
if (info)
{
if (*ppMemberGroupSDict==0)
{
*ppMemberGroupSDict = new MemberGroupSDict;
(*ppMemberGroupSDict)->setAutoDelete(TRUE);
}
MemberGroup *mg = (*ppMemberGroupSDict)->find(groupId);
if (mg==0)
{
mg = new MemberGroup(
context,
groupId,
info->header,
info->doc,
info->docFile,
info->docLine
);
(*ppMemberGroupSDict)->append(groupId,mg);
}
mg->insertMember(fmd); // insert in member group
fmd->setMemberGroup(mg);
}
}
}
}
}
int groupId=md->getMemberGroupId();
if (groupId!=-1)
{
//QCString *pGrpHeader = Doxygen::memberHeaderDict[groupId];
//QCString *pDocs = Doxygen::memberDocDict[groupId];
if (info)
{
if (*ppMemberGroupSDict==0)
{
*ppMemberGroupSDict = new MemberGroupSDict;
(*ppMemberGroupSDict)->setAutoDelete(TRUE);
}
MemberGroup *mg = (*ppMemberGroupSDict)->find(groupId);
if (mg==0)
{
mg = new MemberGroup(
context,
groupId,
info->header,
info->doc,
info->docFile,
info->docLine
);
(*ppMemberGroupSDict)->append(groupId,mg);
}
md = ml->take(index); // remove from member list
mg->insertMember(md); // insert in member group
mg->setRefItems(info->m_sli);
md->setMemberGroup(mg);
continue;
}
}
++mli;++index;
}
}
void addRefItem ( const QList< ListItemInfo > *  sli,
const char *  key,
const char *  prefix,
const char *  name,
const char *  title,
const char *  args,
Definition scope 
)

Definition at line 6542 of file util.cpp.

References RefItem::args, Config_getBool, RefList::getRefItem(), RefList::insertIntoList(), ListItemInfo::itemId, RefItem::name, RefItem::prefix, RefItem::scope, RefItem::title, ListItemInfo::type, and Doxygen::xrefLists.

Referenced by MemberDef::addListReference(), GroupDef::addListReferences(), NamespaceDef::addListReferences(), MemberGroup::addListReferences(), FileDef::addListReferences(), ClassDef::addListReferences(), addListReferences(), and buildPageList().

{
//printf("addRefItem(sli=%p,key=%s,prefix=%s,name=%s,title=%s,args=%s)\n",sli,key,prefix,name,title,args);
if (sli && key && key[0]!='@') // check for @ to skip anonymous stuff (see bug427012)
{
QListIterator<ListItemInfo> slii(*sli);
for (slii.toFirst();(lii=slii.current());++slii)
{
RefList *refList = Doxygen::xrefLists->find(lii->type);
if (refList
&&
(
// either not a built-in list or the list is enabled
(lii->type!="todo" || Config_getBool(GENERATE_TODOLIST)) &&
(lii->type!="test" || Config_getBool(GENERATE_TESTLIST)) &&
(lii->type!="bug" || Config_getBool(GENERATE_BUGLIST)) &&
(lii->type!="deprecated" || Config_getBool(GENERATE_DEPRECATEDLIST))
)
)
{
RefItem *item = refList->getRefItem(lii->itemId);
ASSERT(item!=0);
item->prefix = prefix;
item->scope = scope;
item->name = name;
item->title = title;
item->args = args;
refList->insertIntoList(key,item);
}
}
}
}
PageDef* addRelatedPage ( const char *  name,
const QCString &  ptitle,
const QCString &  doc,
QList< SectionInfo > *  ,
const char *  fileName,
int  startLine,
const QList< ListItemInfo > *  sli,
GroupDef gd,
TagInfo tagInfo,
SrcLangExt  lang 
)

Definition at line 6455 of file util.cpp.

References GroupDef::addPage(), SDict< T >::append(), TagInfo::fileName, SectionInfo::fileName, SDict< T >::find(), GroupDef::getOutputFileBase(), PageDef::getOutputFileBase(), Definition::getReference(), Doxygen::htmlFileExtension, SectionInfo::lineNr, Definition::name(), SectionInfo::Page, Doxygen::pageSDict, Doxygen::sectionDict, Definition::setDocumentation(), PageDef::setFileName(), Definition::setLanguage(), Definition::setReference(), Definition::setRefItems(), TagInfo::tagName, PageDef::title(), and warn().

{
PageDef *pd=0;
//printf("addRelatedPage(name=%s gd=%p)\n",name,gd);
if ((pd=Doxygen::pageSDict->find(name)) && !tagInfo)
{
// append documentation block to the page.
pd->setDocumentation(doc,fileName,startLine);
//printf("Adding page docs `%s' pi=%p name=%s\n",doc.data(),pd,name);
}
else // new page
{
QCString baseName=name;
if (baseName.right(4)==".tex")
baseName=baseName.left(baseName.length()-4);
else if (baseName.right(Doxygen::htmlFileExtension.length())==Doxygen::htmlFileExtension)
baseName=baseName.left(baseName.length()-Doxygen::htmlFileExtension.length());
QCString title=ptitle.stripWhiteSpace();
pd=new PageDef(fileName,startLine,baseName,doc,title);
pd->setRefItems(sli);
pd->setLanguage(lang);
if (tagInfo)
{
pd->setReference(tagInfo->tagName);
pd->setFileName(tagInfo->fileName);
}
//printf("Appending page `%s'\n",baseName.data());
Doxygen::pageSDict->append(baseName,pd);
if (gd) gd->addPage(pd);
if (!pd->title().isEmpty())
{
//outputList->writeTitle(pi->name,pi->title);
// a page name is a label as well!
QCString file;
if (gd)
{
file=gd->getOutputFileBase();
}
else
{
file=pd->getOutputFileBase();
}
if (si)
{
if (si->lineNr != -1)
{
warn(file,-1,"multiple use of section label '%s', (first occurrence: %s, line %d)",pd->name().data(),si->fileName.data(),si->lineNr);
}
else
{
warn(file,-1,"multiple use of section label '%s', (first occurrence: %s)",pd->name().data(),si->fileName.data());
}
}
else
{
si=new SectionInfo(
file,-1,pd->name(),pd->title(),SectionInfo::Page,0,pd->getReference());
//printf("si->label=`%s' si->definition=%s si->fileName=`%s'\n",
// si->label.data(),si->definition?si->definition->name().data():"<none>",
// si->fileName.data());
//printf(" SectionInfo: sec=%p sec->fileName=%s\n",si,si->fileName.data());
//printf("Adding section key=%s si->fileName=%s\n",pageName.data(),si->fileName.data());
}
}
}
return pd;
}
QCString argListToString ( ArgumentList al,
bool  useCanonicalType,
bool  showDefVals 
)

Definition at line 2228 of file util.cpp.

References Argument::array, Argument::attrib, Argument::canType, ArgumentList::constSpecifier, Argument::defval, Argument::name, ArgumentList::pureSpecifier, removeRedundantWhiteSpace(), ArgumentList::trailingReturnType, Argument::type, and ArgumentList::volatileSpecifier.

Referenced by checkArgumentName(), checkUndocumentedParams(), findGlobalMember(), and findMember().

{
QCString result;
if (al==0) return result;
Argument *a=ali.current();
result+="(";
while (a)
{
QCString type1 = useCanonicalType && !a->canType.isEmpty() ?
a->canType : a->type;
QCString type2;
int i=type1.find(")("); // hack to deal with function pointers
if (i!=-1)
{
type2=type1.mid(i);
type1=type1.left(i);
}
if (!a->attrib.isEmpty())
{
result+=a->attrib+" ";
}
if (!a->name.isEmpty() || !a->array.isEmpty())
{
result+= type1+" "+a->name+type2+a->array;
}
else
{
result+= type1+type2;
}
if (!a->defval.isEmpty() && showDefVals)
{
result+="="+a->defval;
}
++ali;
a = ali.current();
if (a) result+=", ";
}
result+=")";
if (al->constSpecifier) result+=" const";
if (al->volatileSpecifier) result+=" volatile";
if (!al->trailingReturnType.isEmpty()) result+=" -> "+al->trailingReturnType;
if (al->pureSpecifier) result+=" =0";
return removeRedundantWhiteSpace(result);
}
bool checkExtension ( const char *  fName,
const char *  ext 
)

Definition at line 6872 of file util.cpp.

Referenced by copyLatexStyleSheet(), and writeDefaultHeaderPart1().

{
return (QCString(fName).right(QCString(ext).length())==ext);
}
bool checkIfTypedef ( Definition scope,
FileDef fileScope,
const char *  n 
)

Returns true iff the given name string appears to be a typedef in scope.

Definition at line 7246 of file util.cpp.

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

Referenced by isVarWithConstructor().

{
MemberDef *bestMatch = getMemberFromSymbol(scope,fileScope,n);
if (bestMatch && bestMatch->isTypedef())
return TRUE; // closest matching symbol is a typedef
else
return FALSE;
}
bool classHasVisibleChildren ( ClassDef cd)

Definition at line 5267 of file util.cpp.

References ClassDef::baseClasses(), Definition::getLanguage(), SrcLangExt_VHDL, and ClassDef::subClasses().

Referenced by NestingNodeContext::Private::addClasses(), writeClassTree(), and writeClassTreeForList().

{
if (cd->getLanguage()==SrcLangExt_VHDL) // reverse baseClass/subClass relation
{
if (cd->baseClasses()==0) return FALSE;
bcl=cd->baseClasses();
}
else
{
if (cd->subClasses()==0) return FALSE;
bcl=cd->subClasses();
}
for ( ; bcli.current() ; ++bcli)
{
if (bcli.current()->classDef->isVisibleInHierarchy())
{
return TRUE;
}
}
return FALSE;
}
Protection classInheritedProtectionLevel ( ClassDef cd,
ClassDef bcd,
Protection  prot,
int  level 
)

Definition at line 2639 of file util.cpp.

References ClassDef::baseClasses(), ClassDef::categoryOf(), classInheritedProtectionLevel(), err(), Definition::name(), Private, and Protected.

Referenced by classInheritedProtectionLevel().

{
if (bcd->categoryOf()) // use class that is being extended in case of
// an Objective-C category
{
bcd=bcd->categoryOf();
}
if (cd==bcd)
{
goto exit;
}
if (level==256)
{
err("Internal inconsistency: found class %s seem to have a recursive "
"inheritance relation! Please send a bug report to dimitri@stack.nl\n",cd->name().data());
}
else if (cd->baseClasses())
{
BaseClassDef *bcdi;
for (;(bcdi=bcli.current()) && prot!=Private;++bcli)
{
Protection baseProt = classInheritedProtectionLevel(bcdi->classDef,bcd,bcdi->prot,level+1);
if (baseProt==Private) prot=Private;
else if (baseProt==Protected) prot=Protected;
}
}
exit:
//printf("classInheritedProtectionLevel(%s,%s)=%d\n",cd->name().data(),bcd->name().data(),prot);
return prot;
}
bool classVisibleInIndex ( ClassDef cd)

Definition at line 8449 of file util.cpp.

References Config_getBool, ClassDef::isLinkable(), and ClassDef::isLinkableInProject().

Referenced by NestingContext::Private::addClasses(), and writeClassTree().

{
static bool allExternals = Config_getBool(ALLEXTERNALS);
return (allExternals && cd->isLinkable()) || cd->isLinkableInProject();
}
int computeQualifiedIndex ( const QCString &  name)

Definition at line 1203 of file util.cpp.

Referenced by Definition::addToMap(), getMemberFromSymbol(), and getResolvedClassRec().

{
int i = name.find('<');
return name.findRev("::",i==-1 ? name.length() : i);
}
bool containsWord ( const QCString &  s,
const QCString &  word 
)

returns TRUE iff string s contains word w

Definition at line 6924 of file util.cpp.

{
static QRegExp wordExp("[a-z_A-Z\\x80-\\xFF]+");
int p=0,i,l;
while ((i=wordExp.match(s,p,&l))!=-1)
{
if (s.mid(i,l)==word) return TRUE;
p=i+l;
}
return FALSE;
}
QCString convertCharEntitiesToUTF8 ( const QCString &  s)

Definition at line 5908 of file util.cpp.

References GrowBuf::addChar(), GrowBuf::addStr(), GrowBuf::clear(), GrowBuf::get(), HtmlEntityMapper::instance(), HtmlEntityMapper::name2sym(), and DocSymbol::Sym_Unknown.

Referenced by convertToJSString(), generateXMLForPage(), parseCommentAsText(), XmlDocVisitor::visitPre(), HtmlDocVisitor::visitPre(), and LatexDocVisitor::visitPre().

{
QCString result;
static QRegExp entityPat("&[a-zA-Z]+[0-9]*;");
if (s.length()==0) return result;
static GrowBuf growBuf;
growBuf.clear();
int p,i=0,l;
while ((p=entityPat.match(s,i,&l))!=-1)
{
if (p>i)
{
growBuf.addStr(s.mid(i,p-i));
}
QCString entity = s.mid(p,l);
const char *code=0;
if (symType!=DocSymbol::Sym_Unknown && (code=HtmlEntityMapper::instance()->utf8(symType)))
{
growBuf.addStr(code);
}
else
{
growBuf.addStr(s.mid(p,l));
}
i=p+l;
}
growBuf.addStr(s.mid(i,s.length()-i));
growBuf.addChar(0);
//printf("convertCharEntitiesToUTF8(%s)->%s\n",s.data(),growBuf.get());
return growBuf.get();
}
QCString convertNameToFile ( const char *  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 5439 of file util.cpp.

References Config_getBool, escapeCharsInString(), and Doxygen::htmlDirMap.

Referenced by buildExampleList(), ClassDef::ClassDef(), DocAnchor::DocAnchor(), DocCite::DocCite(), VhdlDocGen::findConstraintFile(), GroupDef::GroupDef(), NamespaceDef::NamespaceDef(), PageDef::PageDef(), RefList::RefList(), FileDef::setDiskName(), and NamespaceDef::setFileName().

{
if (name==0 || name[0]=='\0') return "";
static bool shortNames = Config_getBool(SHORT_NAMES);
static bool createSubdirs = Config_getBool(CREATE_SUBDIRS);
QCString result;
if (shortNames) // use short names only
{
static QDict<int> usedNames(10007);
usedNames.setAutoDelete(TRUE);
static int count=1;
int *value=usedNames.find(name);
int num;
if (value==0)
{
usedNames.insert(name,new int(count));
num = count++;
}
else
{
num = *value;
}
result.sprintf("a%05d",num);
}
else // long names
{
result=escapeCharsInString(name,allowDots,allowUnderscore);
int resultLen = result.length();
if (resultLen>=128) // prevent names that cannot be created!
{
// third algorithm based on MD5 hash
uchar md5_sig[16];
QCString sigStr(33);
MD5Buffer((const unsigned char *)result.data(),resultLen,md5_sig);
MD5SigToString(md5_sig,sigStr.rawData(),33);
result=result.left(128-32)+sigStr;
}
}
if (createSubdirs)
{
int l1Dir=0,l2Dir=0;
#if MAP_ALGO==ALGO_COUNT
// old algorithm, has the problem that after regeneration the
// output can be located in a different dir.
{
Doxygen::htmlDirMap=new QDict<int>(100003);
Doxygen::htmlDirMap->setAutoDelete(TRUE);
}
static int curDirNum=0;
int *dirNum = Doxygen::htmlDirMap->find(result);
if (dirNum==0) // new name
{
Doxygen::htmlDirMap->insert(result,new int(curDirNum));
l1Dir = (curDirNum)&0xf; // bits 0-3
l2Dir = (curDirNum>>4)&0xff; // bits 4-11
curDirNum++;
}
else // existing name
{
l1Dir = (*dirNum)&0xf; // bits 0-3
l2Dir = ((*dirNum)>>4)&0xff; // bits 4-11
}
#elif MAP_ALGO==ALGO_CRC16
// second algorithm based on CRC-16 checksum
int dirNum = qChecksum(result,result.length());
l1Dir = dirNum&0xf;
l2Dir = (dirNum>>4)&0xff;
#elif MAP_ALGO==ALGO_MD5
// third algorithm based on MD5 hash
uchar md5_sig[16];
MD5Buffer((const unsigned char *)result.data(),result.length(),md5_sig);
l1Dir = md5_sig[14]&0xf;
l2Dir = md5_sig[15];
#endif
result.prepend(QCString().sprintf("d%x/d%02x/",l1Dir,l2Dir));
}
//printf("*** convertNameToFile(%s)->%s\n",name,result.data());
return result;
}
void convertProtectionLevel ( MemberListType  inListType,
Protection  inProt,
int *  outListType1,
int *  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 8493 of file util.cpp.

References Config_getBool, MemberListType_priAttribs, MemberListType_priMethods, MemberListType_priSlots, MemberListType_priStaticAttribs, MemberListType_priStaticMethods, MemberListType_priTypes, MemberListType_proAttribs, MemberListType_proMethods, MemberListType_proSlots, MemberListType_proStaticAttribs, MemberListType_proStaticMethods, MemberListType_proTypes, MemberListType_pubAttribs, MemberListType_pubMethods, MemberListType_pubSlots, MemberListType_pubStaticAttribs, MemberListType_pubStaticMethods, MemberListType_pubTypes, Private, Protected, and Public.

Referenced by ClassDef::countInheritedDecMembers(), InheritedMemberInfoListContext::Private::findInheritedMembers(), and ClassDef::writeInheritedMemberDeclarations().

{
static bool extractPrivate = Config_getBool(EXTRACT_PRIVATE);
// default representing 1-1 mapping
*outListType1=inListType;
*outListType2=-1;
if (inProt==Public)
{
switch (inListType) // in the private section of the derived class,
// the private section of the base class should not
// be visible
{
*outListType1=-1;
*outListType2=-1;
break;
default:
break;
}
}
else if (inProt==Protected) // Protected inheritance
{
switch (inListType) // in the protected section of the derived class,
// both the public and protected members are shown
// as protected
{
*outListType1=-1;
*outListType2=-1;
break;
break;
break;
*outListType2=MemberListType_pubSlots;
break;
break;
break;
*outListType2=MemberListType_pubTypes;
break;
default:
break;
}
}
else if (inProt==Private)
{
switch (inListType) // in the private section of the derived class,
// both the public and protected members are shown
// as private
{
*outListType1=-1;
*outListType2=-1;
break;
if (extractPrivate)
{
}
else
{
*outListType1=-1;
*outListType2=-1;
}
break;
if (extractPrivate)
{
}
else
{
*outListType1=-1;
*outListType2=-1;
}
break;
if (extractPrivate)
{
*outListType1=MemberListType_pubSlots;
*outListType2=MemberListType_proSlots;
}
else
{
*outListType1=-1;
*outListType2=-1;
}
break;
if (extractPrivate)
{
}
else
{
*outListType1=-1;
*outListType2=-1;
}
break;
if (extractPrivate)
{
}
else
{
*outListType1=-1;
*outListType2=-1;
}
break;
if (extractPrivate)
{
*outListType1=MemberListType_pubTypes;
*outListType2=MemberListType_proTypes;
}
else
{
*outListType1=-1;
*outListType2=-1;
}
break;
default:
break;
}
}
//printf("convertProtectionLevel(type=%d prot=%d): %d,%d\n",
// inListType,inProt,*outListType1,*outListType2);
}
QCString convertToHtml ( const char *  s,
bool  keepEntities 
)

Converts a string to a HTML-encoded string

Definition at line 5832 of file util.cpp.

References GrowBuf::addChar(), GrowBuf::addStr(), GrowBuf::clear(), GrowBuf::get(), and isId().

Referenced by HtmlCodeGenerator::_writeCodeLink(), HtmlHelp::addContentsItem(), HtmlEscaper::escape(), FTVHelp::generateLink(), ClassContext::Private::inheritanceDiagram(), Definition::navigationPathAsString(), HtmlGenerator::startFile(), HtmlDocVisitor::startLink(), substituteHtmlKeywords(), HtmlDocVisitor::visit(), writeDirHierarchy(), writeDirTreeNode(), writeGroupTreeNode(), HtmlGenerator::writeInheritedSectionTitle(), TextGeneratorHtml::writeLink(), writeMapArea(), HtmlGenerator::writePageFooter(), NamespaceDef::writeQuickMemberLinks(), GroupDef::writeQuickMemberLinks(), FileDef::writeQuickMemberLinks(), ClassDef::writeQuickMemberLinks(), HtmlGenerator::writeSearchPage(), TextGeneratorHtml::writeString(), and Definition::writeToc().

{
static GrowBuf growBuf;
growBuf.clear();
if (s==0) return "";
const char *p=s;
char c;
while ((c=*p++))
{
switch (c)
{
case '<': growBuf.addStr("&lt;"); break;
case '>': growBuf.addStr("&gt;"); break;
case '&': if (keepEntities)
{
const char *e=p;
char ce;
while ((ce=*e++))
{
if (ce==';' || (!(isId(ce) || ce=='#'))) break;
}
if (ce==';') // found end of an entity
{
// copy entry verbatim
growBuf.addChar(c);
while (p<e) growBuf.addChar(*p++);
}
else
{
growBuf.addStr("&amp;");
}
}
else
{
growBuf.addStr("&amp;");
}
break;
case '\'': growBuf.addStr("&#39;"); break;
case '"': growBuf.addStr("&quot;"); break;
default: growBuf.addChar(c); break;
}
}
growBuf.addChar(0);
return growBuf.get();
}
QCString convertToId ( const char *  s)

Converts a string to a HTML id string

Definition at line 5771 of file util.cpp.

References GrowBuf::addChar(), GrowBuf::addStr(), GrowBuf::clear(), and GrowBuf::get().

Referenced by HtmlGenerator::endClassDiagram(), and ClassContext::Private::inheritanceDiagram().

{
static const char hex[] = "0123456789ABCDEF";
static GrowBuf growBuf;
growBuf.clear();
if (s==0) return "";
const char *p=s;
char c;
bool first=TRUE;
while ((c=*p++))
{
char encChar[4];
if ((c>='0' && c<='9') || (c>='a' && c<='z') || (c>='A' && c<='Z') || c=='-' || c==':' || c=='.')
{ // any permissive character except _
if (first && c>='0' && c<='9') growBuf.addChar('a'); // don't start with a digit
growBuf.addChar(c);
}
else
{
encChar[0]='_';
encChar[1]=hex[((unsigned char)c)>>4];
encChar[2]=hex[((unsigned char)c)&0xF];
encChar[3]=0;
growBuf.addStr(encChar);
}
first=FALSE;
}
growBuf.addChar(0);
return growBuf.get();
}
QCString convertToJSString ( const char *  s)

Definition at line 5878 of file util.cpp.

References GrowBuf::addChar(), GrowBuf::addStr(), GrowBuf::clear(), convertCharEntitiesToUTF8(), and GrowBuf::get().

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

{
static GrowBuf growBuf;
growBuf.clear();
if (s==0) return "";
const char *p=s;
char c;
while ((c=*p++))
{
switch (c)
{
case '"': growBuf.addStr("\\\""); break;
case '\\': growBuf.addStr("\\\\"); break;
default: growBuf.addChar(c); break;
}
}
growBuf.addChar(0);
return convertCharEntitiesToUTF8(growBuf.get());
}
QCString convertToLaTeX ( const QCString &  s,
bool  insideTabbing,
bool  keepSpaces 
)

Definition at line 5898 of file util.cpp.

References filterLatexString().

Referenced by LatexGenerator::endIndexSection(), LatexEscaper::escape(), LatexGenerator::startIndexSection(), and TextGeneratorLatex::writeString().

{
QGString result;
FTextStream t(&result);
filterLatexString(t,s,insideTabbing,FALSE,FALSE,keepSpaces);
return result.data();
}
QCString convertToXML ( const char *  s)

Converts a string to an XML-encoded string

Definition at line 5803 of file util.cpp.

References GrowBuf::addChar(), GrowBuf::addStr(), GrowBuf::clear(), and GrowBuf::get().

Referenced by DocSets::addContentsItem(), EclipseHelp::addContentsItem(), DocbookDocVisitor::filter(), XmlDocVisitor::filter(), generateDocbookForClass(), generateDocbookForDir(), generateDocbookForFile(), generateDocbookForGroup(), generateDocbookForMember(), generateDocbookForPage(), generateDocbookSection(), generateXMLForClass(), generateXMLForDir(), generateXMLForFile(), generateXMLForGroup(), generateXMLForMember(), generateXMLForNamespace(), generateXMLForPage(), generateXMLSection(), htmlAttribsToString(), EclipseHelp::initialize(), QhpXmlWriter::openCloseContent(), QhpXmlWriter::openPureHelper(), SymbolContext::Private::scope(), DocbookDocVisitor::visitPre(), HtmlDocVisitor::visitPre(), XmlDocVisitor::visitPre(), visitPreStart(), SearchIndexExternal::write(), Definition::writeDocAnchorsToTagFile(), DotNode::writeDocbook(), writeDocbookString(), DotDirDeps::writeGraph(), writeGraphHeader(), DotGroupCollaboration::writeGraphHeader(), writeInnerClasses(), writeInnerDirs(), writeInnerFiles(), writeInnerGroups(), writeInnerNamespaces(), writeInnerPages(), writeJavascriptSearchIndex(), writeListOfAllMembers(), writeMapArea(), writeMemberReference(), NamespaceDef::writeTagFile(), PageDef::writeTagFile(), GroupDef::writeTagFile(), DirDef::writeTagFile(), VhdlDocGen::writeTagFile(), FileDef::writeTagFile(), MemberDef::writeTagFile(), ClassDef::writeTagFile(), DocSets::writeToken(), DotNode::writeXML(), writeXMLLink(), and writeXMLString().

{
static GrowBuf growBuf;
growBuf.clear();
if (s==0) return "";
const char *p=s;
char c;
while ((c=*p++))
{
switch (c)
{
case '<': growBuf.addStr("&lt;"); break;
case '>': growBuf.addStr("&gt;"); break;
case '&': growBuf.addStr("&amp;"); break;
case '\'': growBuf.addStr("&apos;"); break;
case '"': growBuf.addStr("&quot;"); break;
case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8:
case 11: case 12: case 13: case 14: case 15: case 16: case 17: case 18:
case 19: case 20: case 21: case 22: case 23: case 24: case 25: case 26:
case 27: case 28: case 29: case 30: case 31:
break; // skip invalid XML characters (see http://www.w3.org/TR/2000/REC-xml-20001006#NT-Char)
default: growBuf.addChar(c); break;
}
}
growBuf.addChar(0);
return growBuf.get();
}
QList<ArgumentList>* copyArgumentLists ( const QList< ArgumentList > *  srcLists)

Makes a deep copy of the list of argument lists srcLists. Will allocate memory, that is owned by the caller.

Definition at line 6291 of file util.cpp.

References ArgumentList::deepCopy().

Referenced by Entry::Entry(), and MemberDef::setDefinitionTemplateParameterLists().

{
ASSERT(srcLists!=0);
QList<ArgumentList> *dstLists = new QList<ArgumentList>;
dstLists->setAutoDelete(TRUE);
QListIterator<ArgumentList> sli(*srcLists);
for (;(sl=sli.current());++sli)
{
dstLists->append(sl->deepCopy());
}
return dstLists;
}
bool copyFile ( const QCString &  src,
const QCString &  dest 
)

Copies the contents of file with name src to the newly created file with name dest. Returns TRUE if successful.

Definition at line 8057 of file util.cpp.

References err().

Referenced by copyExtraFiles(), copyLatexStyleSheet(), copyLogo(), copyStyleSheet(), and CiteDict::generatePage().

{
QFile sf(src);
if (sf.open(IO_ReadOnly))
{
QFileInfo fi(src);
QFile df(dest);
if (df.open(IO_WriteOnly))
{
char *buffer = new char[fi.size()];
sf.readBlock(buffer,fi.size());
df.writeBlock(buffer,fi.size());
df.flush();
delete[] buffer;
}
else
{
err("could not write to file %s\n",dest.data());
return FALSE;
}
}
else
{
err("could not open user specified file %s\n",src.data());
return FALSE;
}
return TRUE;
}
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 8199 of file util.cpp.

Referenced by startQuickIndexItem(), HtmlDocVisitor::visitPre(), and writeIndexHierarchyEntries().

{
QCString result = url;
if (!relPath.isEmpty() &&
url.left(5)!="http:" && url.left(6)!="https:" &&
url.left(4)!="ftp:" && url.left(5)!="file:")
{
result.prepend(relPath);
}
return result;
}
int countAliasArguments ( const QCString  argList)

Definition at line 7604 of file util.cpp.

References findEndOfCommand().

Referenced by expandAliasRec().

{
int count=1;
int l = argList.length();
int i;
for (i=0;i<l;i++)
{
char c = argList.at(i);
if (c==',' && (i==0 || argList.at(i-1)!='\\')) count++;
else if (c=='@' || c=='\\')
{
// check if this is the start of another aliased command (see bug704172)
i+=findEndOfCommand(argList.data()+i+1);
}
}
//printf("countAliasArguments=%d\n",count);
return count;
}
void createSubDirs ( QDir &  d)

Definition at line 5544 of file util.cpp.

References Config_getBool.

Referenced by generateDocbook(), generateOutputViaTemplate(), generateXML(), RTFGenerator::init(), ManGenerator::init(), LatexGenerator::init(), HtmlGenerator::init(), NamespaceDef::writeQuickMemberLinks(), GroupDef::writeQuickMemberLinks(), FileDef::writeQuickMemberLinks(), and ClassDef::writeQuickMemberLinks().

{
if (Config_getBool(CREATE_SUBDIRS))
{
// create 4096 subdirectories
int l1,l2;
for (l1=0;l1<16;l1++)
{
d.mkdir(QCString().sprintf("d%x",l1));
for (l2=0;l2<256;l2++)
{
d.mkdir(QCString().sprintf("d%x/d%02x",l1,l2));
}
}
}
}
QCString dateToString ( bool  includeTime)

Definition at line 2556 of file util.cpp.

References portable_getenv(), theTranslator, Translator::trDateTime(), and warn_uncond().

Referenced by DoxygenContext::Private::date(), RTFGenerator::endIndexSection(), ManGenerator::endTitleHead(), substituteHtmlKeywords(), substituteKeywords(), writeDefaultHeaderPart1(), writeDefaultHeaderPart3(), and HtmlGenerator::writeLogoAsString().

{
QDateTime current = QDateTime::currentDateTime();
QCString sourceDateEpoch = portable_getenv("SOURCE_DATE_EPOCH");
if (!sourceDateEpoch.isEmpty())
{
bool ok;
uint64 epoch = sourceDateEpoch.toUInt64(&ok);
if (!ok)
{
static bool warnedOnce=FALSE;
if (!warnedOnce)
{
warn_uncond("Environment variable SOURCE_DATE_EPOCH does not contain a valid number; value is '%s'\n",
sourceDateEpoch.data());
warnedOnce=TRUE;
}
}
else if (epoch>UINT_MAX)
{
static bool warnedOnce=FALSE;
if (!warnedOnce)
{
warn_uncond("Environment variable SOURCE_DATA_EPOCH must have a value smaller than or equal to %llu; actual value %llu\n",UINT_MAX,epoch);
warnedOnce=TRUE;
}
}
else // all ok, replace current time with epoch value
{
current.setTimeUtc_t((ulong)epoch); // TODO: add support for 64bit epoch value
}
}
return theTranslator->trDateTime(current.date().year(),
current.date().month(),
current.date().day(),
current.date().dayOfWeek(),
current.time().hour(),
current.time().minute(),
current.time().second(),
includeTime);
}
static Definition* endOfPathIsUsedClass ( SDict< Definition > *  cl,
const QCString &  localName 
)
static

Definition at line 730 of file util.cpp.

References Definition::localName().

Referenced by followPath().

{
if (cl)
{
for (cli.toFirst();(cd=cli.current());++cli)
{
if (cd->localName()==localName)
{
return cd;
}
}
}
return 0;
}
QCString escapeCharsInString ( const char *  name,
bool  allowDots,
bool  allowUnderscore 
)

Definition at line 5327 of file util.cpp.

References GrowBuf::addChar(), GrowBuf::addStr(), GrowBuf::clear(), Config_getBool, and GrowBuf::get().

Referenced by convertNameToFile(), DotGfxHierarchyTable::createGraph(), PageDef::writeDocumentation(), DotClassGraph::writeGraph(), DotInclDepGraph::writeGraph(), DotDirDeps::writeGraph(), and DotGroupCollaboration::writeGraph().

{
static bool caseSenseNames = Config_getBool(CASE_SENSE_NAMES);
static bool allowUnicodeNames = Config_getBool(ALLOW_UNICODE_NAMES);
static GrowBuf growBuf;
growBuf.clear();
char c;
const char *p=name;
while ((c=*p++)!=0)
{
switch(c)
{
case '_': if (allowUnderscore) growBuf.addChar('_'); else growBuf.addStr("__"); break;
case '-': growBuf.addChar('-'); break;
case ':': growBuf.addStr("_1"); break;
case '/': growBuf.addStr("_2"); break;
case '<': growBuf.addStr("_3"); break;
case '>': growBuf.addStr("_4"); break;
case '*': growBuf.addStr("_5"); break;
case '&': growBuf.addStr("_6"); break;
case '|': growBuf.addStr("_7"); break;
case '.': if (allowDots) growBuf.addChar('.'); else growBuf.addStr("_8"); break;
case '!': growBuf.addStr("_9"); break;
case ',': growBuf.addStr("_00"); break;
case ' ': growBuf.addStr("_01"); break;
case '{': growBuf.addStr("_02"); break;
case '}': growBuf.addStr("_03"); break;
case '?': growBuf.addStr("_04"); break;
case '^': growBuf.addStr("_05"); break;
case '%': growBuf.addStr("_06"); break;
case '(': growBuf.addStr("_07"); break;
case ')': growBuf.addStr("_08"); break;
case '+': growBuf.addStr("_09"); break;
case '=': growBuf.addStr("_0A"); break;
case '$': growBuf.addStr("_0B"); break;
case '\\': growBuf.addStr("_0C"); break;
case '@': growBuf.addStr("_0D"); break;
default:
if (c<0)
{
char ids[5];
const unsigned char uc = (unsigned char)c;
bool doEscape = TRUE;
if (allowUnicodeNames && uc <= 0xf7)
{
const char* pt = p;
ids[ 0 ] = c;
int l = 0;
if ((uc&0xE0)==0xC0)
{
l=2; // 11xx.xxxx: >=2 byte character
}
if ((uc&0xF0)==0xE0)
{
l=3; // 111x.xxxx: >=3 byte character
}
if ((uc&0xF8)==0xF0)
{
l=4; // 1111.xxxx: >=4 byte character
}
doEscape = l==0;
for (int m=1; m<l && !doEscape; ++m)
{
unsigned char ct = (unsigned char)*pt;
if (ct==0 || (ct&0xC0)!=0x80) // invalid unicode character
{
doEscape=TRUE;
}
else
{
ids[ m ] = *pt++;
}
}
if ( !doEscape ) // got a valid unicode character
{
ids[ l ] = 0;
growBuf.addStr( ids );
p += l - 1;
}
}
if (doEscape) // not a valid unicode char or escaping needed
{
static char map[] = "0123456789ABCDEF";
unsigned char id = (unsigned char)c;
ids[0]='_';
ids[1]='x';
ids[2]=map[id>>4];
ids[3]=map[id&0xF];
ids[4]=0;
growBuf.addStr(ids);
}
}
else if (caseSenseNames || !isupper(c))
{
growBuf.addChar(c);
}
else
{
growBuf.addChar('_');
growBuf.addChar(tolower(c));
}
break;
}
}
growBuf.addChar(0);
return growBuf.get();
}
static QCString escapeCommas ( const QCString &  s)
static

Definition at line 7519 of file util.cpp.

Referenced by expandAliasRec().

{
QGString result;
const char *p = s.data();
char c,pc=0;
while ((c=*p++))
{
if (c==',' && pc!='\\')
{
result+="\\,";
}
else
{
result+=c;
}
pc=c;
}
result+='\0';
//printf("escapeCommas: '%s'->'%s'\n",s.data(),result.data());
return result.data();
}
QCString expandAlias ( const QCString &  aliasName,
const QCString &  aliasValue 
)

Definition at line 7663 of file util.cpp.

References expandAliasRec().

Referenced by expandAliases().

{
QCString result;
// avoid expanding this command recursively
aliasesProcessed.insert(aliasName,(void *)0x8);
// expand embedded commands
//printf("Expanding: '%s'->'%s'\n",aliasName.data(),aliasValue.data());
result = expandAliasRec(aliasValue);
//printf("Expanding result: '%s'->'%s'\n",aliasName.data(),result.data());
return result;
}
static QCString expandAliasRec ( const QCString  s,
bool  allowRecursion = FALSE 
)
static

Definition at line 7541 of file util.cpp.

References Doxygen::aliasDict, countAliasArguments(), escapeCommas(), extractAliasArgs(), and replaceAliasArguments().

Referenced by expandAlias(), replaceAliasArguments(), and resolveAliasCmd().

{
QCString result;
static QRegExp cmdPat("[\\\\@][a-z_A-Z][a-z_A-Z0-9]*");
QCString value=s;
int i,p=0,l;
while ((i=cmdPat.match(value,p,&l))!=-1)
{
result+=value.mid(p,i-p);
QCString args = extractAliasArgs(value,i+l);
bool hasArgs = !args.isEmpty(); // found directly after command
int argsLen = args.length();
QCString cmd = value.mid(i+1,l-1);
QCString cmdNoArgs = cmd;
int numArgs=0;
if (hasArgs)
{
numArgs = countAliasArguments(args);
cmd += QCString().sprintf("{%d}",numArgs); // alias name + {n}
}
QCString *aliasText=Doxygen::aliasDict.find(cmd);
if (numArgs>1 && aliasText==0)
{ // in case there is no command with numArgs parameters, but there is a command with 1 parameter,
// we also accept all text as the argument of that command (so you don't have to escape commas)
aliasText=Doxygen::aliasDict.find(cmdNoArgs+"{1}");
if (aliasText)
{
cmd = cmdNoArgs+"{1}";
args = escapeCommas(args); // escape , so that everything is seen as one argument
}
}
//printf("Found command s='%s' cmd='%s' numArgs=%d args='%s' aliasText=%s\n",
// s.data(),cmd.data(),numArgs,args.data(),aliasText?aliasText->data():"<none>");
if ((allowRecursion || aliasesProcessed.find(cmd)==0) && aliasText) // expand the alias
{
//printf("is an alias!\n");
if (!allowRecursion) aliasesProcessed.insert(cmd,(void *)0x8);
QCString val = *aliasText;
if (hasArgs)
{
val = replaceAliasArguments(val,args);
//printf("replace '%s'->'%s' args='%s'\n",
// aliasText->data(),val.data(),args.data());
}
result+=expandAliasRec(val);
if (!allowRecursion) aliasesProcessed.remove(cmd);
p=i+l;
if (hasArgs) p+=argsLen+2;
}
else // command is not an alias
{
//printf("not an alias!\n");
result+=value.mid(i,l);
p=i+l;
}
}
result+=value.right(value.length()-p);
//printf("expandAliases '%s'->'%s'\n",s.data(),result.data());
return result;
}
QCString externalLinkTarget ( )

Definition at line 7941 of file util.cpp.

References Config_getBool.

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

{
static bool extLinksInWindow = Config_getBool(EXT_LINKS_IN_WINDOW);
if (extLinksInWindow) return "target=\"_blank\" "; else return "";
}
QCString externalRef ( const QCString &  relPath,
const QCString &  ref,
bool  href 
)

Definition at line 7947 of file util.cpp.

References Doxygen::tagDestinationDict.

Referenced by HtmlCodeGenerator::_writeCodeLink(), convertMapFile(), generateJSLink(), FTVHelp::generateLink(), SymbolContext::Private::relPath(), replaceRef(), HtmlGenerator::startIndexItem(), HtmlDocVisitor::startLink(), HtmlGenerator::writeInheritedSectionTitle(), writeJavascriptSearchIndex(), TextGeneratorHtml::writeLink(), writeMapArea(), HtmlGenerator::writeObjectLink(), and HtmlCodeGenerator::writeTooltip().

{
QCString result;
if (!ref.isEmpty())
{
QCString *dest = Doxygen::tagDestinationDict[ref];
if (dest)
{
result = *dest;
int l = result.length();
if (!relPath.isEmpty() && l>0 && result.at(0)=='.')
{ // relative path -> prepend relPath.
result.prepend(relPath);
l+=relPath.length();
}
if (!href){
result.prepend("doxygen=\""+ref+":");
l+=10+ref.length();
}
if (l>0 && result.at(l-1)!='/') result+='/';
if (!href) result.append("\" ");
}
}
else
{
result = relPath;
}
return result;
}
QCString extractAliasArgs ( const QCString &  args,
int  pos 
)

Definition at line 7623 of file util.cpp.

Referenced by expandAliasRec(), and findEndOfCommand().

{
int i;
int bc=0;
char prevChar=0;
if (args.at(pos)=='{') // alias has argument
{
for (i=pos;i<(int)args.length();i++)
{
if (prevChar!='\\')
{
if (args.at(i)=='{') bc++;
if (args.at(i)=='}') bc--;
prevChar=args.at(i);
}
else
{
prevChar=0;
}
if (bc==0)
{
//printf("extractAliasArgs('%s')->'%s'\n",args.data(),args.mid(pos+1,i-pos-1).data());
return args.mid(pos+1,i-pos-1);
}
}
}
return "";
}
QCString extractBlock ( const QCString  text,
const QCString  marker 
)

Returns the section of text, in between a pair of markers. Full lines are returned, excluding the lines on which the markers appear.

See Also
routine lineBlock

Definition at line 8090 of file util.cpp.

Referenced by DocPara::handleInclude(), DocbookDocVisitor::visit(), ManDocVisitor::visit(), RTFDocVisitor::visit(), XmlDocVisitor::visit(), HtmlDocVisitor::visit(), and LatexDocVisitor::visit().

{
QCString result;
int p=0,i;
bool found=FALSE;
// find the character positions of the markers
int m1 = text.find(marker);
if (m1==-1) return result;
int m2 = text.find(marker,m1+marker.length());
if (m2==-1) return result;
// find start and end line positions for the markers
int l1=-1,l2=-1;
while (!found && (i=text.find('\n',p))!=-1)
{
found = (p<=m1 && m1<i); // found the line with the start marker
p=i+1;
}
l1=p;
int lp=i;
if (found)
{
while ((i=text.find('\n',p))!=-1)
{
if (p<=m2 && m2<i) // found the line with the end marker
{
l2=p;
break;
}
p=i+1;
lp=i;
}
}
if (l2==-1) // marker at last line without newline (see bug706874)
{
l2=lp;
}
//printf("text=[%s]\n",text.mid(l1,l2-l1).data());
return l2>l1 ? text.mid(l1,l2-l1) : QCString();
}
static QCString extractCanonicalArgType ( Definition d,
FileDef fs,
const Argument arg 
)
static

Definition at line 3648 of file util.cpp.

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

Referenced by matchArgument2().

{
QCString type = arg->type.stripWhiteSpace();
QCString name = arg->name;
//printf("----- extractCanonicalArgType(type=%s,name=%s)\n",type.data(),name.data());
if ((type=="const" || type=="volatile") && !name.isEmpty())
{ // name is part of type => correct
type+=" ";
type+=name;
}
if (name=="const" || name=="volatile")
{ // name is part of type => correct
if (!type.isEmpty()) type+=" ";
type+=name;
}
if (!arg->array.isEmpty())
{
type+=arg->array;
}
return extractCanonicalType(d,fs,type);
}
static QCString extractCanonicalType ( Definition d,
FileDef fs,
QCString  type 
)
static

Definition at line 3578 of file util.cpp.

References extractClassNameFromType(), getCanonicalTypeForIdentifier(), removeRedundantWhiteSpace(), and stripIrrelevantConstVolatile().

Referenced by extractCanonicalArgType(), and getCanonicalTemplateSpec().

{
type = type.stripWhiteSpace();
// strip const and volatile keywords that are not relevant for the type
// strip leading keywords
type.stripPrefix("class ");
type.stripPrefix("struct ");
type.stripPrefix("union ");
type.stripPrefix("enum ");
type.stripPrefix("typename ");
//printf("extractCanonicalType(type=%s) start: def=%s file=%s\n",type.data(),
// d ? d->name().data() : "<null>",fs ? fs->name().data() : "<null>");
//static QRegExp id("[a-z_A-Z\\x80-\\xFF][:a-z_A-Z0-9\\x80-\\xFF]*");
QCString canType;
QCString templSpec,word;
int i,p=0,pp=0;
while ((i=extractClassNameFromType(type,p,word,templSpec))!=-1)
// foreach identifier in the type
{
//printf(" i=%d p=%d\n",i,p);
if (i>pp) canType += type.mid(pp,i-pp);
QCString ct = getCanonicalTypeForIdentifier(d,fs,word,&templSpec);
// in case the ct is empty it means that "word" represents scope "d"
// and this does not need to be added to the canonical
// type (it is redundant), so/ we skip it. This solves problem 589616.
if (ct.isEmpty() && type.mid(p,2)=="::")
{
p+=2;
}
else
{
canType += ct;
}
//printf(" word=%s templSpec=%s canType=%s ct=%s\n",
// word.data(),templSpec.data(),canType.data(),ct.data());
if (!templSpec.isEmpty()) // if we didn't use up the templSpec already
// (i.e. type is not a template specialization)
// then resolve any identifiers inside.
{
static QRegExp re("[a-z_A-Z\\x80-\\xFF][a-z_A-Z0-9\\x80-\\xFF]*");
int tp=0,tl,ti;
// for each identifier template specifier
//printf("adding resolved %s to %s\n",templSpec.data(),canType.data());
while ((ti=re.match(templSpec,tp,&tl))!=-1)
{
canType += templSpec.mid(tp,ti-tp);
canType += getCanonicalTypeForIdentifier(d,fs,templSpec.mid(ti,tl),0);
tp=ti+tl;
}
canType+=templSpec.right(templSpec.length()-tp);
}
pp=p;
}
canType += type.right(type.length()-pp);
//printf("extractCanonicalType = '%s'->'%s'\n",type.data(),canType.data());
return removeRedundantWhiteSpace(canType);
}
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 6049 of file util.cpp.

References SrcLangExt_Fortran.

Referenced by extractCanonicalType(), and findUsedClassesForClass().

{
static const QRegExp re_norm("[a-z_A-Z\\x80-\\xFF][a-z_A-Z0-9:\\x80-\\xFF]*");
static const QRegExp re_ftn("[a-z_A-Z\\x80-\\xFF][()=_a-z_A-Z0-9:\\x80-\\xFF]*");
QRegExp re;
name.resize(0);
templSpec.resize(0);
int i,l;
int typeLen=type.length();
if (typeLen>0)
{
if (lang == SrcLangExt_Fortran)
{
if (type.at(pos)==',') return -1;
if (type.left(4).lower()=="type")
{
re = re_norm;
}
else
{
re = re_ftn;
}
}
else
{
re = re_norm;
}
if ((i=re.match(type,pos,&l))!=-1) // for each class name in the type
{
int ts=i+l;
int te=ts;
int tl=0;
while (type.at(ts)==' ' && ts<typeLen) ts++,tl++; // skip any whitespace
if (type.at(ts)=='<') // assume template instance
{
// locate end of template
te=ts+1;
int brCount=1;
while (te<typeLen && brCount!=0)
{
if (type.at(te)=='<')
{
if (te<typeLen-1 && type.at(te+1)=='<') te++; else brCount++;
}
if (type.at(te)=='>')
{
if (te<typeLen-1 && type.at(te+1)=='>') te++; else brCount--;
}
te++;
}
}
name = type.mid(i,l);
if (te>ts)
{
templSpec = type.mid(ts,te-ts),tl+=te-ts;
pos=i+l+tl;
}
else // no template part
{
pos=i+l;
}
//printf("extractClassNameFromType([in] type=%s,[out] pos=%d,[out] name=%s,[out] templ=%s)=TRUE\n",
// type.data(),pos,name.data(),templSpec.data());
return i;
}
}
pos = typeLen;
//printf("extractClassNameFromType([in] type=%s,[out] pos=%d,[out] name=%s,[out] templ=%s)=FALSE\n",
// type.data(),pos,name.data(),templSpec.data());
return -1;
}
QCString extractDirection ( QCString &  docs)

Definition at line 8457 of file util.cpp.

Referenced by MemberContext::Private::paramDocs(), and MemberDef::writeDocumentation().

{
QRegExp re("\\[[^\\]]+\\]"); // [...]
int l=0;
if (re.match(docs,0,&l)==0)
{
int inPos = docs.find("in", 1,FALSE);
int outPos = docs.find("out",1,FALSE);
bool input = inPos!=-1 && inPos<l;
bool output = outPos!=-1 && outPos<l;
if (input || output) // in,out attributes
{
docs = docs.mid(l); // strip attributes
if (input && output) return "[in,out]";
else if (input) return "[in]";
else if (output) return "[out]";
}
}
return QCString();
}
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 5564 of file util.cpp.

References getClass(), getResolvedNamespace(), and Definition::name().

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

{
int i,p;
QCString clName=scopeName;
NamespaceDef *nd = 0;
if (!clName.isEmpty() && (nd=getResolvedNamespace(clName)) && getClass(clName)==0)
{ // the whole name is a namespace (and not a class)
namespaceName=nd->name().copy();
className.resize(0);
goto done;
}
p=clName.length()-2;
while (p>=0 && (i=clName.findRev("::",p))!=-1)
// see if the first part is a namespace (and not a class)
{
//printf("Trying %s\n",clName.left(i).data());
if (i>0 && (nd=getResolvedNamespace(clName.left(i))) && getClass(clName.left(i))==0)
{
//printf("found!\n");
namespaceName=nd->name().copy();
className=clName.right(clName.length()-i-2);
goto done;
}
p=i-2; // try a smaller piece of the scope
}
//printf("not found!\n");
// not found, so we just have to guess.
className=scopeName.copy();
namespaceName.resize(0);
done:
if (className.isEmpty() && !namespaceName.isEmpty() && !allowEmptyClass)
{
// class and namespace with the same name, correct to return the class.
className=namespaceName.copy();
namespaceName.resize(0);
}
//printf("extractNamespace `%s' => `%s|%s'\n",scopeName.data(),
// className.data(),namespaceName.data());
if (/*className.right(2)=="-g" ||*/ className.right(2)=="-p")
{
className = className.left(className.length()-2);
}
return;
}
QCString fileToString ( const char *  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 2501 of file util.cpp.

References err(), filterCRLF(), and readInputFile().

Referenced by DoxygenContext::Private::Cachable::Cachable(), LatexGenerator::endIndexSection(), FormulaList::generateBitmaps(), HtmlGenerator::init(), parseCode(), FileDef::parseSource(), readTextFileByName(), LatexGenerator::startIndexSection(), writeDocbookCodeBlock(), FileDef::writeSource(), HtmlGenerator::writeStyleInfo(), and writeXMLCodeBlock().

{
if (name==0 || name[0]==0) return 0;
QFile f;
bool fileOpened=FALSE;
if (name[0]=='-' && name[1]==0) // read from stdin
{
fileOpened=f.open(IO_ReadOnly,stdin);
if (fileOpened)
{
const int bSize=4096;
QCString contents(bSize);
int totalSize=0;
int size;
while ((size=f.readBlock(contents.rawData()+totalSize,bSize))==bSize)
{
totalSize+=bSize;
contents.resize(totalSize+bSize);
}
totalSize = filterCRLF(contents.rawData(),totalSize+size)+2;
contents.resize(totalSize);
contents.at(totalSize-2)='\n'; // to help the scanner
contents.at(totalSize-1)='\0';
return contents;
}
}
else // read from file
{
QFileInfo fi(name);
if (!fi.exists() || !fi.isFile())
{
err("file `%s' not found\n",name);
return "";
}
BufStr buf(fi.size());
fileOpened=readInputFile(name,buf,filter,isSourceCode);
if (fileOpened)
{
int s = buf.size();
if (s>1 && buf.at(s-2)!='\n')
{
buf.at(s-1)='\n';
buf.addChar(0);
}
return buf.data();
}
}
if (!fileOpened)
{
err("cannot open file `%s' for reading\n",name);
}
return "";
}
bool fileVisibleInIndex ( FileDef fd,
bool &  genSourceFile 
)

Definition at line 8292 of file util.cpp.

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

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

{
static bool allExternals = Config_getBool(ALLEXTERNALS);
bool isDocFile = fd->isDocumentationFile();
genSourceFile = !isDocFile && fd->generateSourceFile();
return ( ((allExternals && fd->isLinkable()) ||
) &&
!isDocFile
);
}
int filterCRLF ( char *  buf,
int  len 
)

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

Definition at line 2361 of file util.cpp.

Referenced by fileToString(), and readInputFile().

{
int src = 0; // source index
int dest = 0; // destination index
char c; // current character
while (src<len)
{
c = buf[src++]; // Remember the processed character.
if (c == '\r') // CR to be solved (MAC, DOS)
{
c = '\n'; // each CR to LF
if (src<len && buf[src] == '\n')
++src; // skip LF just after CR (DOS)
}
else if ( c == '\0' && src<len-1) // filter out internal \0 characters, as it will confuse the parser
{
c = ' '; // turn into a space
}
buf[dest++] = c; // copy the (modified) character to dest
}
return dest; // length of the valid part of the buf
}
void filterLatexString ( FTextStream t,
const char *  str,
bool  insideTabbing,
bool  insidePre,
bool  insideItem,
bool  keepSpaces 
)

Definition at line 6619 of file util.cpp.

References Config_getBool, HtmlEntityMapper::instance(), isId(), HtmlEntityMapper::latex(), HtmlEntityMapper::name2sym(), and DocSymbol::Sym_Unknown.

Referenced by LatexCodeGenerator::codify(), convertToLaTeX(), LatexGenerator::docify(), LatexDocVisitor::filter(), latexEscapeIndexChars(), latexEscapeLabelName(), writeDefaultHeaderPart1(), and TextGeneratorLatex::writeLink().

{
if (str==0) return;
//if (strlen(str)<2) stackTrace();
const unsigned char *p=(const unsigned char *)str;
const unsigned char *q;
int cnt;
unsigned char c;
unsigned char pc='\0';
while (*p)
{
c=*p++;
if (insidePre)
{
switch(c)
{
case '\\': t << "\\(\\backslash\\)"; break;
case '{': t << "\\{"; break;
case '}': t << "\\}"; break;
case '_': t << "\\_"; break;
case ' ': if (keepSpaces) t << "~"; else t << ' ';
break;
default:
t << (char)c;
break;
}
}
else
{
switch(c)
{
case '#': t << "\\#"; break;
case '$': t << "\\$"; break;
case '%': t << "\\%"; break;
case '^': t << "$^\\wedge$"; break;
case '&': // possibility to have a special symbol
q = p;
cnt = 2; // we have to count & and ; as well
while ((*q >= 'a' && *q <= 'z') || (*q >= 'A' && *q <= 'Z') || (*q >= '0' && *q <= '9'))
{
cnt++;
q++;
}
if (*q == ';')
{
--p; // we need & as well
DocSymbol::SymType res = HtmlEntityMapper::instance()->name2sym(QCString((char *)p).left(cnt));
{
p++;
t << "\\&";
}
else
{
q++;
p = q;
}
}
else
{
t << "\\&";
}
break;
case '*': t << "$\\ast$"; break;
case '_': if (!insideTabbing) t << "\\+";
t << "\\_";
if (!insideTabbing) t << "\\+";
break;
case '{': t << "\\{"; break;
case '}': t << "\\}"; break;
case '<': t << "$<$"; break;
case '>': t << "$>$"; break;
case '|': t << "$\\vert$"; break;
case '~': t << "$\\sim$"; break;
case '[': if (Config_getBool(PDF_HYPERLINKS) || insideItem)
t << "\\mbox{[}";
else
t << "[";
break;
case ']': if (pc=='[') t << "$\\,$";
if (Config_getBool(PDF_HYPERLINKS) || insideItem)
t << "\\mbox{]}";
else
t << "]";
break;
case '-': t << "-\\/";
break;
case '\\': t << "\\textbackslash{}";
break;
case '"': t << "\\char`\\\"{}";
break;
case '\'': t << "\\textquotesingle{}";
break;
case ' ': if (keepSpaces) { if (insideTabbing) t << "\\>"; else t << '~'; } else t << ' ';
break;
default:
//if (!insideTabbing && forceBreaks && c!=' ' && *p!=' ')
if (!insideTabbing &&
((c>='A' && c<='Z' && pc!=' ' && pc!='\0' && *p) || (c==':' && pc!=':') || (pc=='.' && isId(c)))
)
{
t << "\\+";
}
t << (char)c;
}
}
pc = c;
}
}
QCString filterTitle ( const QCString &  title)

Definition at line 7856 of file util.cpp.

Referenced by PerlModGenerator::generatePerlModForPage(), generateXMLForPage(), mainPageHasOwnTitle(), HtmlGenerator::startFile(), PageDef::writeDocumentation(), writeExampleIndex(), writeIndex(), and writePages().

{
QCString tf;
static QRegExp re("%[A-Z_a-z]");
int p=0,i,l;
while ((i=re.match(title,p,&l))!=-1)
{
tf+=title.mid(p,i-p);
tf+=title.mid(i+1,l-1); // skip %
p=i+l;
}
tf+=title.right(title.length()-p);
return tf;
}
bool findAndRemoveWord ( QCString &  s,
const QCString &  word 
)

Definition at line 6936 of file util.cpp.

Referenced by isVarWithConstructor().

{
static QRegExp wordExp("[a-z_A-Z\\x80-\\xFF]+");
int p=0,i,l;
while ((i=wordExp.match(s,p,&l))!=-1)
{
if (s.mid(i,l)==word)
{
if (i>0 && isspace((uchar)s.at(i-1)))
i--,l++;
else if (i+l<(int)s.length() && isspace(s.at(i+l)))
l++;
s = s.left(i)+s.mid(i+l); // remove word + spacing
return TRUE;
}
p=i+l;
}
return FALSE;
}
static int findEndOfCommand ( const char *  s)
static

For a string s that starts with a command name, returns the character offset within that string representing the first character after the command. For an alias with argument, this is the offset to the character just after the argument list.

Examples:

  • s=="a b" returns 1
  • s=="a{2,3} b" returns 6 = s=="#" returns 0

Definition at line 7400 of file util.cpp.

References extractAliasArgs(), and isId().

Referenced by countAliasArguments(), and replaceAliasArguments().

{
const char *p = s;
char c;
int i=0;
if (p)
{
while ((c=*p) && isId(c)) p++;
if (c=='{')
{
QCString args = extractAliasArgs(p,0);
i+=args.length();
}
i+=p-s;
}
return i;
}
FileDef* findFileDef ( const FileNameDict fnDict,
const char *  n,
bool &  ambig 
)

Definition at line 5048 of file util.cpp.

References FindFileCacheElem::fileDef, g_findFileDefCache(), FileDef::getPath(), FindFileCacheElem::isAmbig, and stripFromIncludePath().

Referenced by addIncludeFile(), buildFileList(), findAndCopyImage(), findDocsForMemberOrCompound(), format_warn(), generateFileRef(), generateFileSources(), handleLinkedWord(), DocDotFile::parse(), DocMscFile::parse(), DocDiaFile::parse(), parseFiles(), processLink(), readTextFileByName(), resolveLink(), resolveRef(), and DocbookDocVisitor::visitPost().

{
ambig=FALSE;
if (n==0) return 0;
const int maxAddrSize = 20;
char addr[maxAddrSize];
qsnprintf(addr,maxAddrSize,"%p:",fnDict);
QCString key = addr;
key+=n;
g_findFileDefCache.setAutoDelete(TRUE);
FindFileCacheElem *cachedResult = g_findFileDefCache.find(key);
//printf("key=%s cachedResult=%p\n",key.data(),cachedResult);
if (cachedResult)
{
ambig = cachedResult->isAmbig;
//printf("cached: fileDef=%p\n",cachedResult->fileDef);
return cachedResult->fileDef;
}
else
{
cachedResult = new FindFileCacheElem(0,FALSE);
}
QCString name=QDir::cleanDirPath(n).utf8();
QCString path;
int slashPos;
FileName *fn;
if (name.isEmpty()) goto exit;
slashPos=QMAX(name.findRev('/'),name.findRev('\\'));
if (slashPos!=-1)
{
path=name.left(slashPos+1);
name=name.right(name.length()-slashPos-1);
//printf("path=%s name=%s\n",path.data(),name.data());
}
if (name.isEmpty()) goto exit;
if ((fn=(*fnDict)[name]))
{
//printf("fn->count()=%d\n",fn->count());
if (fn->count()==1)
{
FileDef *fd = fn->getFirst();
#if defined(_WIN32) || defined(__MACOSX__) // Windows or MacOSX
bool isSamePath = fd->getPath().right(path.length()).lower()==path.lower();
#else // Unix
bool isSamePath = fd->getPath().right(path.length())==path;
#endif
if (path.isEmpty() || isSamePath)
{
cachedResult->fileDef = fd;
g_findFileDefCache.insert(key,cachedResult);
//printf("=1 ===> add to cache %p\n",fd);
return fd;
}
}
else // file name alone is ambiguous
{
int count=0;
FileNameIterator fni(*fn);
FileDef *fd;
FileDef *lastMatch=0;
QCString pathStripped = stripFromIncludePath(path);
for (fni.toFirst();(fd=fni.current());++fni)
{
QCString fdStripPath = stripFromIncludePath(fd->getPath());
if (path.isEmpty() || fdStripPath.right(pathStripped.length())==pathStripped)
{
count++;
lastMatch=fd;
}
}
//printf(">1 ===> add to cache %p\n",fd);
ambig=(count>1);
cachedResult->isAmbig = ambig;
cachedResult->fileDef = lastMatch;
g_findFileDefCache.insert(key,cachedResult);
return lastMatch;
}
}
else
{
//printf("not found!\n");
}
exit:
//printf("0 ===> add to cache %p: %s\n",cachedResult,n);
g_findFileDefCache.insert(key,cachedResult);
//delete cachedResult;
return 0;
}
static void findMembersWithSpecificName ( MemberName mn,
const char *  args,
bool  checkStatics,
FileDef currentFile,
bool  checkCV,
const char *  forceTagFile,
QList< MemberDef > &  members 
)
static

Definition at line 3949 of file util.cpp.

References MemberDef::argumentList(), MemberDef::getFileDef(), MemberDef::getGroupDef(), MemberDef::getNamespaceDef(), Definition::getOuterScope(), MemberDef::getReference(), Doxygen::globalScope, MemberDef::isDefine(), GroupDef::isLinkable(), FileDef::isLinkable(), MemberDef::isLinkable(), MemberDef::isReference(), MemberDef::isStatic(), matchArguments2(), and stringToArgumentList().

Referenced by getDefs().

{
//printf(" Function with global scope name `%s' args=`%s'\n",
// mn->memberName(),args);
MemberDef *md;
for (mli.toFirst();(md=mli.current());++mli)
{
FileDef *fd=md->getFileDef();
GroupDef *gd=md->getGroupDef();
//printf(" md->name()=`%s' md->args=`%s' fd=%p gd=%p current=%p ref=%s\n",
// md->name().data(),args,fd,gd,currentFile,md->getReference().data());
if (
((gd && gd->isLinkable()) || (fd && fd->isLinkable()) || md->isReference()) &&
md->getNamespaceDef()==0 && md->isLinkable() &&
(!checkStatics || (!md->isStatic() && !md->isDefine()) ||
currentFile==0 || fd==currentFile) // statics must appear in the same file
)
{
bool match=TRUE;
ArgumentList *argList=0;
if (args && !md->isDefine() && qstrcmp(args,"()")!=0)
{
argList=new ArgumentList;
ArgumentList *mdAl = md->argumentList();
stringToArgumentList(args,argList);
md->getOuterScope(),fd,mdAl,
checkCV);
delete argList; argList=0;
}
if (match && (forceTagFile==0 || md->getReference()==forceTagFile))
{
//printf("Found match!\n");
members.append(md);
}
}
}
}
static bool findOperator ( const QCString &  s,
int  i 
)
static

Definition at line 1623 of file util.cpp.

{
int b = s.findRev("operator",i);
if (b==-1) return FALSE; // not found
b+=8;
while (b<i) // check if there are only spaces in between
// the operator and the >
{
if (!isspace((uchar)s.at(b))) return FALSE;
b++;
}
return TRUE;
}
static bool findOperator2 ( const QCString &  s,
int  i 
)
static

Definition at line 1637 of file util.cpp.

References isId().

{
int b = s.findRev("operator",i);
if (b==-1) return FALSE; // not found
b+=8;
while (b<i) // check if there are only non-ascii
// characters in front of the operator
{
if (isId((uchar)s.at(b))) return FALSE;
b++;
}
return TRUE;
}
int findParameterList ( const QCString &  name)

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

Definition at line 1925 of file util.cpp.

Referenced by resolveRef().

{
int pos=-1;
int templateDepth=0;
do
{
if (templateDepth > 0)
{
int nextOpenPos=name.findRev('>', pos);
int nextClosePos=name.findRev('<', pos);
if (nextOpenPos!=-1 && nextOpenPos>nextClosePos)
{
++templateDepth;
pos=nextOpenPos-1;
}
else if (nextClosePos!=-1)
{
--templateDepth;
pos=nextClosePos-1;
}
else // more >'s than <'s, see bug701295
{
return -1;
}
}
else
{
int lastAnglePos=name.findRev('>', pos);
int bracePos=name.findRev('(', pos);
if (lastAnglePos!=-1 && lastAnglePos>bracePos)
{
++templateDepth;
pos=lastAnglePos-1;
}
else
{
int bp = bracePos>0 ? name.findRev('(',bracePos-1) : -1;
// bp test is to allow foo(int(&)[10]), but we need to make an exception for operator()
return bp==-1 || (bp>=8 && name.mid(bp-8,10)=="operator()") ? bracePos : bp;
}
}
} while (pos!=-1);
return -1;
}
static int findScopePattern ( const QCString &  pattern,
const QCString &  s,
int  p,
int *  len 
)
static
Parameters
patternpattern to look for
sstring to search in
pposition to start
lenresulting pattern length
Returns
position on which string is found, or -1 if not found

Definition at line 2761 of file util.cpp.

Referenced by trimScope().

{
int sl=s.length();
int pl=pattern.length();
int sp=0;
*len=0;
while (p<sl)
{
sp=p; // start of match
int pp=0; // pattern position
while (p<sl && pp<pl)
{
if (s.at(p)=='<') // skip template arguments while matching
{
int bc=1;
//printf("skipping pos=%d c=%c\n",p,s.at(p));
p++;
while (p<sl)
{
if (s.at(p)=='<') bc++;
else if (s.at(p)=='>')
{
bc--;
if (bc==0)
{
p++;
break;
}
}
//printf("skipping pos=%d c=%c\n",p,s.at(p));
p++;
}
}
else if (s.at(p)==pattern.at(pp))
{
//printf("match at position p=%d pp=%d c=%c\n",p,pp,s.at(p));
p++;
pp++;
}
else // no match
{
//printf("restarting at %d c=%c pat=%s\n",p,s.at(p),pattern.data());
p=sp+1;
break;
}
}
if (pp==pl) // whole pattern matches
{
*len=p-sp;
return sp;
}
}
return -1;
}
static Definition* followPath ( Definition start,
FileDef fileScope,
const QCString &  path 
)
static

Starting with scope start, the string path is interpreted as a part of a qualified scope name (e.g. A::B::C), and the scope is searched. If found the scope definition is returned, otherwise 0 is returned.

Definition at line 752 of file util.cpp.

References DefinitionIntf::definitionType(), endOfPathIsUsedClass(), Definition::findInnerCompound(), getScopeFragment(), newResolveTypedef(), substTypedef(), DefinitionIntf::TypeFile, and DefinitionIntf::TypeNamespace.

Referenced by accessibleViaUsingClass(), accessibleViaUsingNamespace(), and isAccessibleFromWithExpScope().

{
int is,ps;
int l;
Definition *current=start;
ps=0;
//printf("followPath: start='%s' path='%s'\n",start?start->name().data():"<none>",path.data());
// for each part of the explicit scope
while ((is=getScopeFragment(path,ps,&l))!=-1)
{
// try to resolve the part if it is a typedef
MemberDef *typeDef=0;
QCString qualScopePart = substTypedef(current,fileScope,path.mid(is,l),&typeDef);
//printf(" qualScopePart=%s\n",qualScopePart.data());
if (typeDef)
{
ClassDef *type = newResolveTypedef(fileScope,typeDef);
if (type)
{
//printf("Found type %s\n",type->name().data());
return type;
}
}
Definition *next = current->findInnerCompound(qualScopePart);
//printf("++ Looking for %s inside %s result %s\n",
// qualScopePart.data(),
// current->name().data(),
// next?next->name().data():"<null>");
if (next==0) // failed to follow the path
{
//printf("==> next==0!\n");
{
((NamespaceDef *)current)->getUsedClasses(),qualScopePart);
}
else if (current->definitionType()==Definition::TypeFile)
{
((FileDef *)current)->getUsedClasses(),qualScopePart);
}
current = next;
if (current==0) break;
}
else // continue to follow scope
{
current = next;
//printf("==> current = %p\n",current);
}
ps=is+l;
}
//printf("followPath(start=%s,path=%s) result=%s\n",
// start->name().data(),path.data(),current?current->name().data():"<null>");
return current; // path could be followed
}
static QCache<FindFileCacheElem> g_findFileDefCache ( 5000  )
static

Referenced by findFileDef().

void generateFileRef ( OutputDocInterface od,
const char *  name,
const char *  text 
)

Definition at line 4993 of file util.cpp.

References BaseOutputDocInterface::docify(), findFileDef(), FileDef::getOutputFileBase(), Definition::getReference(), Doxygen::inputNameDict, FileDef::isLinkable(), and BaseOutputDocInterface::writeObjectLink().

{
//printf("generateFileRef(%s,%s)\n",name,text);
QCString linkText = text ? text : name;
//FileInfo *fi;
FileDef *fd;
bool ambig;
if ((fd=findFileDef(Doxygen::inputNameDict,name,ambig)) &&
fd->isLinkable())
// link to documented input file
od.writeObjectLink(fd->getReference(),fd->getOutputFileBase(),0,linkText);
else
od.docify(linkText);
}
bool generateLink ( OutputDocInterface od,
const char *  clName,
const char *  lr,
bool  inSeeBlock,
const char *  lt 
)

Definition at line 4951 of file util.cpp.

References DefinitionIntf::definitionType(), BaseOutputDocInterface::docify(), err(), Definition::getLanguage(), Definition::getOutputFileBase(), Definition::getReference(), Definition::isReference(), linkToText(), resolveLink(), SrcLangExt_Unknown, DefinitionIntf::TypeFile, DefinitionIntf::TypeGroup, BaseOutputDocInterface::writeObjectLink(), and writePageRef().

{
//printf("generateLink(clName=%s,lr=%s,lr=%s)\n",clName,lr,lt);
Definition *compound;
//PageDef *pageDef=0;
QCString anchor,linkText=linkToText(SrcLangExt_Unknown,lt,FALSE);
//printf("generateLink linkText=%s\n",linkText.data());
if (resolveLink(clName,lr,inSeeBlock,&compound,anchor))
{
if (compound) // link to compound
{
if (lt==0 && anchor.isEmpty() && /* compound link */
compound->definitionType()==Definition::TypeGroup /* is group */
)
{
linkText=((GroupDef *)compound)->groupTitle(); // use group's title as link
}
else if (compound->definitionType()==Definition::TypeFile)
{
linkText=linkToText(compound->getLanguage(),lt,TRUE);
}
od.writeObjectLink(compound->getReference(),
compound->getOutputFileBase(),anchor,linkText);
if (!compound->isReference())
{
writePageRef(od,compound->getOutputFileBase(),anchor);
}
}
else
{
err("%s:%d: Internal error: resolveLink successful but no compound found!",__FILE__,__LINE__);
}
return TRUE;
}
else // link could not be found
{
od.docify(linkText);
return FALSE;
}
}
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 266 of file util.cpp.

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

{
const int maxMarkerStrLen = 20;
char result[maxMarkerStrLen];
qsnprintf(result,maxMarkerStrLen,"@%d",id);
return result;
}
QCString getCanonicalTemplateSpec ( Definition d,
FileDef fs,
const QCString &  spec 
)

Definition at line 3421 of file util.cpp.

References extractCanonicalType(), and resolveTypeDef().

Referenced by getCanonicalTypeForIdentifier().

{
QCString templSpec = spec.stripWhiteSpace();
// this part had been commented out before... but it is needed to match for instance
// std::list<std::string> against list<string> so it is now back again!
if (!templSpec.isEmpty() && templSpec.at(0) == '<')
{
templSpec = "< " + extractCanonicalType(d,fs,templSpec.right(templSpec.length()-1).stripWhiteSpace());
}
QCString resolvedType = resolveTypeDef(d,templSpec);
if (!resolvedType.isEmpty()) // not known as a typedef either
{
templSpec = resolvedType;
}
//printf("getCanonicalTemplateSpec(%s)=%s\n",spec.data(),templSpec.data());
return templSpec;
}
static QCString getCanonicalTypeForIdentifier ( Definition d,
FileDef fs,
const QCString &  word,
QCString *  tSpec,
int  count = 0 
)
static

Definition at line 3441 of file util.cpp.

References getCanonicalTemplateSpec(), getResolvedClass(), MemberDef::isEnumerate(), ClassDef::isTemplate(), MemberDef::isTypedef(), ClassDef::isUsedOnly(), Definition::name(), MemberDef::qualifiedName(), Definition::qualifiedName(), ClassDef::qualifiedNameWithTemplateParameters(), removeRedundantWhiteSpace(), resolveTypeDef(), stripDeclKeywords(), stripScope(), and MemberDef::typeString().

Referenced by extractCanonicalType().

{
if (count>10) return word; // oops recursion
QCString symName,result,templSpec,tmpName;
//DefinitionList *defList=0;
if (tSpec && !tSpec->isEmpty())
templSpec = stripDeclKeywords(getCanonicalTemplateSpec(d,fs,*tSpec));
if (word.findRev("::")!=-1 && !(tmpName=stripScope(word)).isEmpty())
{
symName=tmpName; // name without scope
}
else
{
symName=word;
}
//printf("getCanonicalTypeForIdentifier(%s,[%s->%s]) start\n",
// word.data(),tSpec?tSpec->data():"<none>",templSpec.data());
ClassDef *cd = 0;
MemberDef *mType = 0;
QCString ts;
QCString resolvedType;
// lookup class / class template instance
cd = getResolvedClass(d,fs,word+templSpec,&mType,&ts,TRUE,TRUE,&resolvedType);
bool isTemplInst = cd && !templSpec.isEmpty();
if (!cd && !templSpec.isEmpty())
{
// class template specialization not known, look up class template
cd = getResolvedClass(d,fs,word,&mType,&ts,TRUE,TRUE,&resolvedType);
}
if (cd && cd->isUsedOnly()) cd=0; // ignore types introduced by usage relations
//printf("cd=%p mtype=%p\n",cd,mType);
//printf(" getCanonicalTypeForIdentifer: symbol=%s word=%s cd=%s d=%s fs=%s cd->isTemplate=%d\n",
// symName.data(),
// word.data(),
// cd?cd->name().data():"<none>",
// d?d->name().data():"<none>",
// fs?fs->name().data():"<none>",
// cd?cd->isTemplate():-1
// );
//printf(" >>>> word '%s' => '%s' templSpec=%s ts=%s tSpec=%s isTemplate=%d resolvedType=%s\n",
// (word+templSpec).data(),
// cd?cd->qualifiedName().data():"<none>",
// templSpec.data(),ts.data(),
// tSpec?tSpec->data():"<null>",
// cd?cd->isTemplate():FALSE,
// resolvedType.data());
//printf(" mtype=%s\n",mType?mType->name().data():"<none>");
if (cd) // resolves to a known class type
{
if (cd==d && tSpec) *tSpec="";
if (mType && mType->isTypedef()) // but via a typedef
{
result = resolvedType+ts; // the +ts was added for bug 685125
}
else
{
if (isTemplInst)
{
// spec is already part of class type
templSpec="";
if (tSpec) *tSpec="";
}
else if (!ts.isEmpty() && templSpec.isEmpty())
{
// use formal template args for spec
}
result = removeRedundantWhiteSpace(cd->qualifiedName() + templSpec);
if (cd->isTemplate() && tSpec) //
{
if (!templSpec.isEmpty()) // specific instance
{
result=cd->name()+templSpec;
}
else // use template type
{
}
// template class, so remove the template part (it is part of the class name)
*tSpec="";
}
else if (ts.isEmpty() && !templSpec.isEmpty() && cd && !cd->isTemplate() && tSpec)
{
// obscure case, where a class is used as a template, but doxygen think it is
// not (could happen when loading the class from a tag file).
*tSpec="";
}
}
}
else if (mType && mType->isEnumerate()) // an enum
{
result = mType->qualifiedName();
}
else if (mType && mType->isTypedef()) // a typedef
{
//result = mType->qualifiedName(); // changed after 1.7.2
//result = mType->typeString();
//printf("word=%s typeString=%s\n",word.data(),mType->typeString());
if (word!=mType->typeString())
{
result = getCanonicalTypeForIdentifier(d,fs,mType->typeString(),tSpec,count+1);
}
else
{
result = mType->typeString();
}
}
else // fallback
{
resolvedType = resolveTypeDef(d,word);
//printf("typedef [%s]->[%s]\n",word.data(),resolvedType.data());
if (resolvedType.isEmpty()) // not known as a typedef either
{
result = word;
}
else
{
result = resolvedType;
}
}
//printf("getCanonicalTypeForIdentifier [%s]->[%s]\n",word.data(),result.data());
return result;
}
ClassDef* getClass ( const char *  n)

Get a class definition given its name. Returns 0 if the class is not found.

Definition at line 472 of file util.cpp.

References Doxygen::classSDict, and SDict< T >::find().

Referenced by addClassToContext(), addEnumValuesToEnums(), addVariable(), addVariableToFile(), buildFunctionList(), buildInterfaceAndServiceList(), buildScopeFromQualifiedName(), computeClassRelations(), computeTemplateClassRelations(), extractNamespaceName(), findClassRelation(), findClassWithinClassContext(), findEnumDocumentation(), findEnums(), findInheritedTemplateInstances(), findMember(), findUsedTemplateInstances(), findUsingDeclImports(), MemberDef::getClassDefOfAnonymousType(), getResolvedClass(), getScopeDefs(), getTemplateArgumentsFromName(), handleLinkedWord(), insertTemplateSpecifierInScope(), MemberDef::isDocumentedFriendClass(), linkifyText(), matchArgument(), resolveLink(), resolveRef(), stripTemplateSpecifiersFromScope(), trimTemplateSpecifiers(), and MemberDef::writeDeclaration().

{
if (n==0 || n[0]=='\0') return 0;
QCString name=n;
ClassDef *result = Doxygen::classSDict->find(name);
//if (result==0 && !exact) // also try generic and protocol versions
//{
// result = Doxygen::classSDict->find(name+"-g");
// if (result==0)
// {
// result = Doxygen::classSDict->find(name+"-p");
// }
//}
//printf("getClass(%s)=%s\n",n,result?result->name().data():"<none>");
return result;
}
bool getDefs ( const QCString &  scName,
const QCString &  mbName,
const char *  args,
MemberDef *&  md,
ClassDef *&  cd,
FileDef *&  fd,
NamespaceDef *&  nd,
GroupDef *&  gd,
bool  forceEmptyScope,
FileDef currentFile,
bool  checkCV,
const char *  forceTagFile 
)

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

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

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

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

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

Definition at line 4018 of file util.cpp.

References MemberDef::argumentList(), MemberDef::enumFieldList(), SDict< T >::find(), findMembersWithSpecificName(), Doxygen::functionNameSDict, MemberDef::getClassDef(), MemberDef::getEnumScope(), MemberDef::getFileDef(), ClassDef::getFileDef(), MemberDef::getGroupDef(), MemberDef::getNamespaceDef(), Definition::getOuterScope(), getResolvedClass(), Doxygen::globalScope, MemberDef::isEnumerate(), MemberDef::isForeign(), GroupDef::isLinkable(), NamespaceDef::isLinkable(), FileDef::isLinkable(), ClassDef::isLinkable(), MemberDef::isLinkable(), MemberDef::isRelated(), MemberDef::isStrong(), MemberDef::isStrongEnumValue(), Definition::localName(), matchArguments2(), maxInheritanceDepth, Doxygen::memberNameSDict, minClassDistance(), FileDef::name(), Definition::name(), Doxygen::namespaceSDict, rightScopeMatch(), stringToArgumentList(), stripTemplateSpecifiersFromScope(), and substitute().

Referenced by findDocsForMemberOrCompound(), linkifyText(), and resolveRef().

{
fd=0, md=0, cd=0, nd=0, gd=0;
if (mbName.isEmpty()) return FALSE; /* empty name => nothing to link */
QCString scopeName=scName;
QCString memberName=mbName;
scopeName = substitute(scopeName,"\\","::"); // for PHP
memberName = substitute(memberName,"\\","::"); // for PHP
//printf("Search for name=%s args=%s in scope=%s forceEmpty=%d\n",
// memberName.data(),args,scopeName.data(),forceEmptyScope);
int is,im=0,pm=0;
// strip common part of the scope from the scopeName
while ((is=scopeName.findRev("::"))!=-1 &&
(im=memberName.find("::",pm))!=-1 &&
(scopeName.right(scopeName.length()-is-2)==memberName.mid(pm,im-pm))
)
{
scopeName=scopeName.left(is);
pm=im+2;
}
//printf("result after scope corrections scope=%s name=%s\n",
// scopeName.data(),memberName.data());
QCString mName=memberName;
QCString mScope;
if (memberName.left(9)!="operator " && // treat operator conversion methods
// as a special case
(im=memberName.findRev("::"))!=-1 &&
im<(int)memberName.length()-2 // not A::
)
{
mScope=memberName.left(im);
mName=memberName.right(memberName.length()-im-2);
}
// handle special the case where both scope name and member scope are equal
if (mScope==scopeName) scopeName.resize(0);
//printf("mScope=`%s' mName=`%s'\n",mScope.data(),mName.data());
//printf("mName=%s mn=%p\n",mName.data(),mn);
if ((!forceEmptyScope || scopeName.isEmpty()) && // this was changed for bug638856, forceEmptyScope => empty scopeName
mn && !(scopeName.isEmpty() && mScope.isEmpty()))
{
//printf(" >member name '%s' found\n",mName.data());
int scopeOffset=scopeName.length();
do
{
QCString className = scopeName.left(scopeOffset);
if (!className.isEmpty() && !mScope.isEmpty())
{
className+="::"+mScope;
}
else if (!mScope.isEmpty())
{
className=mScope;
}
MemberDef *tmd=0;
if (fcd==0 && className.find('<')!=-1) // try without template specifiers as well
{
QCString nameWithoutTemplates = stripTemplateSpecifiersFromScope(className,FALSE);
fcd=getResolvedClass(Doxygen::globalScope,0,nameWithoutTemplates,&tmd);
}
//printf("Trying class scope %s: fcd=%p tmd=%p\n",className.data(),fcd,tmd);
// todo: fill in correct fileScope!
if (fcd && // is it a documented class
fcd->isLinkable()
)
{
//printf(" Found fcd=%p\n",fcd);
MemberNameIterator mmli(*mn);
MemberDef *mmd;
int mdist=maxInheritanceDepth;
ArgumentList *argList=0;
if (args)
{
argList=new ArgumentList;
stringToArgumentList(args,argList);
}
for (mmli.toFirst();(mmd=mmli.current());++mmli)
{
if (!mmd->isStrongEnumValue())
{
ArgumentList *mmdAl = mmd->argumentList();
bool match=args==0 ||
fcd,fcd->getFileDef(),argList,
checkCV
);
//printf("match=%d\n",match);
if (match)
{
ClassDef *mcd=mmd->getClassDef();
if (mcd)
{
int m=minClassDistance(fcd,mcd);
if (m<mdist && mcd->isLinkable())
{
mdist=m;
cd=mcd;
md=mmd;
}
}
}
}
}
if (argList)
{
delete argList; argList=0;
}
if (mdist==maxInheritanceDepth && args && qstrcmp(args,"()")==0)
// no exact match found, but if args="()" an arbitrary member will do
{
//printf(" >Searching for arbitrary member\n");
for (mmli.toFirst();(mmd=mmli.current());++mmli)
{
//if (mmd->isLinkable())
//{
ClassDef *mcd=mmd->getClassDef();
//printf(" >Class %s found\n",mcd->name().data());
if (mcd)
{
int m=minClassDistance(fcd,mcd);
if (m<mdist /* && mcd->isLinkable()*/ )
{
//printf("Class distance %d\n",m);
mdist=m;
cd=mcd;
md=mmd;
}
}
//}
}
}
//printf(" >Succes=%d\n",mdist<maxInheritanceDepth);
if (mdist<maxInheritanceDepth)
{
if (!md->isLinkable() || md->isStrongEnumValue())
{
md=0; // avoid returning things we cannot link to
cd=0;
return FALSE; // match found, but was not linkable
}
else
{
gd=md->getGroupDef();
if (gd) cd=0;
return TRUE; /* found match */
}
}
}
if (tmd && tmd->isEnumerate() && tmd->isStrong()) // scoped enum
{
//printf("Found scoped enum!\n");
MemberList *tml = tmd->enumFieldList();
if (tml)
{
MemberListIterator tmi(*tml);
MemberDef *emd;
for (;(emd=tmi.current());++tmi)
{
if (emd->localName()==mName)
{
if (emd->isLinkable())
{
cd=tmd->getClassDef();
md=emd;
return TRUE;
}
else
{
cd=0;
md=0;
return FALSE;
}
}
}
}
}
/* go to the parent scope */
if (scopeOffset==0)
{
scopeOffset=-1;
}
else if ((scopeOffset=scopeName.findRev("::",scopeOffset-1))==-1)
{
scopeOffset=0;
}
} while (scopeOffset>=0);
}
if (mn && scopeName.isEmpty() && mScope.isEmpty()) // Maybe a related function?
{
//printf("Global symbol\n");
MemberNameIterator mmli(*mn);
MemberDef *mmd, *fuzzy_mmd = 0;
ArgumentList *argList = 0;
bool hasEmptyArgs = args && qstrcmp(args, "()") == 0;
if (args)
stringToArgumentList(args, argList = new ArgumentList);
for (mmli.toFirst(); (mmd = mmli.current()); ++mmli)
{
if (!mmd->isLinkable() || (!mmd->isRelated() && !mmd->isForeign()) ||
!mmd->getClassDef())
continue;
if (!args) break;
ArgumentList *mmdAl = mmd->argumentList();
if (matchArguments2(mmd->getOuterScope(),mmd->getFileDef(),mmdAl,
checkCV
)
) break;
if (!fuzzy_mmd && hasEmptyArgs)
fuzzy_mmd = mmd;
}
if (argList) delete argList, argList = 0;
mmd = mmd ? mmd : fuzzy_mmd;
if (mmd && !mmd->isStrongEnumValue())
{
md = mmd;
cd = mmd->getClassDef();
return TRUE;
}
}
// maybe an namespace, file or group member ?
//printf("Testing for global symbol scopeName=`%s' mScope=`%s' :: mName=`%s'\n",
// scopeName.data(),mScope.data(),mName.data());
if ((mn=Doxygen::functionNameSDict->find(mName))) // name is known
{
//printf(" >symbol name found\n");
NamespaceDef *fnd=0;
int scopeOffset=scopeName.length();
do
{
QCString namespaceName = scopeName.left(scopeOffset);
if (!namespaceName.isEmpty() && !mScope.isEmpty())
{
namespaceName+="::"+mScope;
}
else if (!mScope.isEmpty())
{
namespaceName=mScope.copy();
}
//printf("Trying namespace %s\n",namespaceName.data());
if (!namespaceName.isEmpty() &&
(fnd=Doxygen::namespaceSDict->find(namespaceName)) &&
fnd->isLinkable()
)
{
//printf("Symbol inside existing namespace `%s' count=%d\n",
// namespaceName.data(),mn->count());
bool found=FALSE;
MemberNameIterator mmli(*mn);
MemberDef *mmd;
for (mmli.toFirst();((mmd=mmli.current()) && !found);++mmli)
{
//printf("mmd->getNamespaceDef()=%p fnd=%p\n",
// mmd->getNamespaceDef(),fnd);
MemberDef *emd = mmd->getEnumScope();
if (emd && emd->isStrong())
{
//printf("yes match %s<->%s!\n",mScope.data(),emd->localName().data());
if (emd->getNamespaceDef()==fnd &&
rightScopeMatch(mScope,emd->localName()))
{
//printf("found it!\n");
nd=fnd;
md=mmd;
found=TRUE;
}
else
{
md=0;
cd=0;
return FALSE;
}
}
else if (mmd->getNamespaceDef()==fnd /* && mmd->isLinkable() */ )
{ // namespace is found
bool match=TRUE;
ArgumentList *argList=0;
if (args && qstrcmp(args,"()")!=0)
{
argList=new ArgumentList;
ArgumentList *mmdAl = mmd->argumentList();
stringToArgumentList(args,argList);
mmd->getOuterScope(),mmd->getFileDef(),mmdAl,
fnd,mmd->getFileDef(),argList,
checkCV);
}
if (match)
{
nd=fnd;
md=mmd;
found=TRUE;
}
if (args)
{
delete argList; argList=0;
}
}
}
if (!found && args && !qstrcmp(args,"()"))
// no exact match found, but if args="()" an arbitrary
// member will do
{
for (mmli.toFirst();((mmd=mmli.current()) && !found);++mmli)
{
if (mmd->getNamespaceDef()==fnd /*&& mmd->isLinkable() */ )
{
nd=fnd;
md=mmd;
found=TRUE;
}
}
}
if (found)
{
if (!md->isLinkable())
{
md=0; // avoid returning things we cannot link to
nd=0;
return FALSE; // match found but not linkable
}
else
{
gd=md->getGroupDef();
if (gd && gd->isLinkable()) nd=0; else gd=0;
return TRUE;
}
}
}
else
{
//printf("not a namespace\n");
MemberNameIterator mmli(*mn);
MemberDef *mmd;
for (mmli.toFirst();(mmd=mmli.current());++mmli)
{
MemberDef *tmd = mmd->getEnumScope();
//printf("try member %s tmd=%s\n",mmd->name().data(),tmd?tmd->name().data():"<none>");
int ni=namespaceName.findRev("::");
//printf("namespaceName=%s ni=%d\n",namespaceName.data(),ni);
bool notInNS = tmd && ni==-1 && tmd->getNamespaceDef()==0 && (mScope.isEmpty() || mScope==tmd->name());
bool sameNS = tmd && tmd->getNamespaceDef() && namespaceName.left(ni)==tmd->getNamespaceDef()->name();
//printf("notInNS=%d sameNS=%d\n",notInNS,sameNS);
if (tmd && tmd->isStrong() && // C++11 enum class
(notInNS || sameNS) &&
namespaceName.length()>0 // enum is part of namespace so this should not be empty
)
{
md=mmd;
fd=mmd->getFileDef();
gd=mmd->getGroupDef();
if (gd && gd->isLinkable()) fd=0; else gd=0;
//printf("Found scoped enum %s fd=%p gd=%p\n",
// mmd->name().data(),fd,gd);
return TRUE;
}
}
}
if (scopeOffset==0)
{
scopeOffset=-1;
}
else if ((scopeOffset=scopeName.findRev("::",scopeOffset-1))==-1)
{
scopeOffset=0;
}
} while (scopeOffset>=0);
//else // no scope => global function
{
QList<MemberDef> members;
// search for matches with strict static checking
findMembersWithSpecificName(mn,args,TRUE,currentFile,checkCV,forceTagFile,members);
if (members.count()==0) // nothing found
{
// search again without strict static checking
findMembersWithSpecificName(mn,args,FALSE,currentFile,checkCV,forceTagFile,members);
}
//printf("found %d members\n",members.count());
if (members.count()!=1 && args && !qstrcmp(args,"()"))
{
// no exact match found, but if args="()" an arbitrary
// member will do
for (mni.toLast();(md=mni.current());--mni)
{
//printf("Found member `%s'\n",md->name().data());
//printf("member is linkable md->name()=`%s'\n",md->name().data());
fd=md->getFileDef();
gd=md->getGroupDef();
MemberDef *tmd = md->getEnumScope();
if (
(gd && gd->isLinkable()) || (fd && fd->isLinkable()) ||
(tmd && tmd->isStrong())
)
{
members.append(md);
}
}
}
//printf("found %d candidate members\n",members.count());
if (members.count()>0) // at least one match
{
if (currentFile)
{
//printf("multiple results; pick one from file:%s\n", currentFile->name().data());
QListIterator<MemberDef> mit(members);
for (mit.toFirst();(md=mit.current());++mit)
{
if (md->getFileDef() && md->getFileDef()->name() == currentFile->name())
{
break; // found match in the current file
}
}
if (!md) // member not in the current file
{
md=members.getLast();
}
}
else
{
md=members.getLast();
}
}
if (md && (md->getEnumScope()==0 || !md->getEnumScope()->isStrong()))
// found a matching global member, that is not a scoped enum value (or uniquely matches)
{
fd=md->getFileDef();
gd=md->getGroupDef();
//printf("fd=%p gd=%p gd->isLinkable()=%d\n",fd,gd,gd->isLinkable());
if (gd && gd->isLinkable()) fd=0; else gd=0;
return TRUE;
}
}
}
// no nothing found
return FALSE;
}
QCString getDotImageExtension ( void  )

Definition at line 8677 of file util.cpp.

References Config_getEnum.

Referenced by DotGfxHierarchyTable::createGraph(), RTFGenerator::endCallGraph(), RTFGenerator::endDirDepGraph(), RTFGenerator::endDotGraph(), RTFGenerator::endInclDepGraph(), VhdlDocGen::findConstraintFile(), generateGraphLegend(), DocbookDocVisitor::startDotFile(), TranslatorDutch::trLegendDocs(), TranslatorSlovene::trLegendDocs(), TranslatorCroatian::trLegendDocs(), TranslatorSwedish::trLegendDocs(), TranslatorChinese::trLegendDocs(), TranslatorDanish::trLegendDocs(), TranslatorUkrainian::trLegendDocs(), TranslatorArmenian::trLegendDocs(), TranslatorHungarian::trLegendDocs(), TranslatorIndonesian::trLegendDocs(), TranslatorSerbian::trLegendDocs(), TranslatorAfrikaans::trLegendDocs(), TranslatorSlovak::trLegendDocs(), TranslatorMacedonian::trLegendDocs(), TranslatorGreek::trLegendDocs(), TranslatorRussian::trLegendDocs(), TranslatorLithuanian::trLegendDocs(), TranslatorBrazilian::trLegendDocs(), TranslatorPolish::trLegendDocs(), TranslatorEnglish::trLegendDocs(), TranslatorPersian::trLegendDocs(), TranslatorTurkish::trLegendDocs(), TranslatorPortuguese::trLegendDocs(), TranslatorEsperanto::trLegendDocs(), TranslatorLatvian::trLegendDocs(), TranslatorCatalan::trLegendDocs(), TranslatorChinesetraditional::trLegendDocs(), TranslatorVietnamese::trLegendDocs(), TranslatorRomanian::trLegendDocs(), TranslatorSerbianCyrillic::trLegendDocs(), TranslatorItalian::trLegendDocs(), TranslatorKorean::trLegendDocs(), TranslatorJapanese::trLegendDocs(), TranslatorArabic::trLegendDocs(), TranslatorSpanish::trLegendDocs(), TranslatorNorwegian::trLegendDocs(), TranslatorCzech::trLegendDocs(), TranslatorFrench::trLegendDocs(), TranslatorFinnish::trLegendDocs(), TranslatorGerman::trLegendDocs(), RTFDocVisitor::writeDotFile(), writeDotGraphFromFile(), writeDotImageMapFromFile(), DotClassGraph::writeGraph(), DotInclDepGraph::writeGraph(), DotCallGraph::writeGraph(), DotDirDeps::writeGraph(), DotGroupCollaboration::writeGraph(), writeGraphInfo(), HtmlDocVisitor::writeMscFile(), and HtmlDocVisitor::writePlantUMLFile().

{
QCString imgExt = Config_getEnum(DOT_IMAGE_FORMAT);
imgExt = imgExt.replace( QRegExp(":.*"), "" );
return imgExt;
}
QCString getFileFilter ( const char *  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 2422 of file util.cpp.

References Config_getList, Config_getString, and getFilterFromList().

Referenced by readCodeFragment(), readInputFile(), and FileDef::writeSource().

{
// sanity check
if (name==0) return "";
QStrList& filterSrcList = Config_getList(FILTER_SOURCE_PATTERNS);
QStrList& filterList = Config_getList(FILTER_PATTERNS);
QCString filterName;
bool found=FALSE;
if (isSourceCode && !filterSrcList.isEmpty())
{ // first look for source filter pattern list
filterName = getFilterFromList(name,filterSrcList,found);
}
if (!found && filterName.isEmpty())
{ // then look for filter pattern list
filterName = getFilterFromList(name,filterList,found);
}
if (!found)
{ // then use the generic input filter
return Config_getString(INPUT_FILTER);
}
else
{
/* remove surrounding double quotes */
if ((filterName.right(1) == "\"") && (filterName.left(1) == "\""))
{
filterName.remove(filterName.length() - 1, 1);
filterName.remove(0, 1);
}
return filterName;
}
}
static QCString getFilterFromList ( const char *  name,
const QStrList &  filterList,
bool &  found 
)
static

Definition at line 2385 of file util.cpp.

References portable_fileSystemIsCaseSensitive().

Referenced by getFileFilter().

{
found=FALSE;
// compare the file name to the filter pattern list
QStrListIterator sli(filterList);
char* filterStr;
for (sli.toFirst(); (filterStr = sli.current()); ++sli)
{
QCString fs = filterStr;
int i_equals=fs.find('=');
if (i_equals!=-1)
{
QCString filterPattern = fs.left(i_equals);
QRegExp fpat(filterPattern,portable_fileSystemIsCaseSensitive(),TRUE);
if (fpat.match(name)!=-1)
{
// found a match!
QCString filterName = fs.mid(i_equals+1);
if (filterName.find(' ')!=-1)
{ // add quotes if the name has spaces
filterName="\""+filterName+"\"";
}
found=TRUE;
return filterName;
}
}
}
// no match
return "";
}
SrcLangExt getLanguageFromFileName ( const QCString  fileName)

Definition at line 7152 of file util.cpp.

References SrcLangExt_Cpp.

Referenced by DocRef::DocRef(), FileDef::FileDef(), ClassDefImpl::init(), processLink(), readCodeFragment(), DocbookDocVisitor::visit(), ManDocVisitor::visit(), RTFDocVisitor::visit(), XmlDocVisitor::visit(), HtmlDocVisitor::visit(), LatexDocVisitor::visit(), writeDocbookCodeBlock(), and writeXMLCodeBlock().

{
int i = fileName.findRev('.');
if (i!=-1) // name has an extension
{
QCString extStr=fileName.right(fileName.length()-i).lower();
if (!extStr.isEmpty()) // non-empty extension
{
int *pVal=g_extLookup.find(extStr);
if (pVal) // listed extension
{
//printf("getLanguageFromFileName(%s)=%x\n",extStr.data(),*pVal);
return (SrcLangExt)*pVal;
}
}
}
//printf("getLanguageFromFileName(%s) not found!\n",fileName.data());
return SrcLangExt_Cpp; // not listed => assume C-ish language.
}
QCString getLanguageSpecificSeparator ( SrcLangExt  lang,
bool  classScope 
)
MemberDef* getMemberFromSymbol ( Definition scope,
FileDef fileScope,
const char *  n 
)

Definition at line 7174 of file util.cpp.

References computeQualifiedIndex(), DefinitionIntf::definitionType(), g_visitedNamespaces, Doxygen::globalScope, isAccessibleFromWithExpScope(), replaceNamespaceAliases(), Doxygen::symbolMap, DefinitionIntf::TypeClass, DefinitionIntf::TypeMember, DefinitionIntf::TypeNamespace, and DefinitionIntf::TypeSymbolList.

Referenced by checkIfTypedef().

{
if (scope==0 ||
)
)
{
}
QCString name = n;
if (name.isEmpty())
return 0; // no name was given
if (di==0)
return 0; // could not find any matching symbols
// mostly copied from getResolvedClassRec()
QCString explicitScopePart;
int qualifierIndex = computeQualifiedIndex(name);
if (qualifierIndex!=-1)
{
explicitScopePart = name.left(qualifierIndex);
replaceNamespaceAliases(explicitScopePart,explicitScopePart.length());
name = name.mid(qualifierIndex+2);
}
//printf("explicitScopePart=%s\n",explicitScopePart.data());
int minDistance = 10000;
MemberDef *bestMatch = 0;
{
//printf("multiple matches!\n");
// find the closest closest matching definition
for (dli.toFirst();(d=dli.current());++dli)
{
{
int distance = isAccessibleFromWithExpScope(scope,fileScope,d,explicitScopePart);
if (distance!=-1 && distance<minDistance)
{
minDistance = distance;
bestMatch = (MemberDef *)d;
//printf("new best match %s distance=%d\n",bestMatch->qualifiedName().data(),distance);
}
}
}
}
{
//printf("unique match!\n");
Definition *d = (Definition *)di;
int distance = isAccessibleFromWithExpScope(scope,fileScope,d,explicitScopePart);
if (distance!=-1 && distance<minDistance)
{
minDistance = distance;
bestMatch = (MemberDef *)d;
//printf("new best match %s distance=%d\n",bestMatch->qualifiedName().data(),distance);
}
}
return bestMatch;
}
QCString getOverloadDocs ( )

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

Definition at line 5945 of file util.cpp.

References theTranslator, and Translator::trOverloadText().

Referenced by addMemberDocs(), and findMember().

{
//"This is an overloaded member function, "
// "provided for convenience. It differs from the above "
// "function only in what argument(s) it accepts.";
}
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 5229 of file util.cpp.

References Config_getList.

Referenced by addClassMemberNameToIndex(), addFileMemberNameToIndex(), addNamespaceMemberNameToIndex(), SearchIndex::addWord(), PrefixIgnoreClassList::compareValue(), MemberNameSDict::compareValues(), FilterAlphaIndex::determineSortKey(), writeAlphabeticalClassList(), and writeMemberList().

{
if (name.isEmpty()) return 0;
static QStrList &sl = Config_getList(IGNORE_PREFIX);
char *s = sl.first();
while (s)
{
const char *ps=s;
const char *pd=name.data();
int i=0;
while (*ps!=0 && *pd!=0 && *ps==*pd) ps++,pd++,i++;
if (*ps==0 && *pd!=0)
{
return i;
}
s = sl.next();
}
return 0;
}
ClassDef* getResolvedClass ( Definition scope,
FileDef fileScope,
const char *  n,
MemberDef **  pTypeDef,
QCString *  pTemplSpec,
bool  mayBeUnlinkable,
bool  mayBeHidden,
QCString *  pResolvedType 
)

Definition at line 1563 of file util.cpp.

References Config_getBool, DefinitionIntf::definitionType(), g_resolvedTypedefs, getClass(), Definition::getLanguage(), getResolvedClassRec(), Doxygen::globalScope, Definition::isHidden(), ClassDef::isLinkable(), SrcLangExt_Java, DefinitionIntf::TypeClass, and DefinitionIntf::TypeNamespace.

Referenced by ClassDef::addTypeConstraint(), findClassDefinition(), findClassRelation(), findClassWithinClassContext(), findUsedClassesForClass(), findUsingDeclarations(), findUsingDeclImports(), getCanonicalTypeForIdentifier(), getDefs(), isVarWithConstructor(), linkifyText(), and normalizeNonTemplateArgumentsInString().

{
static bool optimizeOutputVhdl = Config_getBool(OPTIMIZE_OUTPUT_VHDL);
if (scope==0 ||
) ||
(scope->getLanguage()==SrcLangExt_Java && QCString(n).find("::")!=-1)
)
{
}
//printf("------------ getResolvedClass(scope=%s,file=%s,name=%s,mayUnlinkable=%d)\n",
// scope?scope->name().data():"<global>",
// fileScope?fileScope->name().data():"<none>",
// n,
// mayBeUnlinkable
// );
ClassDef *result;
if (optimizeOutputVhdl)
{
result = getClass(n);
}
else
{
result = getResolvedClassRec(scope,fileScope,n,pTypeDef,pTemplSpec,pResolvedType);
}
if (result==0) // for nested classes imported via tag files, the scope may not
// present, so we check the class name directly as well.
// See also bug701314
{
result = getClass(n);
}
if (!mayBeUnlinkable && result && !result->isLinkable())
{
if (!mayBeHidden || !result->isHidden())
{
//printf("result was %s\n",result?result->name().data():"<none>");
result=0; // don't link to artificial/hidden classes unless explicitly allowed
}
}
//printf("getResolvedClass(%s,%s)=%s\n",scope?scope->name().data():"<global>",
// n,result?result->name().data():"<none>");
return result;
}
static ClassDef * getResolvedClassRec ( Definition scope,
FileDef fileScope,
const char *  n,
MemberDef **  pTypeDef,
QCString *  pTemplSpec,
QCString *  pResolvedType 
)
static

Definition at line 1374 of file util.cpp.

References FileDef::absFilePath(), LookupInfo::classDef, computeQualifiedIndex(), SDict< T >::count(), DefinitionIntf::definitionType(), getResolvedSymbol(), FileDef::getUsedClasses(), FileDef::getUsedNamespaces(), Doxygen::lookupCache, Definition::name(), removeRedundantWhiteSpace(), replaceNamespaceAliases(), LookupInfo::resolvedType, stringToArgumentList(), stripTemplateSpecifiersFromScope(), Doxygen::symbolMap, LookupInfo::templSpec, LookupInfo::typeDef, and DefinitionIntf::TypeSymbolList.

Referenced by getResolvedClass(), and newResolveTypedef().

{
//printf("[getResolvedClassRec(%s,%s)\n",scope?scope->name().data():"<global>",n);
QCString name;
QCString explicitScopePart;
QCString strippedTemplateParams;
&strippedTemplateParams);
ArgumentList actTemplParams;
if (!strippedTemplateParams.isEmpty()) // template part that was stripped
{
stringToArgumentList(strippedTemplateParams,&actTemplParams);
}
int qualifierIndex = computeQualifiedIndex(name);
//printf("name=%s qualifierIndex=%d\n",name.data(),qualifierIndex);
if (qualifierIndex!=-1) // qualified name
{
// split off the explicit scope part
explicitScopePart=name.left(qualifierIndex);
// todo: improve namespace alias substitution
replaceNamespaceAliases(explicitScopePart,explicitScopePart.length());
name=name.mid(qualifierIndex+2);
}
if (name.isEmpty())
{
//printf("] empty name\n");
return 0; // empty name
}
//printf("Looking for symbol %s\n",name.data());
// the -g (for C# generics) and -p (for ObjC protocols) are now already
// stripped from the key used in the symbolMap, so that is not needed here.
if (di==0)
{
//di = Doxygen::symbolMap->find(name+"-g");
//if (di==0)
//{
di = Doxygen::symbolMap->find(name+"-p");
if (di==0)
{
//printf("no such symbol!\n");
return 0;
}
//}
}
//printf("found symbol!\n");
bool hasUsingStatements =
(fileScope && ((fileScope->getUsedNamespaces() &&
fileScope->getUsedNamespaces()->count()>0) ||
(fileScope->getUsedClasses() &&
fileScope->getUsedClasses()->count()>0))
);
//printf("hasUsingStatements=%d\n",hasUsingStatements);
// Since it is often the case that the same name is searched in the same
// scope over an over again (especially for the linked source code generation)
// we use a cache to collect previous results. This is possible since the
// result of a lookup is deterministic. As the key we use the concatenated
// scope, the name to search for and the explicit scope prefix. The speedup
// achieved by this simple cache can be enormous.
int scopeNameLen = scope->name().length()+1;
int nameLen = name.length()+1;
int explicitPartLen = explicitScopePart.length();
int fileScopeLen = hasUsingStatements ? 1+fileScope->absFilePath().length() : 0;
// below is a more efficient coding of
// QCString key=scope->name()+"+"+name+"+"+explicitScopePart;
QCString key(scopeNameLen+nameLen+explicitPartLen+fileScopeLen+1);
char *p=key.rawData();
qstrcpy(p,scope->name()); *(p+scopeNameLen-1)='+';
p+=scopeNameLen;
qstrcpy(p,name); *(p+nameLen-1)='+';
p+=nameLen;
qstrcpy(p,explicitScopePart);
p+=explicitPartLen;
// if a file scope is given and it contains using statements we should
// also use the file part in the key (as a class name can be in
// two different namespaces and a using statement in a file can select
// one of them).
if (hasUsingStatements)
{
// below is a more efficient coding of
// key+="+"+fileScope->name();
*p++='+';
qstrcpy(p,fileScope->absFilePath());
p+=fileScopeLen-1;
}
*p='\0';
LookupInfo *pval=Doxygen::lookupCache->find(key);
//printf("Searching for %s result=%p\n",key.data(),pval);
if (pval)
{
//printf("LookupInfo %p %p '%s' %p\n",
// pval->classDef, pval->typeDef, pval->templSpec.data(),
// pval->resolvedType.data());
if (pTemplSpec) *pTemplSpec=pval->templSpec;
if (pTypeDef) *pTypeDef=pval->typeDef;
if (pResolvedType) *pResolvedType=pval->resolvedType;
//printf("] cachedMatch=%s\n",
// pval->classDef?pval->classDef->name().data():"<none>");
//if (pTemplSpec)
// printf("templSpec=%s\n",pTemplSpec->data());
return pval->classDef;
}
else // not found yet; we already add a 0 to avoid the possibility of
// endless recursion.
{
Doxygen::lookupCache->insert(key,new LookupInfo);
}
ClassDef *bestMatch=0;
MemberDef *bestTypedef=0;
QCString bestTemplSpec;
QCString bestResolvedType;
int minDistance=10000; // init at "infinite"
if (di->definitionType()==DefinitionIntf::TypeSymbolList) // not a unique name
{
//printf(" name is not unique\n");
int count=0;
for (dli.toFirst();(d=dli.current());++dli,++count) // foreach definition
{
getResolvedSymbol(scope,fileScope,d,explicitScopePart,&actTemplParams,
minDistance,bestMatch,bestTypedef,bestTemplSpec,
bestResolvedType);
}
}
else // unique name
{
//printf(" name is unique\n");
Definition *d = (Definition *)di;
getResolvedSymbol(scope,fileScope,d,explicitScopePart,&actTemplParams,
minDistance,bestMatch,bestTypedef,bestTemplSpec,
bestResolvedType);
}
if (pTypeDef)
{
*pTypeDef = bestTypedef;
}
if (pTemplSpec)
{
*pTemplSpec = bestTemplSpec;
}
if (pResolvedType)
{
*pResolvedType = bestResolvedType;
}
//printf("getResolvedClassRec: bestMatch=%p pval->resolvedType=%s\n",
// bestMatch,bestResolvedType.data());
pval=Doxygen::lookupCache->find(key);
if (pval)
{
pval->classDef = bestMatch;
pval->typeDef = bestTypedef;
pval->templSpec = bestTemplSpec;
pval->resolvedType = bestResolvedType;
}
else
{
Doxygen::lookupCache->insert(key,new LookupInfo(bestMatch,bestTypedef,bestTemplSpec,bestResolvedType));
}
//printf("] bestMatch=%s distance=%d\n",
// bestMatch?bestMatch->name().data():"<none>",minDistance);
//if (pTemplSpec)
// printf("templSpec=%s\n",pTemplSpec->data());
return bestMatch;
}
NamespaceDef* getResolvedNamespace ( const char *  name)

Definition at line 489 of file util.cpp.

References SDict< T >::find(), Doxygen::namespaceAliasDict, Doxygen::namespaceSDict, and warn_uncond().

Referenced by addEnumValuesToEnums(), addVariableToFile(), buildFunctionList(), extractNamespaceName(), findEnums(), findMember(), findUsedNamespace(), findUsingDeclarations(), findUsingDirectives(), and writeAlphabeticalClassList().

{
if (name==0 || name[0]=='\0') return 0;
QCString *subst = Doxygen::namespaceAliasDict[name];
if (subst)
{
int count=0; // recursion detection guard
QCString *newSubst;
while ((newSubst=Doxygen::namespaceAliasDict[*subst]) && count<10)
{
subst=newSubst;
count++;
}
if (count==10)
{
warn_uncond("possible recursive namespace alias detected for %s!\n",name);
}
return Doxygen::namespaceSDict->find(subst->data());
}
else
{
}
}
static void getResolvedSymbol ( Definition scope,
FileDef fileScope,
Definition d,
const QCString &  explicitScopePart,
ArgumentList actTemplParams,
int &  minDistance,
ClassDef *&  bestMatch,
MemberDef *&  bestTypedef,
QCString &  bestTemplSpec,
QCString &  bestResolvedType 
)
static

Definition at line 1209 of file util.cpp.

References MemberDef::argsString(), DefinitionIntf::definitionType(), g_visitedNamespaces, Definition::getOuterScope(), FileDef::getUsedNamespaces(), Doxygen::globalScope, isAccessibleFromWithExpScope(), MemberDef::isEnumerate(), MemberDef::isReference(), ClassDef::isTemplateArgument(), MemberDef::isTypedef(), newResolveTypedef(), MemberDef::qualifiedName(), Definition::qualifiedName(), DefinitionIntf::TypeClass, DefinitionIntf::TypeMember, and DefinitionIntf::TypeNamespace.

Referenced by getResolvedClassRec().

{
//printf(" => found type %x name=%s d=%p\n",
// d->definitionType(),d->name().data(),d);
// only look at classes and members that are enums or typedefs
(((MemberDef*)d)->isTypedef() || ((MemberDef*)d)->isEnumerate())
)
)
{
// test accessibility of definition within scope.
int distance = isAccessibleFromWithExpScope(scope,fileScope,d,explicitScopePart);
//printf(" %s; distance %s (%p) is %d\n",scope->name().data(),d->name().data(),d,distance);
if (distance!=-1) // definition is accessible
{
// see if we are dealing with a class or a typedef
if (d->definitionType()==Definition::TypeClass) // d is a class
{
ClassDef *cd = (ClassDef *)d;
//printf("cd=%s\n",cd->name().data());
if (!cd->isTemplateArgument()) // skip classes that
// are only there to
// represent a template
// argument
{
//printf("is not a templ arg\n");
if (distance<minDistance) // found a definition that is "closer"
{
minDistance=distance;
bestMatch = cd;
bestTypedef = 0;
bestTemplSpec.resize(0);
bestResolvedType = cd->qualifiedName();
}
else if (distance==minDistance &&
fileScope && bestMatch &&
fileScope->getUsedNamespaces() &&
)
{
// in case the distance is equal it could be that a class X
// is defined in a namespace and in the global scope. When searched
// in the global scope the distance is 0 in both cases. We have
// to choose one of the definitions: we choose the one in the
// namespace if the fileScope imports namespaces and the definition
// found was in a namespace while the best match so far isn't.
// Just a non-perfect heuristic but it could help in some situations
// (kdecore code is an example).
minDistance=distance;
bestMatch = cd;
bestTypedef = 0;
bestTemplSpec.resize(0);
bestResolvedType = cd->qualifiedName();
}
}
else
{
//printf(" is a template argument!\n");
}
}
{
MemberDef *md = (MemberDef *)d;
//printf(" member isTypedef()=%d\n",md->isTypedef());
if (md->isTypedef()) // d is a typedef
{
QCString args=md->argsString();
if (args.isEmpty()) // do not expand "typedef t a[4];"
{
//printf(" found typedef!\n");
// we found a symbol at this distance, but if it didn't
// resolve to a class, we still have to make sure that
// something at a greater distance does not match, since
// that symbol is hidden by this one.
if (distance<minDistance)
{
QCString spec;
QCString type;
minDistance=distance;
MemberDef *enumType = 0;
ClassDef *cd = newResolveTypedef(fileScope,md,&enumType,&spec,&type,actTemplParams);
if (cd) // type resolves to a class
{
//printf(" bestTypeDef=%p spec=%s type=%s\n",md,spec.data(),type.data());
bestMatch = cd;
bestTypedef = md;
bestTemplSpec = spec;
bestResolvedType = type;
}
else if (enumType) // type resolves to a enum
{
//printf(" is enum\n");
bestMatch = 0;
bestTypedef = enumType;
bestTemplSpec = "";
bestResolvedType = enumType->qualifiedName();
}
else if (md->isReference()) // external reference
{
bestMatch = 0;
bestTypedef = md;
bestTemplSpec = spec;
bestResolvedType = type;
}
else
{
bestMatch = 0;
bestTypedef = md;
bestTemplSpec.resize(0);
bestResolvedType.resize(0);
//printf(" no match\n");
}
}
else
{
//printf(" not the best match %d min=%d\n",distance,minDistance);
}
}
else
{
//printf(" not a simple typedef\n")
}
}
else if (md->isEnumerate())
{
if (distance<minDistance)
{
minDistance=distance;
bestMatch = 0;
bestTypedef = md;
bestTemplSpec = "";
bestResolvedType = md->qualifiedName();
}
}
}
} // if definition accessible
else
{
//printf(" Not accessible!\n");
}
} // if definition is a class or member
//printf(" bestMatch=%p bestResolvedType=%s\n",bestMatch,bestResolvedType.data());
}
static bool getScopeDefs ( const char *  docScope,
const char *  scope,
ClassDef *&  cd,
NamespaceDef *&  nd 
)
static

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

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

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

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

Definition at line 4504 of file util.cpp.

References getClass(), NamespaceDef::isLinkable(), ClassDef::isLinkable(), and Doxygen::namespaceSDict.

Referenced by resolveRef().

{
cd=0;nd=0;
QCString scopeName=scope;
//printf("getScopeDefs: docScope=`%s' scope=`%s'\n",docScope,scope);
if (scopeName.isEmpty()) return FALSE;
bool explicitGlobalScope=FALSE;
if (scopeName.at(0)==':' && scopeName.at(1)==':')
{
scopeName=scopeName.right(scopeName.length()-2);
explicitGlobalScope=TRUE;
}
QCString docScopeName=docScope;
int scopeOffset=explicitGlobalScope ? 0 : docScopeName.length();
do // for each possible docScope (from largest to and including empty)
{
QCString fullName=scopeName.copy();
if (scopeOffset>0) fullName.prepend(docScopeName.left(scopeOffset)+"::");
if (((cd=getClass(fullName)) || // normal class
(cd=getClass(fullName+"-p")) //|| // ObjC protocol
//(cd=getClass(fullName+"-g")) // C# generic
) && cd->isLinkable())
{
return TRUE; // class link written => quit
}
else if ((nd=Doxygen::namespaceSDict->find(fullName)) && nd->isLinkable())
{
return TRUE; // namespace link written => quit
}
if (scopeOffset==0)
{
scopeOffset=-1;
}
else if ((scopeOffset=docScopeName.findRev("::",scopeOffset-1))==-1)
{
scopeOffset=0;
}
} while (scopeOffset>=0);
return FALSE;
}
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 6408 of file util.cpp.

Referenced by buildScopeFromQualifiedName(), findScopeFromQualifiedName(), followPath(), resolveTypeDef(), stripAnonymousNamespaceScope(), and trimTemplateSpecifiers().

{
int sl=s.length();
int sp=p;
int count=0;
bool done;
if (sp>=sl) return -1;
while (sp<sl)
{
char c=s.at(sp);
if (c==':') sp++,p++; else break;
}
while (sp<sl)
{
char c=s.at(sp);
switch (c)
{
case ':': // found next part
goto found;
case '<': // skip template specifier
count=1;sp++;
done=FALSE;
while (sp<sl && !done)
{
// TODO: deal with << and >> operators!
char c=s.at(sp++);
switch(c)
{
case '<': count++; break;
case '>': count--; if (count==0) done=TRUE; break;
default: break;
}
}
break;
default:
sp++;
break;
}
}
found:
*l=sp-p;
//printf("getScopeFragment(%s,%d)=%s\n",s.data(),p,s.mid(p,*l).data());
return p;
}
uint getUtf8Code ( const QCString &  s,
int  idx 
)

Get one unicode character as an unsigned integer from utf-8 string.

Parameters
sutf-8 encoded string
idxbyte position of given string s.
Returns
the unicode codepoint, 0 - MAX_UNICODE_CODEPOINT
See Also
getNextUtf8OrToLower()
getNextUtf8OrToUpper()

Definition at line 8355 of file util.cpp.

Referenced by getUtf8CodeToLower(), and getUtf8CodeToUpper().

{
const int length = s.length();
if (idx >= length) { return 0; }
const uint c0 = (uchar)s.at(idx);
if ( c0 < 0xC2 || c0 >= 0xF8 ) // 1 byte character
{
return c0;
}
if (idx+1 >= length) { return 0; }
const uint c1 = ((uchar)s.at(idx+1)) & 0x3f;
if ( c0 < 0xE0 ) // 2 byte character
{
return ((c0 & 0x1f) << 6) | c1;
}
if (idx+2 >= length) { return 0; }
const uint c2 = ((uchar)s.at(idx+2)) & 0x3f;
if ( c0 < 0xF0 ) // 3 byte character
{
return ((c0 & 0x0f) << 12) | (c1 << 6) | c2;
}
if (idx+3 >= length) { return 0; }
// 4 byte character
const uint c3 = ((uchar)s.at(idx+3)) & 0x3f;
return ((c0 & 0x07) << 18) | (c1 << 12) | (c2 << 6) | c3;
}
uint getUtf8CodeToLower ( const QCString &  s,
int  idx 
)

Returns one unicode character as an unsigned integer from utf-8 string, making the character lower case if it was upper case.

Parameters
sutf-8 encoded string
idxbyte position of given string s.
Returns
the unicode codepoint, 0 - MAX_UNICODE_CODEPOINT, excludes 'A'-'Z'
See Also
getNextUtf8Code()

Definition at line 8391 of file util.cpp.

References getUtf8Code().

Referenced by addClassMemberNameToIndex(), addFileMemberNameToIndex(), addMemberToSearchIndex(), addNamespaceMemberNameToIndex(), createJavascriptSearchIndex(), and writeAlphabeticalClassList().

{
const uint v = getUtf8Code( s, idx );
return v < 0x7f ? tolower( v ) : v;
}
uint getUtf8CodeToUpper ( const QCString &  s,
int  idx 
)

Returns one unicode character as ian unsigned interger from utf-8 string, making the character upper case if it was lower case.

Parameters
sutf-8 encoded string
idxbyte position of given string s.
Returns
the unicode codepoint, 0 - MAX_UNICODE_CODEPOINT, excludes 'A'-'Z'
See Also
getNextUtf8Code()

Definition at line 8406 of file util.cpp.

References getUtf8Code().

Referenced by FilterAlphaIndex::determineSortKey().

{
const uint v = getUtf8Code( s, idx );
return v < 0x7f ? toupper( v ) : v;
}
int guessSection ( const char *  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 315 of file util.cpp.

References Entry::HEADER_SEC, and Entry::SOURCE_SEC.

Referenced by addIncludeFile(), TagFileParser::buildLists(), computeClassRelations(), FileDef::FileDef(), FileDef::generateSourceFile(), and ClassDefImpl::init().

{
QCString n=((QCString)name).lower();
if (n.right(2)==".c" || // source
n.right(3)==".cc" ||
n.right(4)==".cxx" ||
n.right(4)==".cpp" ||
n.right(4)==".c++" ||
n.right(5)==".java" ||
n.right(2)==".m" ||
n.right(2)==".M" ||
n.right(3)==".mm" ||
n.right(3)==".ii" || // inline
n.right(4)==".ixx" ||
n.right(4)==".ipp" ||
n.right(4)==".i++" ||
n.right(4)==".inl" ||
n.right(4)==".xml"
if (n.right(2)==".h" || // header
n.right(3)==".hh" ||
n.right(4)==".hxx" ||
n.right(4)==".hpp" ||
n.right(4)==".h++" ||
n.right(4)==".idl" ||
n.right(4)==".ddl" ||
n.right(5)==".pidl"
return 0;
}
bool hasVisibleRoot ( BaseClassList bcl)
static void initBaseClassHierarchy ( BaseClassList bcl)
static

Definition at line 5251 of file util.cpp.

References ClassDef::baseClasses(), and ClassDef::visited.

Referenced by initClassHierarchy().

{
if (bcl==0) return;
for ( ; bcli.current(); ++bcli)
{
ClassDef *cd=bcli.current()->classDef;
if (cd->baseClasses()==0) // no base classes => new root
{
}
cd->visited=FALSE;
}
}
void initClassHierarchy ( ClassSDict cl)
void initDefaultExtensionMapping ( )

Definition at line 7087 of file util.cpp.

References updateLanguageMapping().

Referenced by initDoxygen().

{
// NOTE: when adding an extension, also add the extension in config.xml
g_extLookup.setAutoDelete(TRUE);
// extension parser id
updateLanguageMapping(".dox", "c");
updateLanguageMapping(".txt", "c"); // see bug 760836
updateLanguageMapping(".doc", "c");
updateLanguageMapping(".cc", "c");
updateLanguageMapping(".CC", "c");
updateLanguageMapping(".cxx", "c");
updateLanguageMapping(".cpp", "c");
updateLanguageMapping(".c++", "c");
updateLanguageMapping(".ii", "c");
updateLanguageMapping(".ixx", "c");
updateLanguageMapping(".ipp", "c");
updateLanguageMapping(".i++", "c");
updateLanguageMapping(".inl", "c");
updateLanguageMapping(".hh", "c");
updateLanguageMapping(".HH", "c");
updateLanguageMapping(".hxx", "c");
updateLanguageMapping(".hpp", "c");
updateLanguageMapping(".h++", "c");
updateLanguageMapping(".idl", "idl");
updateLanguageMapping(".ddl", "idl");
updateLanguageMapping(".odl", "idl");
updateLanguageMapping(".java", "java");
//updateLanguageMapping(".as", "javascript"); // not officially supported
//updateLanguageMapping(".js", "javascript"); // not officially supported
updateLanguageMapping(".cs", "csharp");
updateLanguageMapping(".php", "php");
updateLanguageMapping(".php4", "php");
updateLanguageMapping(".php5", "php");
updateLanguageMapping(".inc", "php");
updateLanguageMapping(".phtml", "php");
updateLanguageMapping(".m", "objective-c");
updateLanguageMapping(".M", "objective-c");
updateLanguageMapping(".mm", "c"); // see bug746361
updateLanguageMapping(".py", "python");
updateLanguageMapping(".pyw", "python");
updateLanguageMapping(".f", "fortran");
updateLanguageMapping(".for", "fortran");
updateLanguageMapping(".f90", "fortran");
updateLanguageMapping(".f95", "fortran");
updateLanguageMapping(".f03", "fortran");
updateLanguageMapping(".f08", "fortran");
updateLanguageMapping(".vhd", "vhdl");
updateLanguageMapping(".vhdl", "vhdl");
updateLanguageMapping(".tcl", "tcl");
updateLanguageMapping(".ucf", "vhdl");
updateLanguageMapping(".qsf", "vhdl");
updateLanguageMapping(".md", "md");
updateLanguageMapping(".markdown", "md");
}
QCString insertTemplateSpecifierInScope ( const QCString &  scope,
const QCString &  templ 
)

Definition at line 5613 of file util.cpp.

References getClass(), and ClassDef::templateArguments().

Referenced by DotClassGraph::addClass(), generateXMLForClass(), InheritanceListContext::InheritanceListContext(), DiagramItem::label(), and ClassDef::writeInheritanceGraph().

{
QCString result=scope.copy();
if (!templ.isEmpty() && scope.find('<')==-1)
{
int si,pi=0;
ClassDef *cd=0;
while (
(si=scope.find("::",pi))!=-1 && !getClass(scope.left(si)+templ) &&
((cd=getClass(scope.left(si)))==0 || cd->templateArguments()==0)
)
{
//printf("Tried `%s'\n",(scope.left(si)+templ).data());
pi=si+2;
}
if (si==-1) // not nested => append template specifier
{
result+=templ;
}
else // nested => insert template specifier before after first class name
{
result=scope.left(si) + templ + scope.right(scope.length()-si);
}
}
//printf("insertTemplateSpecifierInScope(`%s',`%s')=%s\n",
// scope.data(),templ.data(),result.data());
return result;
}
int isAccessibleFrom ( Definition scope,
FileDef fileScope,
Definition item 
)

Definition at line 948 of file util.cpp.

References accessibleViaUsingClass(), accessibleViaUsingNamespace(), DefinitionIntf::definitionType(), AccessStack::find(), Definition::getOuterScope(), NamespaceDef::getUsedClasses(), FileDef::getUsedClasses(), NamespaceDef::getUsedNamespaces(), FileDef::getUsedNamespaces(), Doxygen::globalScope, isAccessibleFrom(), AccessStack::pop(), AccessStack::push(), DefinitionIntf::TypeClass, DefinitionIntf::TypeMember, and DefinitionIntf::TypeNamespace.

Referenced by isAccessibleFrom(), isAccessibleFromWithExpScope(), and resolveTypeDef().

{
//printf("<isAccesibleFrom(scope=%s,item=%s itemScope=%s)\n",
// scope->name().data(),item->name().data(),item->getOuterScope()->name().data());
static AccessStack accessStack;
if (accessStack.find(scope,fileScope,item))
{
return -1;
}
accessStack.push(scope,fileScope,item);
int result=0; // assume we found it
int i;
Definition *itemScope=item->getOuterScope();
bool memberAccessibleFromScope =
(item->definitionType()==Definition::TypeMember && // a member
itemScope && itemScope->definitionType()==Definition::TypeClass && // of a class
scope->definitionType()==Definition::TypeClass && // accessible
((ClassDef*)scope)->isAccessibleMember((MemberDef *)item) // from scope
);
bool nestedClassInsideBaseClass =
(item->definitionType()==Definition::TypeClass && // a nested class
itemScope && itemScope->definitionType()==Definition::TypeClass && // inside a base
scope->definitionType()==Definition::TypeClass && // class of scope
((ClassDef*)scope)->isBaseClass((ClassDef*)itemScope,TRUE)
);
if (itemScope==scope || memberAccessibleFromScope || nestedClassInsideBaseClass)
{
//printf("> found it\n");
if (nestedClassInsideBaseClass) result++; // penalty for base class to prevent
// this is preferred over nested class in this class
// see bug 686956
}
else if (scope==Doxygen::globalScope)
{
if (fileScope)
{
SDict<Definition> *cl = fileScope->getUsedClasses();
if (accessibleViaUsingClass(cl,fileScope,item))
{
//printf("> found via used class\n");
goto done;
}
NamespaceSDict *nl = fileScope->getUsedNamespaces();
if (accessibleViaUsingNamespace(nl,fileScope,item))
{
//printf("> found via used namespace\n");
goto done;
}
}
//printf("> reached global scope\n");
result=-1; // not found in path to globalScope
}
else // keep searching
{
// check if scope is a namespace, which is using other classes and namespaces
{
NamespaceDef *nscope = (NamespaceDef*)scope;
//printf(" %s is namespace with %d used classes\n",nscope->name().data(),nscope->getUsedClasses());
if (accessibleViaUsingClass(cl,fileScope,item))
{
//printf("> found via used class\n");
goto done;
}
if (accessibleViaUsingNamespace(nl,fileScope,item))
{
//printf("> found via used namespace\n");
goto done;
}
}
// repeat for the parent scope
i=isAccessibleFrom(scope->getOuterScope(),fileScope,item);
//printf("> result=%d\n",i);
result= (i==-1) ? -1 : i+2;
}
done:
accessStack.pop();
//Doxygen::lookupCache.insert(key,new int(result));
return result;
}
int isAccessibleFromWithExpScope ( Definition scope,
FileDef fileScope,
Definition item,
const QCString &  explicitScopePart 
)

Definition at line 1051 of file util.cpp.

References accessibleViaUsingNamespace(), DefinitionIntf::definitionType(), AccessStack::find(), followPath(), g_visitedNamespaces, Definition::getOuterScope(), NamespaceDef::getUsedClasses(), NamespaceDef::getUsedNamespaces(), FileDef::getUsedNamespaces(), Doxygen::globalScope, isAccessibleFrom(), isAccessibleFromWithExpScope(), SDict< NamespaceDef >::Iterator, Definition::name(), AccessStack::pop(), AccessStack::push(), DefinitionIntf::TypeClass, and DefinitionIntf::TypeNamespace.

Referenced by getMemberFromSymbol(), getResolvedSymbol(), isAccessibleFromWithExpScope(), and substTypedef().

{
if (explicitScopePart.isEmpty())
{
// handle degenerate case where there is no explicit scope.
return isAccessibleFrom(scope,fileScope,item);
}
static AccessStack accessStack;
if (accessStack.find(scope,fileScope,item,explicitScopePart))
{
return -1;
}
accessStack.push(scope,fileScope,item,explicitScopePart);
//printf(" <isAccessibleFromWithExpScope(%s,%s,%s)\n",scope?scope->name().data():"<global>",
// item?item->name().data():"<none>",
// explicitScopePart.data());
int result=0; // assume we found it
Definition *newScope = followPath(scope,fileScope,explicitScopePart);
if (newScope) // explicitScope is inside scope => newScope is the result
{
Definition *itemScope = item->getOuterScope();
//printf(" scope traversal successful %s<->%s!\n",itemScope->name().data(),newScope->name().data());
//if (newScope && newScope->definitionType()==Definition::TypeClass)
//{
// ClassDef *cd = (ClassDef *)newScope;
// printf("---> Class %s: bases=%p\n",cd->name().data(),cd->baseClasses());
//}
if (itemScope==newScope) // exact match of scopes => distance==0
{
//printf("> found it\n");
}
else if (itemScope && newScope &&
((ClassDef*)newScope)->isBaseClass((ClassDef*)itemScope,TRUE,0)
)
{
// inheritance is also ok. Example: looking for B::I, where
// class A { public: class I {} };
// class B : public A {}
// but looking for B::I, where
// class A { public: class I {} };
// class B { public: class I {} };
// will find A::I, so we still prefer a direct match and give this one a distance of 1
result=1;
//printf("scope(%s) is base class of newScope(%s)\n",
// scope->name().data(),newScope->name().data());
}
else
{
int i=-1;
{
g_visitedNamespaces.insert(newScope->name(),newScope);
// this part deals with the case where item is a class
// A::B::C but is explicit referenced as A::C, where B is imported
// in A via a using directive.
//printf("newScope is a namespace: %s!\n",newScope->name().data());
NamespaceDef *nscope = (NamespaceDef*)newScope;
if (cl)
{
for (cli.toFirst();(cd=cli.current());++cli)
{
//printf("Trying for class %s\n",cd->name().data());
if (cd==item)
{
//printf("> class is used in this scope\n");
goto done;
}
}
}
if (nl)
{
for (nli.toFirst();(nd=nli.current());++nli)
{
if (g_visitedNamespaces.find(nd->name())==0)
{
//printf("Trying for namespace %s\n",nd->name().data());
i = isAccessibleFromWithExpScope(scope,fileScope,item,nd->name());
if (i!=-1)
{
//printf("> found via explicit scope of used namespace\n");
goto done;
}
}
}
}
}
// repeat for the parent scope
{
item,explicitScopePart);
}
//printf(" | result=%d\n",i);
result = (i==-1) ? -1 : i+2;
}
}
else // failed to resolve explicitScope
{
//printf(" failed to resolve: scope=%s\n",scope->name().data());
{
NamespaceDef *nscope = (NamespaceDef*)scope;
if (accessibleViaUsingNamespace(nl,fileScope,item,explicitScopePart))
{
//printf("> found in used namespace\n");
goto done;
}
}
{
if (fileScope)
{
NamespaceSDict *nl = fileScope->getUsedNamespaces();
if (accessibleViaUsingNamespace(nl,fileScope,item,explicitScopePart))
{
//printf("> found in used namespace\n");
goto done;
}
}
//printf("> not found\n");
result=-1;
}
else // continue by looking into the parent scope
{
int i=isAccessibleFromWithExpScope(scope->getOuterScope(),fileScope,
item,explicitScopePart);
//printf("> result=%d\n",i);
result= (i==-1) ? -1 : i+2;
}
}
done:
//printf(" > result=%d\n",result);
accessStack.pop();
//Doxygen::lookupCache.insert(key,new int(result));
return result;
}
static bool isLowerCase ( QCString &  s)
static

Definition at line 4552 of file util.cpp.

Referenced by resolveRef().

{
uchar *p=(uchar*)s.data();
if (p==0) return TRUE;
int c;
while ((c=*p++)) if (!islower(c)) return FALSE;
return TRUE;
}
QCString langToString ( SrcLangExt  lang)

Returns a string representation of lang.

Definition at line 8156 of file util.cpp.

References SrcLangExt_Cpp, SrcLangExt_CSharp, SrcLangExt_D, SrcLangExt_Fortran, SrcLangExt_IDL, SrcLangExt_Java, SrcLangExt_JS, SrcLangExt_Markdown, SrcLangExt_ObjC, SrcLangExt_PHP, SrcLangExt_Python, SrcLangExt_Tcl, SrcLangExt_Unknown, SrcLangExt_VHDL, and SrcLangExt_XML.

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

{
switch(lang)
{
case SrcLangExt_Unknown: return "Unknown";
case SrcLangExt_IDL: return "IDL";
case SrcLangExt_Java: return "Java";
case SrcLangExt_CSharp: return "C#";
case SrcLangExt_D: return "D";
case SrcLangExt_PHP: return "PHP";
case SrcLangExt_ObjC: return "Objective-C";
case SrcLangExt_Cpp: return "C++";
case SrcLangExt_JS: return "Javascript";
case SrcLangExt_Python: return "Python";
case SrcLangExt_Fortran: return "Fortran";
case SrcLangExt_VHDL: return "VHDL";
case SrcLangExt_XML: return "XML";
case SrcLangExt_Tcl: return "Tcl";
case SrcLangExt_Markdown: return "Markdown";
}
return "Unknown";
}
QCString latexEscapeIndexChars ( const char *  s,
bool  insideTabbing 
)

Definition at line 6769 of file util.cpp.

References filterLatexString(), and languages::tmp.

Referenced by LatexGenerator::addIndexItem(), FilterTexIndex::apply(), LatexGenerator::endTitleHead(), and LatexGenerator::startMemberDoc().

{
QGString result;
QCString tmp(qstrlen(s)+1);
FTextStream t(&result);
const char *p=s;
char c;
int i;
while ((c=*p++))
{
switch (c)
{
case '!': t << "\"!"; break;
case '"': t << "\"\""; break;
case '@': t << "\"@"; break;
case '|': t << "\\texttt{\"|}"; break;
case '[': t << "["; break;
case ']': t << "]"; break;
case '{': t << "\\lcurly{}"; break;
case '}': t << "\\rcurly{}"; break;
// NOTE: adding a case here, means adding it to while below as well!
default:
i=0;
// collect as long string as possible, before handing it to docify
tmp[i++]=c;
while ((c=*p) && c!='"' && c!='@' && c!='[' && c!=']' && c!='!' && c!='{' && c!='}' && c!='|')
{
tmp[i++]=c;
p++;
}
tmp[i]=0;
filterLatexString(t,tmp.data(),insideTabbing);
break;
}
}
return result.data();
}
QCString latexEscapeLabelName ( const char *  s,
bool  insideTabbing 
)

Definition at line 6733 of file util.cpp.

References filterLatexString(), and languages::tmp.

Referenced by LatexGenerator::addIndexItem(), FilterTexLabel::apply(), LatexGenerator::endTitleHead(), and LatexGenerator::startMemberDoc().

{
QGString result;
QCString tmp(qstrlen(s)+1);
FTextStream t(&result);
const char *p=s;
char c;
int i;
while ((c=*p++))
{
switch (c)
{
case '|': t << "\\texttt{\"|}"; break;
case '!': t << "\"!"; break;
case '%': t << "\\%"; break;
case '{': t << "\\lcurly{}"; break;
case '}': t << "\\rcurly{}"; break;
case '~': t << "````~"; break; // to get it a bit better in index together with other special characters
// NOTE: adding a case here, means adding it to while below as well!
default:
i=0;
// collect as long string as possible, before handing it to docify
tmp[i++]=c;
while ((c=*p) && c!='|' && c!='!' && c!='%' && c!='{' && c!='}' && c!='~')
{
tmp[i++]=c;
p++;
}
tmp[i]=0;
filterLatexString(t,tmp.data(),insideTabbing);
break;
}
}
return result.data();
}
QCString latexEscapePDFString ( const char *  s)

Definition at line 6807 of file util.cpp.

Referenced by LatexGenerator::startMemberDoc().

{
QGString result;
FTextStream t(&result);
const char *p=s;
char c;
while ((c=*p++))
{
switch (c)
{
case '\\': t << "\\textbackslash{}"; break;
case '{': t << "\\{"; break;
case '}': t << "\\}"; break;
case '_': t << "\\_"; break;
case '%': t << "\\%"; break;
case '&': t << "\\&"; break;
default:
t << c;
break;
}
}
return result.data();
}
bool leftScopeMatch ( const QCString &  scope,
const QCString &  name 
)

Definition at line 1981 of file util.cpp.

Referenced by addClassToContext(), buildFunctionList(), mergeScopes(), and substituteTemplateArgumentsInString().

{
int sl=scope.length();
int nl=name.length();
return (name==scope || // equal
(scope.left(nl)==name && // substring
sl>nl+1 && scope.at(nl)==':' && scope.at(nl+1)==':' // scope
)
);
}
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 8135 of file util.cpp.

Referenced by DocPara::handleInclude().

{
int result = 1;
int p=0,i;
bool found=FALSE;
// find the character positions of the first marker
int m1 = text.find(marker);
if (m1==-1) return result;
// find start line positions for the markers
while (!found && (i=text.find('\n',p))!=-1)
{
found = (p<=m1 && m1<i); // found the line with the start marker
p=i+1;
result++;
}
return result;
}
void linkifyText ( const TextGeneratorIntf out,
Definition scope,
FileDef fileScope,
Definition self,
const char *  text,
bool  autoBreak,
bool  external,
bool  keepSpaces,
int  indentLevel 
)

Definition at line 1993 of file util.cpp.

References MemberDef::anchor(), ClassDef::anchor(), DefinitionIntf::definitionType(), getClass(), getDefs(), Definition::getOuterScope(), MemberDef::getOutputFileBase(), ClassDef::getOutputFileBase(), MemberDef::getReference(), ClassDef::getReference(), getResolvedClass(), ClassDef::isLinkable(), MemberDef::isLinkable(), ClassDef::isLinkableInProject(), MemberDef::isLinkableInProject(), Definition::name(), substitute(), DefinitionIntf::TypeClass, DefinitionIntf::TypeNamespace, TextGeneratorIntf::writeBreak(), TextGeneratorIntf::writeLink(), and TextGeneratorIntf::writeString().

Referenced by createLinkedText(), generateDocbookForMember(), generateXMLForMember(), MemberDef::writeDeclaration(), writeDefArgumentList(), MemberDef::writeDocumentation(), writeExceptionListImpl(), MemberDef::writeMemberDocSimple(), writeTemplateArgumentList(), and writeTypeConstraints().

{
//printf("linkify=`%s'\n",text);
static QRegExp regExp("[a-z_A-Z\\x80-\\xFF][~!a-z_A-Z0-9$\\\\.:\\x80-\\xFF]*");
static QRegExp regExpSplit("(?!:),");
QCString txtStr=text;
int strLen = txtStr.length();
//printf("linkifyText scope=%s fileScope=%s strtxt=%s strlen=%d external=%d\n",
// scope?scope->name().data():"<none>",
// fileScope?fileScope->name().data():"<none>",
// txtStr.data(),strLen,external);
int matchLen;
int index=0;
int newIndex;
int skipIndex=0;
int floatingIndex=0;
if (strLen==0) return;
// read a word from the text string
while ((newIndex=regExp.match(txtStr,index,&matchLen))!=-1 &&
(newIndex==0 || !(txtStr.at(newIndex-1)>='0' && txtStr.at(newIndex-1)<='9')) // avoid matching part of hex numbers
)
{
// add non-word part to the result
floatingIndex+=newIndex-skipIndex+matchLen;
bool insideString=FALSE;
int i;
for (i=index;i<newIndex;i++)
{
if (txtStr.at(i)=='"') insideString=!insideString;
}
//printf("floatingIndex=%d strlen=%d autoBreak=%d\n",floatingIndex,strLen,autoBreak);
if (strLen>35 && floatingIndex>30 && autoBreak) // try to insert a split point
{
QCString splitText = txtStr.mid(skipIndex,newIndex-skipIndex);
int splitLength = splitText.length();
int offset=1;
i=splitText.find(regExpSplit,0);
if (i==-1) { i=splitText.find('<'); if (i!=-1) offset=0; }
if (i==-1) i=splitText.find('>');
if (i==-1) i=splitText.find(' ');
//printf("splitText=[%s] len=%d i=%d offset=%d\n",splitText.data(),splitLength,i,offset);
if (i!=-1) // add a link-break at i in case of Html output
{
out.writeString(splitText.left(i+offset),keepSpaces);
out.writeBreak(indentLevel==0 ? 0 : indentLevel+1);
out.writeString(splitText.right(splitLength-i-offset),keepSpaces);
floatingIndex=splitLength-i-offset+matchLen;
}
else
{
out.writeString(splitText,keepSpaces);
}
}
else
{
//ol.docify(txtStr.mid(skipIndex,newIndex-skipIndex));
out.writeString(txtStr.mid(skipIndex,newIndex-skipIndex),keepSpaces);
}
// get word from string
QCString word=txtStr.mid(newIndex,matchLen);
QCString matchWord = substitute(substitute(word,"\\","::"),".","::");
//printf("linkifyText word=%s matchWord=%s scope=%s\n",
// word.data(),matchWord.data(),scope?scope->name().data():"<none>");
bool found=FALSE;
if (!insideString)
{
ClassDef *cd=0;
FileDef *fd=0;
MemberDef *md=0;
NamespaceDef *nd=0;
GroupDef *gd=0;
//printf("** Match word '%s'\n",matchWord.data());
MemberDef *typeDef=0;
cd=getResolvedClass(scope,fileScope,matchWord,&typeDef);
if (typeDef) // First look at typedef then class, see bug 584184.
{
//printf("Found typedef %s\n",typeDef->name().data());
if (external ? typeDef->isLinkable() : typeDef->isLinkableInProject())
{
if (typeDef->getOuterScope()!=self)
{
out.writeLink(typeDef->getReference(),
typeDef->getOutputFileBase(),
typeDef->anchor(),
word);
found=TRUE;
}
}
}
if (!found && (cd || (cd=getClass(matchWord))))
{
//printf("Found class %s\n",cd->name().data());
// add link to the result
if (external ? cd->isLinkable() : cd->isLinkableInProject())
{
if (cd!=self)
{
out.writeLink(cd->getReference(),cd->getOutputFileBase(),cd->anchor(),word);
found=TRUE;
}
}
}
else if ((cd=getClass(matchWord+"-p"))) // search for Obj-C protocols as well
{
// add link to the result
if (external ? cd->isLinkable() : cd->isLinkableInProject())
{
if (cd!=self)
{
out.writeLink(cd->getReference(),cd->getOutputFileBase(),cd->anchor(),word);
found=TRUE;
}
}
}
// else if ((cd=getClass(matchWord+"-g"))) // C# generic as well
// {
// // add link to the result
// if (external ? cd->isLinkable() : cd->isLinkableInProject())
// {
// if (cd!=self)
// {
// out.writeLink(cd->getReference(),cd->getOutputFileBase(),cd->anchor(),word);
// found=TRUE;
// }
// }
// }
else
{
//printf(" -> nothing\n");
}
int m = matchWord.findRev("::");
QCString scopeName;
if (scope &&
)
)
{
scopeName=scope->name();
}
else if (m!=-1)
{
scopeName = matchWord.left(m);
matchWord = matchWord.mid(m+2);
}
//printf("ScopeName=%s\n",scopeName.data());
//if (!found) printf("Trying to link %s in %s\n",word.data(),scopeName.data());
if (!found &&
getDefs(scopeName,matchWord,0,md,cd,fd,nd,gd) &&
//(md->isTypedef() || md->isEnumerate() ||
// md->isReference() || md->isVariable()
//) &&
(external ? md->isLinkable() : md->isLinkableInProject())
)
{
//printf("Found ref scope=%s\n",d?d->name().data():"<global>");
//ol.writeObjectLink(d->getReference(),d->getOutputFileBase(),
// md->anchor(),word);
if (md!=self && (self==0 || md->name()!=self->name()))
// name check is needed for overloaded members, where getDefs just returns one
{
md->anchor(),word);
//printf("found symbol %s\n",matchWord.data());
found=TRUE;
}
}
}
if (!found) // add word to the result
{
out.writeString(word,keepSpaces);
}
// set next start point in the string
//printf("index=%d/%d\n",index,txtStr.length());
skipIndex=index=newIndex+matchLen;
}
// add last part of the string to the result.
//ol.docify(txtStr.right(txtStr.length()-skipIndex));
out.writeString(txtStr.right(txtStr.length()-skipIndex),keepSpaces);
}
QCString linkToText ( SrcLangExt  lang,
const char *  link,
bool  isFileName 
)

Definition at line 4744 of file util.cpp.

References getLanguageSpecificSeparator(), and substitute().

Referenced by DotCallGraph::buildGraph(), DocRef::DocRef(), DotCallGraph::DotCallGraph(), generateLink(), and handleLinkedWord().

{
//static bool optimizeOutputJava = Config_getBool(OPTIMIZE_OUTPUT_JAVA);
QCString result=link;
if (!result.isEmpty())
{
// replace # by ::
result=substitute(result,"#","::");
// replace . by ::
if (!isFileName && result.find('<')==-1) result=substitute(result,".","::");
// strip leading :: prefix if present
if (result.at(0)==':' && result.at(1)==':')
{
result=result.right(result.length()-2);
}
QCString sep = getLanguageSpecificSeparator(lang);
if (sep!="::")
{
result=substitute(result,"::",sep);
}
}
return result;
}
bool mainPageHasTitle ( )

Definition at line 8669 of file util.cpp.

References Doxygen::mainPage.

Referenced by mainPageHasOwnTitle(), PageContext::Private::title(), and writeIndex().

{
if (Doxygen::mainPage==0) return FALSE;
if (Doxygen::mainPage->title().isEmpty()) return FALSE;
if (Doxygen::mainPage->title().lower()=="notitle") return FALSE;
return TRUE;
}
static bool matchArgument ( const Argument srcA,
const Argument dstA,
const QCString &  className,
const QCString &  namespaceName,
NamespaceSDict usingNamespaces,
SDict< Definition > *  usingClasses 
)
static

Definition at line 3010 of file util.cpp.

References Argument::array, ClassDef::baseClasses(), SDict< T >::count(), getClass(), isId(), SDict< NamespaceDef >::Iterator, MATCH, Argument::name, Definition::name(), NOMATCH, removeRedundantWhiteSpace(), stripIrrelevantConstVolatile(), trimBaseClassScope(), trimScope(), trimTemplateSpecifiers(), and Argument::type.

Referenced by matchArguments().

{
//printf("match argument start `%s|%s' <-> `%s|%s' using nsp=%p class=%p\n",
// srcA->type.data(),srcA->name.data(),
// dstA->type.data(),dstA->name.data(),
// usingNamespaces,
// usingClasses);
// TODO: resolve any typedefs names that are part of srcA->type
// before matching. This should use className and namespaceName
// and usingNamespaces and usingClass to determine which typedefs
// are in-scope, so it will not be very efficient :-(
QCString srcAType=trimTemplateSpecifiers(namespaceName,className,srcA->type);
QCString dstAType=trimTemplateSpecifiers(namespaceName,className,dstA->type);
QCString srcAName=srcA->name.stripWhiteSpace();
QCString dstAName=dstA->name.stripWhiteSpace();
srcAType.stripPrefix("class ");
dstAType.stripPrefix("class ");
// allow distinguishing "const A" from "const B" even though
// from a syntactic point of view they would be two names of the same
// type "const". This is not fool prove of course, but should at least
// catch the most common cases.
if ((srcAType=="const" || srcAType=="volatile") && !srcAName.isEmpty())
{
srcAType+=" ";
srcAType+=srcAName;
}
if ((dstAType=="const" || dstAType=="volatile") && !dstAName.isEmpty())
{
dstAType+=" ";
dstAType+=dstAName;
}
if (srcAName=="const" || srcAName=="volatile")
{
srcAType+=srcAName;
srcAName.resize(0);
}
else if (dstA->name=="const" || dstA->name=="volatile")
{
dstAType+=dstA->name;
dstAName.resize(0);
}
// strip typename keyword
if (qstrncmp(srcAType,"typename ",9)==0)
{
srcAType = srcAType.right(srcAType.length()-9);
}
if (qstrncmp(dstAType,"typename ",9)==0)
{
dstAType = dstAType.right(dstAType.length()-9);
}
srcAType = removeRedundantWhiteSpace(srcAType);
dstAType = removeRedundantWhiteSpace(dstAType);
//srcAType=stripTemplateSpecifiersFromScope(srcAType,FALSE);
//dstAType=stripTemplateSpecifiersFromScope(dstAType,FALSE);
//printf("srcA=`%s|%s' dstA=`%s|%s'\n",srcAType.data(),srcAName.data(),
// dstAType.data(),dstAName.data());
if (srcA->array!=dstA->array) // nomatch for char[] against char
{
return FALSE;
}
if (srcAType!=dstAType) // check if the argument only differs on name
{
// remove a namespace scope that is only in one type
// (assuming a using statement was used)
//printf("Trimming %s<->%s: %s\n",srcAType.data(),dstAType.data(),namespaceName.data());
//trimNamespaceScope(srcAType,dstAType,namespaceName);
//printf("After Trimming %s<->%s\n",srcAType.data(),dstAType.data());
//QCString srcScope;
//QCString dstScope;
// strip redundant scope specifiers
if (!className.isEmpty())
{
srcAType=trimScope(className,srcAType);
dstAType=trimScope(className,dstAType);
//printf("trimScope: `%s' <=> `%s'\n",srcAType.data(),dstAType.data());
ClassDef *cd;
if (!namespaceName.isEmpty())
cd=getClass(namespaceName+"::"+className);
else
cd=getClass(className);
if (cd && cd->baseClasses())
{
trimBaseClassScope(cd->baseClasses(),srcAType);
trimBaseClassScope(cd->baseClasses(),dstAType);
}
//printf("trimBaseClassScope: `%s' <=> `%s'\n",srcAType.data(),dstAType.data());
}
if (!namespaceName.isEmpty())
{
srcAType=trimScope(namespaceName,srcAType);
dstAType=trimScope(namespaceName,dstAType);
}
//printf("#usingNamespace=%d\n",usingNamespaces->count());
if (usingNamespaces && usingNamespaces->count()>0)
{
NamespaceSDict::Iterator nli(*usingNamespaces);
for (;(nd=nli.current());++nli)
{
srcAType=trimScope(nd->name(),srcAType);
dstAType=trimScope(nd->name(),dstAType);
}
}
//printf("#usingClasses=%d\n",usingClasses->count());
if (usingClasses && usingClasses->count()>0)
{
SDict<Definition>::Iterator cli(*usingClasses);
for (;(cd=cli.current());++cli)
{
srcAType=trimScope(cd->name(),srcAType);
dstAType=trimScope(cd->name(),dstAType);
}
}
//printf("2. srcA=%s|%s dstA=%s|%s\n",srcAType.data(),srcAName.data(),
// dstAType.data(),dstAName.data());
if (!srcAName.isEmpty() && !dstA->type.isEmpty() &&
(srcAType+" "+srcAName)==dstAType)
{
return TRUE;
}
else if (!dstAName.isEmpty() && !srcA->type.isEmpty() &&
(dstAType+" "+dstAName)==srcAType)
{
return TRUE;
}
uint srcPos=0,dstPos=0;
bool equal=TRUE;
while (srcPos<srcAType.length() && dstPos<dstAType.length() && equal)
{
equal=srcAType.at(srcPos)==dstAType.at(dstPos);
if (equal) srcPos++,dstPos++;
}
uint srcATypeLen=srcAType.length();
uint dstATypeLen=dstAType.length();
if (srcPos<srcATypeLen && dstPos<dstATypeLen)
{
// if nothing matches or the match ends in the middle or at the
// end of a string then there is no match
if (srcPos==0 || dstPos==0)
{
return FALSE;
}
if (isId(srcAType.at(srcPos)) && isId(dstAType.at(dstPos)))
{
//printf("partial match srcPos=%d dstPos=%d!\n",srcPos,dstPos);
// check if a name if already found -> if no then there is no match
if (!srcAName.isEmpty() || !dstAName.isEmpty())
{
return FALSE;
}
// types only
while (srcPos<srcATypeLen && isId(srcAType.at(srcPos))) srcPos++;
while (dstPos<dstATypeLen && isId(dstAType.at(dstPos))) dstPos++;
if (srcPos<srcATypeLen ||
dstPos<dstATypeLen ||
(srcPos==srcATypeLen && dstPos==dstATypeLen)
)
{
return FALSE;
}
}
else
{
// otherwise we assume that a name starts at the current position.
while (srcPos<srcATypeLen && isId(srcAType.at(srcPos))) srcPos++;
while (dstPos<dstATypeLen && isId(dstAType.at(dstPos))) dstPos++;
// if nothing more follows for both types then we assume we have
// found a match. Note that now `signed int' and `signed' match, but
// seeing that int is not a name can only be done by looking at the
// semantics.
if (srcPos!=srcATypeLen || dstPos!=dstATypeLen)
{
return FALSE;
}
}
}
else if (dstPos<dstAType.length())
{
if (!isspace((uchar)dstAType.at(dstPos))) // maybe the names differ
{
if (!dstAName.isEmpty()) // dst has its name separated from its type
{
return FALSE;
}
while (dstPos<dstAType.length() && isId(dstAType.at(dstPos))) dstPos++;
if (dstPos!=dstAType.length())
{
return FALSE; // more than a difference in name -> no match
}
}
else // maybe dst has a name while src has not
{
dstPos++;
while (dstPos<dstAType.length() && isId(dstAType.at(dstPos))) dstPos++;
if (dstPos!=dstAType.length() || !srcAName.isEmpty())
{
return FALSE; // nope not a name -> no match
}
}
}
else if (srcPos<srcAType.length())
{
if (!isspace((uchar)srcAType.at(srcPos))) // maybe the names differ
{
if (!srcAName.isEmpty()) // src has its name separated from its type
{
return FALSE;
}
while (srcPos<srcAType.length() && isId(srcAType.at(srcPos))) srcPos++;
if (srcPos!=srcAType.length())
{
return FALSE; // more than a difference in name -> no match
}
}
else // maybe src has a name while dst has not
{
srcPos++;
while (srcPos<srcAType.length() && isId(srcAType.at(srcPos))) srcPos++;
if (srcPos!=srcAType.length() || !dstAName.isEmpty())
{
return FALSE; // nope not a name -> no match
}
}
}
}
return TRUE;
}
static bool matchArgument2 ( Definition srcScope,
FileDef srcFileScope,
Argument srcA,
Definition dstScope,
FileDef dstFileScope,
Argument dstA 
)
static

Definition at line 3671 of file util.cpp.

References Argument::canType, extractCanonicalArgType(), MATCH, Argument::name, NOMATCH, stripIrrelevantConstVolatile(), and Argument::type.

Referenced by matchArguments2().

{
//printf(">> match argument: %s::`%s|%s' (%s) <-> %s::`%s|%s' (%s)\n",
// srcScope ? srcScope->name().data() : "",
// srcA->type.data(),srcA->name.data(),srcA->canType.data(),
// dstScope ? dstScope->name().data() : "",
// dstA->type.data(),dstA->name.data(),dstA->canType.data());
//if (srcA->array!=dstA->array) // nomatch for char[] against char
//{
// NOMATCH
// return FALSE;
//}
QCString sSrcName = " "+srcA->name;
QCString sDstName = " "+dstA->name;
QCString srcType = srcA->type;
QCString dstType = dstA->type;
//printf("'%s'<->'%s'\n",sSrcName.data(),dstType.right(sSrcName.length()).data());
//printf("'%s'<->'%s'\n",sDstName.data(),srcType.right(sDstName.length()).data());
if (sSrcName==dstType.right(sSrcName.length()))
{ // case "unsigned int" <-> "unsigned int i"
srcA->type+=sSrcName;
srcA->name="";
srcA->canType=""; // invalidate cached type value
}
else if (sDstName==srcType.right(sDstName.length()))
{ // case "unsigned int i" <-> "unsigned int"
dstA->type+=sDstName;
dstA->name="";
dstA->canType=""; // invalidate cached type value
}
if (srcA->canType.isEmpty())
{
srcA->canType = extractCanonicalArgType(srcScope,srcFileScope,srcA);
}
if (dstA->canType.isEmpty())
{
dstA->canType = extractCanonicalArgType(dstScope,dstFileScope,dstA);
}
if (srcA->canType==dstA->canType)
{
return TRUE;
}
else
{
//printf(" Canonical types do not match [%s]<->[%s]\n",
// srcA->canType.data(),dstA->canType.data());
return FALSE;
}
}
bool matchArguments ( ArgumentList srcAl,
ArgumentList dstAl,
const char *  cl,
const char *  ns,
bool  checkCV,
NamespaceSDict usingNamespaces,
SDict< Definition > *  usingClasses 
)

Matches the arguments list srcAl with the argument list dstAl Returns TRUE if the argument lists are equal. Two argument list are considered equal if the number of arguments is equal and the types of all arguments are equal. Furthermore the const and volatile specifiers stored in the list should be equal.

Definition at line 3285 of file util.cpp.

References ArgumentList::constSpecifier, MATCH, matchArgument(), NOMATCH, Argument::type, and ArgumentList::volatileSpecifier.

{
QCString className=cl;
QCString namespaceName=ns;
// strip template specialization from class name if present
//int til=className.find('<'),tir=className.find('>');
//if (til!=-1 && tir!=-1 && tir>til)
//{
// className=className.left(til)+className.right(className.length()-tir-1);
//}
//printf("matchArguments(%s,%s) className=%s namespaceName=%s checkCV=%d usingNamespaces=%d usingClasses=%d\n",
// srcAl ? argListToString(srcAl).data() : "",
// dstAl ? argListToString(dstAl).data() : "",
// cl,ns,checkCV,
// usingNamespaces?usingNamespaces->count():0,
// usingClasses?usingClasses->count():0
// );
if (srcAl==0 || dstAl==0)
{
bool match = srcAl==dstAl; // at least one of the members is not a function
if (match)
{
return TRUE;
}
else
{
return FALSE;
}
}
// handle special case with void argument
if ( srcAl->count()==0 && dstAl->count()==1 &&
dstAl->getFirst()->type=="void" )
{ // special case for finding match between func() and func(void)
a->type = "void";
srcAl->append(a);
return TRUE;
}
if ( dstAl->count()==0 && srcAl->count()==1 &&
srcAl->getFirst()->type=="void" )
{ // special case for finding match between func(void) and func()
a->type = "void";
dstAl->append(a);
return TRUE;
}
if (srcAl->count() != dstAl->count())
{
return FALSE; // different number of arguments -> no match
}
if (checkCV)
{
if (srcAl->constSpecifier != dstAl->constSpecifier)
{
return FALSE; // one member is const, the other not -> no match
}
if (srcAl->volatileSpecifier != dstAl->volatileSpecifier)
{
return FALSE; // one member is volatile, the other not -> no match
}
}
// so far the argument list could match, so we need to compare the types of
// all arguments.
ArgumentListIterator srcAli(*srcAl),dstAli(*dstAl);
Argument *srcA,*dstA;
for (;(srcA=srcAli.current()) && (dstA=dstAli.current());++srcAli,++dstAli)
{
if (!matchArgument(srcA,dstA,className,namespaceName,
usingNamespaces,usingClasses))
{
return FALSE;
}
}
return TRUE; // all arguments match
}
bool matchArguments2 ( Definition srcScope,
FileDef srcFileScope,
ArgumentList srcAl,
Definition dstScope,
FileDef dstFileScope,
ArgumentList dstAl,
bool  checkCV 
)

Definition at line 3733 of file util.cpp.

References ArgumentList::constSpecifier, MATCH, matchArgument2(), NOMATCH, Argument::type, and ArgumentList::volatileSpecifier.

Referenced by addMemberDocs(), buildFunctionList(), combineDeclarationAndDefinition(), computeMemberRelations(), findFriends(), findGlobalMember(), findMember(), findMembersWithSpecificName(), getDefs(), GroupDef::insertMember(), ClassDef::mergeMembers(), transferFunctionReferences(), and transferRelatedFunctionDocumentation().

{
//printf("*** matchArguments2\n");
ASSERT(srcScope!=0 && dstScope!=0);
if (srcAl==0 || dstAl==0)
{
bool match = srcAl==dstAl; // at least one of the members is not a function
if (match)
{
return TRUE;
}
else
{
return FALSE;
}
}
// handle special case with void argument
if ( srcAl->count()==0 && dstAl->count()==1 &&
dstAl->getFirst()->type=="void" )
{ // special case for finding match between func() and func(void)
a->type = "void";
srcAl->append(a);
return TRUE;
}
if ( dstAl->count()==0 && srcAl->count()==1 &&
srcAl->getFirst()->type=="void" )
{ // special case for finding match between func(void) and func()
a->type = "void";
dstAl->append(a);
return TRUE;
}
if (srcAl->count() != dstAl->count())
{
return FALSE; // different number of arguments -> no match
}
if (checkCV)
{
if (srcAl->constSpecifier != dstAl->constSpecifier)
{
return FALSE; // one member is const, the other not -> no match
}
if (srcAl->volatileSpecifier != dstAl->volatileSpecifier)
{
return FALSE; // one member is volatile, the other not -> no match
}
}
// so far the argument list could match, so we need to compare the types of
// all arguments.
ArgumentListIterator srcAli(*srcAl),dstAli(*dstAl);
Argument *srcA,*dstA;
for (;(srcA=srcAli.current()) && (dstA=dstAli.current());++srcAli,++dstAli)
{
if (!matchArgument2(srcScope,srcFileScope,srcA,
dstScope,dstFileScope,dstA)
)
{
return FALSE;
}
}
return TRUE; // all arguments match
}
void mergeArguments ( ArgumentList srcAl,
ArgumentList dstAl,
bool  forceNameOverwrite 
)

Definition at line 3818 of file util.cpp.

References Argument::defval, Argument::docs, Argument::name, and Argument::type.

Referenced by addMemberDocs(), buildFunctionList(), and findFriends().

{
//printf("mergeArguments `%s', `%s'\n",
// argListToString(srcAl).data(),argListToString(dstAl).data());
if (srcAl==0 || dstAl==0 || srcAl->count()!=dstAl->count())
{
return; // invalid argument lists -> do not merge
}
ArgumentListIterator srcAli(*srcAl),dstAli(*dstAl);
Argument *srcA,*dstA;
for (;(srcA=srcAli.current()) && (dstA=dstAli.current());++srcAli,++dstAli)
{
if (srcA->defval.isEmpty() && !dstA->defval.isEmpty())
{
//printf("Defval changing `%s'->`%s'\n",srcA->defval.data(),dstA->defval.data());
srcA->defval=dstA->defval.copy();
}
else if (!srcA->defval.isEmpty() && dstA->defval.isEmpty())
{
//printf("Defval changing `%s'->`%s'\n",dstA->defval.data(),srcA->defval.data());
dstA->defval=srcA->defval.copy();
}
// fix wrongly detected const or volatile specifiers before merging.
// example: "const A *const" is detected as type="const A *" name="const"
if (srcA->name=="const" || srcA->name=="volatile")
{
srcA->type+=" "+srcA->name;
srcA->name.resize(0);
}
if (dstA->name=="const" || dstA->name=="volatile")
{
dstA->type+=" "+dstA->name;
dstA->name.resize(0);
}
if (srcA->type==dstA->type)
{
//printf("1. merging %s:%s <-> %s:%s\n",srcA->type.data(),srcA->name.data(),dstA->type.data(),dstA->name.data());
if (srcA->name.isEmpty() && !dstA->name.isEmpty())
{
//printf("type: `%s':=`%s'\n",srcA->type.data(),dstA->type.data());
//printf("name: `%s':=`%s'\n",srcA->name.data(),dstA->name.data());
srcA->type = dstA->type.copy();
srcA->name = dstA->name.copy();
}
else if (!srcA->name.isEmpty() && dstA->name.isEmpty())
{
//printf("type: `%s':=`%s'\n",dstA->type.data(),srcA->type.data());
//printf("name: `%s':=`%s'\n",dstA->name.data(),srcA->name.data());
dstA->type = srcA->type.copy();
dstA->name = dstA->name.copy();
}
else if (!srcA->name.isEmpty() && !dstA->name.isEmpty())
{
//printf("srcA->name=%s dstA->name=%s\n",srcA->name.data(),dstA->name.data());
if (forceNameOverwrite)
{
srcA->name = dstA->name;
}
else
{
if (srcA->docs.isEmpty() && !dstA->docs.isEmpty())
{
srcA->name = dstA->name;
}
else if (!srcA->docs.isEmpty() && dstA->docs.isEmpty())
{
dstA->name = srcA->name;
}
}
}
}
else
{
//printf("2. merging '%s':'%s' <-> '%s':'%s'\n",srcA->type.data(),srcA->name.data(),dstA->type.data(),dstA->name.data());
srcA->type=srcA->type.stripWhiteSpace();
dstA->type=dstA->type.stripWhiteSpace();
if (srcA->type+" "+srcA->name==dstA->type) // "unsigned long:int" <-> "unsigned long int:bla"
{
srcA->type+=" "+srcA->name;
srcA->name=dstA->name;
}
else if (dstA->type+" "+dstA->name==srcA->type) // "unsigned long int bla" <-> "unsigned long int"
{
dstA->type+=" "+dstA->name;
dstA->name=srcA->name;
}
else if (srcA->name.isEmpty() && !dstA->name.isEmpty())
{
srcA->name = dstA->name;
}
else if (dstA->name.isEmpty() && !srcA->name.isEmpty())
{
dstA->name = srcA->name;
}
}
int i1=srcA->type.find("::"),
i2=dstA->type.find("::"),
j1=srcA->type.length()-i1-2,
j2=dstA->type.length()-i2-2;
if (i1!=-1 && i2==-1 && srcA->type.right(j1)==dstA->type)
{
//printf("type: `%s':=`%s'\n",dstA->type.data(),srcA->type.data());
//printf("name: `%s':=`%s'\n",dstA->name.data(),srcA->name.data());
dstA->type = srcA->type.left(i1+2)+dstA->type;
dstA->name = dstA->name.copy();
}
else if (i1==-1 && i2!=-1 && dstA->type.right(j2)==srcA->type)
{
//printf("type: `%s':=`%s'\n",srcA->type.data(),dstA->type.data());
//printf("name: `%s':=`%s'\n",dstA->name.data(),srcA->name.data());
srcA->type = dstA->type.left(i2+2)+srcA->type;
srcA->name = dstA->name.copy();
}
if (srcA->docs.isEmpty() && !dstA->docs.isEmpty())
{
srcA->docs = dstA->docs.copy();
}
else if (dstA->docs.isEmpty() && !srcA->docs.isEmpty())
{
dstA->docs = srcA->docs.copy();
}
//printf("Merge argument `%s|%s' `%s|%s'\n",
// srcA->type.data(),srcA->name.data(),
// dstA->type.data(),dstA->name.data());
}
}
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 6373 of file util.cpp.

References leftScopeMatch().

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

{
// case leftScope=="A" rightScope=="A::B" => result = "A::B"
if (leftScopeMatch(rightScope,leftScope)) return rightScope;
QCString result;
int i=0,p=leftScope.length();
// case leftScope=="A::B" rightScope=="B::C" => result = "A::B::C"
// case leftScope=="A::B" rightScope=="B" => result = "A::B"
bool found=FALSE;
while ((i=leftScope.findRev("::",p))!=-1)
{
if (leftScopeMatch(rightScope,leftScope.right(leftScope.length()-i-2)))
{
result = leftScope.left(i+2)+rightScope;
found=TRUE;
}
p=i-1;
}
if (found) return result;
// case leftScope=="A" rightScope=="B" => result = "A::B"
result=leftScope.copy();
if (!result.isEmpty() && !rightScope.isEmpty()) result+="::";
result+=rightScope;
return result;
}
int minClassDistance ( const ClassDef cd,
const ClassDef bcd,
int  level 
)

Definition at line 2610 of file util.cpp.

References ClassDef::baseClasses(), ClassDef::categoryOf(), maxInheritanceDepth, minClassDistance(), Definition::name(), and warn_uncond().

Referenced by computeMemberRelations(), getDefs(), ClassDef::getMemberByName(), and minClassDistance().

{
if (bcd->categoryOf()) // use class that is being extended in case of
// an Objective-C category
{
bcd=bcd->categoryOf();
}
if (cd==bcd) return level;
if (level==256)
{
warn_uncond("class %s seem to have a recursive "
"inheritance relation!\n",cd->name().data());
return -1;
}
if (cd->baseClasses())
{
BaseClassDef *bcdi;
for (;(bcdi=bcli.current());++bcli)
{
int mc=minClassDistance(bcdi->classDef,bcd,level+1);
if (mc<m) m=mc;
if (m<0) break;
}
}
return m;
}
bool namespaceHasVisibleChild ( NamespaceDef nd,
bool  includeClasses 
)

Definition at line 8414 of file util.cpp.

References NamespaceDef::getClassSDict(), NamespaceDef::getNamespaceSDict(), SDict< NamespaceDef >::Iterator, SDict< ClassDef >::Iterator, and namespaceHasVisibleChild().

Referenced by NestingContext::Private::addNamespaces(), namespaceHasVisibleChild(), and writeNamespaceTree().

{
if (nd->getNamespaceSDict())
{
for (cnli.toFirst();(cnd=cnli.current());++cnli)
{
if (cnd->isLinkableInProject() && cnd->localName().find('@')==-1)
{
return TRUE;
}
else if (namespaceHasVisibleChild(cnd,includeClasses))
{
return TRUE;
}
}
}
if (includeClasses && nd->getClassSDict())
{
ClassDef *cd;
for (;(cd=cli.current());++cli)
{
if (cd->isLinkableInProject() && cd->templateMaster()==0)
{
return TRUE;
}
}
}
return FALSE;
}
ClassDef* newResolveTypedef ( FileDef fileScope,
MemberDef md,
MemberDef **  pMemType,
QCString *  pTemplSpec,
QCString *  pResolvedType,
ArgumentList actTemplParams 
)

Returns the class representing the value of the typedef represented by md within file fileScope.

Example: typedef A T; will return the class representing A if it is a class.

Example: typedef int T; will return 0, since "int" is not a class.

Definition at line 535 of file util.cpp.

References MemberDef::cacheTypedefVal(), g_resolvedTypedefs, MemberDef::getCachedResolvedTypedef(), MemberDef::getCachedTypedefTemplSpec(), MemberDef::getCachedTypedefVal(), MemberDef::getClassDef(), Definition::getDefFileName(), Definition::getOuterScope(), getResolvedClassRec(), ClassDef::isTemplate(), MemberDef::isTypedefValCached(), newResolveTypedef(), MemberDef::qualifiedName(), Definition::qualifiedName(), stripTemplateSpecifiersFromScope(), substituteTemplateArgumentsInString(), ClassDef::templateArguments(), and MemberDef::typeString().

Referenced by followPath(), getResolvedSymbol(), and newResolveTypedef().

{
//printf("newResolveTypedef(md=%p,cachedVal=%p)\n",md,md->getCachedTypedefVal());
bool isCached = md->isTypedefValCached(); // value already cached
if (isCached)
{
//printf("Already cached %s->%s [%s]\n",
// md->name().data(),
// md->getCachedTypedefVal()?md->getCachedTypedefVal()->name().data():"<none>",
// md->getCachedResolvedTypedef()?md->getCachedResolvedTypedef().data():"<none>");
if (pTemplSpec) *pTemplSpec = md->getCachedTypedefTemplSpec();
if (pResolvedType) *pResolvedType = md->getCachedResolvedTypedef();
return md->getCachedTypedefVal();
}
//printf("new typedef\n");
QCString qname = md->qualifiedName();
if (g_resolvedTypedefs.find(qname)) return 0; // typedef already done
g_resolvedTypedefs.insert(qname,md); // put on the trace list
ClassDef *typeClass = md->getClassDef();
QCString type = md->typeString(); // get the "value" of the typedef
if (typeClass && typeClass->isTemplate() &&
actTemplParams && actTemplParams->count()>0)
{
typeClass->templateArguments(),actTemplParams);
}
QCString typedefValue = type;
int tl=type.length();
int ip=tl-1; // remove * and & at the end
while (ip>=0 && (type.at(ip)=='*' || type.at(ip)=='&' || type.at(ip)==' '))
{
ip--;
}
type=type.left(ip+1);
type.stripPrefix("const "); // strip leading "const"
type.stripPrefix("struct "); // strip leading "struct"
type.stripPrefix("union "); // strip leading "union"
int sp=0;
tl=type.length(); // length may have been changed
while (sp<tl && type.at(sp)==' ') sp++;
MemberDef *memTypeDef = 0;
fileScope,type,&memTypeDef,0,pResolvedType);
// if type is a typedef then return what it resolves to.
if (memTypeDef && memTypeDef->isTypedef())
{
result=newResolveTypedef(fileScope,memTypeDef,pMemType,pTemplSpec);
goto done;
}
else if (memTypeDef && memTypeDef->isEnumerate() && pMemType)
{
*pMemType = memTypeDef;
}
//printf("type=%s result=%p\n",type.data(),result);
if (result==0)
{
// try unspecialized version if type is template
int si=type.findRev("::");
int i=type.find('<');
if (si==-1 && i!=-1) // typedef of a template => try the unspecialized version
{
if (pTemplSpec) *pTemplSpec = type.mid(i);
result = getResolvedClassRec(md->getOuterScope(),fileScope,
type.left(i),0,0,pResolvedType);
//printf("result=%p pRresolvedType=%s sp=%d ip=%d tl=%d\n",
// result,pResolvedType?pResolvedType->data():"<none>",sp,ip,tl);
}
else if (si!=-1) // A::B
{
i=type.find('<',si);
if (i==-1) // Something like A<T>::B => lookup A::B
{
i=type.length();
}
else // Something like A<T>::B<S> => lookup A::B, spec=<S>
{
if (pTemplSpec) *pTemplSpec = type.mid(i);
}
result = getResolvedClassRec(md->getOuterScope(),fileScope,
stripTemplateSpecifiersFromScope(type.left(i),FALSE),0,0,
pResolvedType);
}
//if (result) ip=si+sp+1;
}
done:
if (pResolvedType)
{
if (result)
{
*pResolvedType=result->qualifiedName();
//printf("*pResolvedType=%s\n",pResolvedType->data());
if (sp>0) pResolvedType->prepend(typedefValue.left(sp));
if (ip<tl-1) pResolvedType->append(typedefValue.right(tl-ip-1));
}
else
{
*pResolvedType=typedefValue;
}
}
// remember computed value for next time
if (result && result->getDefFileName()!="<code>")
// this check is needed to prevent that temporary classes that are
// introduced while parsing code fragments are being cached here.
{
//printf("setting cached typedef %p in result %p\n",md,result);
//printf("==> %s (%s,%d)\n",result->name().data(),result->getDefFileName().data(),result->getDefLine());
//printf("*pResolvedType=%s\n",pResolvedType?pResolvedType->data():"<none>");
md->cacheTypedefVal(result,
pTemplSpec ? *pTemplSpec : QCString(),
pResolvedType ? *pResolvedType : QCString()
);
}
g_resolvedTypedefs.remove(qname); // remove from the trace list
return result;
}
int nextUtf8CharPosition ( const QCString &  utf8Str,
int  len,
int  startPos 
)

Definition at line 7286 of file util.cpp.

Referenced by lastCharIsMultibyte(), and parseCommentAsText().

{
int bytes=1;
if (startPos>=len) return len;
char c = utf8Str[startPos];
if (c<0) // multibyte utf-8 character
{
if (((uchar)c&0xE0)==0xC0)
{
bytes++; // 11xx.xxxx: >=2 byte character
}
if (((uchar)c&0xF0)==0xE0)
{
bytes++; // 111x.xxxx: >=3 byte character
}
if (((uchar)c&0xF8)==0xF0)
{
bytes++; // 1111.xxxx: >=4 byte character
}
if (((uchar)c&0xFC)==0xF8)
{
bytes++; // 1111.1xxx: >=5 byte character
}
if (((uchar)c&0xFE)==0xFC)
{
bytes++; // 1111.1xxx: 6 byte character
}
}
else if (c=='&') // skip over character entities
{
static QRegExp re1("&#[0-9]+;"); // numerical entity
static QRegExp re2("&[A-Z_a-z]+;"); // named entity
int l1,l2;
int i1 = re1.match(utf8Str,startPos,&l1);
int i2 = re2.match(utf8Str,startPos,&l2);
if (i1!=-1)
{
bytes=l1;
}
else if (i2!=-1)
{
bytes=l2;
}
}
return startPos+bytes;
}
QCString normalizeNonTemplateArgumentsInString ( const QCString &  name,
Definition context,
const ArgumentList formalArgs 
)

Definition at line 6123 of file util.cpp.

References getResolvedClass(), Argument::name, Definition::name(), and removeRedundantWhiteSpace().

Referenced by findUsedClassesForClass().

{
// skip until <
int p=name.find('<');
if (p==-1) return name;
p++;
QCString result = name.left(p);
static QRegExp re("[a-z_A-Z\\x80-\\xFF][a-z_A-Z0-9\\x80-\\xFF]*");
int l,i;
// for each identifier in the template part (e.g. B<T> -> T)
while ((i=re.match(name,p,&l))!=-1)
{
result += name.mid(p,i-p);
QCString n = name.mid(i,l);
bool found=FALSE;
if (formalArgs) // check that n is not a formal template argument
{
ArgumentListIterator formAli(*formalArgs);
Argument *formArg;
for (formAli.toFirst();
(formArg=formAli.current()) && !found;
++formAli
)
{
found = formArg->name==n;
}
}
if (!found)
{
// try to resolve the type
ClassDef *cd = getResolvedClass(context,0,n);
if (cd)
{
result+=cd->name();
}
else
{
result+=n;
}
}
else
{
result+=n;
}
p=i+l;
}
result+=name.right(name.length()-p);
//printf("normalizeNonTemplateArgumentInString(%s)=%s\n",name.data(),result.data());
return removeRedundantWhiteSpace(result);
}
bool openOutputFile ( const char *  outFile,
QFile &  f 
)

Definition at line 8684 of file util.cpp.

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

{
bool fileOpened=FALSE;
bool writeToStdout=(outFile[0]=='-' && outFile[1]=='\0');
if (writeToStdout) // write to stdout
{
fileOpened = f.open(IO_WriteOnly,stdout);
}
else // write to file
{
QFileInfo fi(outFile);
if (fi.exists()) // create a backup
{
QDir dir=fi.dir();
QFileInfo backup(fi.fileName()+".bak");
if (backup.exists()) // remove existing backup
dir.remove(backup.fileName());
dir.rename(fi.fileName(),fi.fileName()+".bak");
}
f.setName(outFile);
fileOpened = f.open(IO_WriteOnly|IO_Translate);
}
return fileOpened;
}
QCString parseCommentAsText ( const Definition scope,
const MemberDef md,
const QCString &  doc,
const QCString &  fileName,
int  lineNr 
)

Definition at line 7333 of file util.cpp.

References DocNode::accept(), convertCharEntitiesToUTF8(), nextUtf8CharPosition(), and validatingParseDoc().

Referenced by Definition::briefDescriptionAsTooltip(), and formatBriefNote().

{
QGString s;
if (doc.isEmpty()) return s.data();
FTextStream t(&s);
DocNode *root = validatingParseDoc(fileName,lineNr,
(Definition*)scope,(MemberDef*)md,doc,FALSE,FALSE);
TextDocVisitor *visitor = new TextDocVisitor(t);
root->accept(visitor);
delete visitor;
delete root;
QCString result = convertCharEntitiesToUTF8(s.data());
int i=0;
int charCnt=0;
int l=result.length();
bool addEllipsis=FALSE;
while ((i=nextUtf8CharPosition(result,l,i))<l)
{
charCnt++;
if (charCnt>=80) break;
}
if (charCnt>=80) // try to truncate the string
{
while ((i=nextUtf8CharPosition(result,l,i))<l && charCnt<100)
{
charCnt++;
if (result.at(i)>=0 && isspace(result.at(i)))
{
addEllipsis=TRUE;
}
else if (result.at(i)==',' ||
result.at(i)=='.' ||
result.at(i)=='?')
{
break;
}
}
}
if (addEllipsis || charCnt==100) result=result.left(i)+"...";
return result.data();
}
bool patternMatch ( const QFileInfo &  fi,
const QStrList *  patList 
)

Definition at line 7875 of file util.cpp.

Referenced by readDir().

{
bool found=FALSE;
if (patList)
{
QStrListIterator it(*patList);
QCString pattern;
QCString fn = fi.fileName().data();
QCString fp = fi.filePath().data();
QCString afp= fi.absFilePath().data();
for (it.toFirst();(pattern=it.current());++it)
{
if (!pattern.isEmpty())
{
int i=pattern.find('=');
if (i!=-1) pattern=pattern.left(i); // strip of the extension specific filter name
#if defined(_WIN32) || defined(__MACOSX__) // Windows or MacOSX
QRegExp re(pattern,FALSE,TRUE); // case insensitive match
#else // unix
QRegExp re(pattern,TRUE,TRUE); // case sensitive match
#endif
found = re.match(fn)!=-1 ||
re.match(fp)!=-1 ||
re.match(afp)!=-1;
if (found) break;
//printf("Matching `%s' against pattern `%s' found=%d\n",
// fi->fileName().data(),pattern.data(),found);
}
}
}
return found;
}
bool protectionLevelVisible ( Protection  prot)
bool readInputFile ( const char *  fileName,
BufStr inBuf,
bool  filter,
bool  isSourceCode 
)

read a file name fileName and optionally filter and transcode it

Definition at line 7764 of file util.cpp.

References BufStr::addArray(), BufStr::addChar(), BufStr::at(), Config_getString, BufStr::curPos(), BufStr::data(), BufStr::dropFromStart(), err(), Debug::ExtCmd, filter(), filterCRLF(), Debug::FilterOutput, getFileFilter(), portable_pclose(), portable_popen(), Debug::print(), BufStr::shrink(), BufStr::skip(), and transcodeCharacterBuffer().

Referenced by fileToString(), and parseFile().

{
// try to open file
int size=0;
//uint oldPos = dest.curPos();
//printf(".......oldPos=%d\n",oldPos);
QFileInfo fi(fileName);
if (!fi.exists()) return FALSE;
QCString filterName = getFileFilter(fileName,isSourceCode);
if (filterName.isEmpty() || !filter)
{
QFile f(fileName);
if (!f.open(IO_ReadOnly))
{
err("could not open file %s\n",fileName);
return FALSE;
}
size=fi.size();
// read the file
inBuf.skip(size);
if (f.readBlock(inBuf.data()/*+oldPos*/,size)!=size)
{
err("problems while reading file %s\n",fileName);
return FALSE;
}
}
else
{
QCString cmd=filterName+" \""+fileName+"\"";
Debug::print(Debug::ExtCmd,0,"Executing popen(`%s`)\n",qPrint(cmd));
FILE *f=portable_popen(cmd,"r");
if (!f)
{
err("could not execute filter %s\n",filterName.data());
return FALSE;
}
const int bufSize=1024;
char buf[bufSize];
int numRead;
while ((numRead=(int)fread(buf,1,bufSize,f))>0)
{
//printf(">>>>>>>>Reading %d bytes\n",numRead);
inBuf.addArray(buf,numRead),size+=numRead;
}
inBuf.at(inBuf.curPos()) ='\0';
Debug::print(Debug::FilterOutput, 0, "Filter output\n");
Debug::print(Debug::FilterOutput,0,"-------------\n%s\n-------------\n",qPrint(inBuf));
}
int start=0;
if (size>=2 &&
((inBuf.at(0)==-1 && inBuf.at(1)==-2) || // Litte endian BOM
(inBuf.at(0)==-2 && inBuf.at(1)==-1) // big endian BOM
)
) // UCS-2 encoded file
{
transcodeCharacterBuffer(fileName,inBuf,inBuf.curPos(),
"UCS-2","UTF-8");
}
else if (size>=3 &&
(uchar)inBuf.at(0)==0xEF &&
(uchar)inBuf.at(1)==0xBB &&
(uchar)inBuf.at(2)==0xBF
) // UTF-8 encoded file
{
inBuf.dropFromStart(3); // remove UTF-8 BOM: no translation needed
}
else // transcode according to the INPUT_ENCODING setting
{
// do character transcoding if needed.
transcodeCharacterBuffer(fileName,inBuf,inBuf.curPos(),
Config_getString(INPUT_ENCODING),"UTF-8");
}
//inBuf.addChar('\n'); /* to prevent problems under Windows ? */
// and translate CR's
size=inBuf.curPos()-start;
int newSize=filterCRLF(inBuf.data()+start,size);
//printf("filter char at %p size=%d newSize=%d\n",dest.data()+oldPos,size,newSize);
if (newSize!=size) // we removed chars
{
inBuf.shrink(newSize); // resize the array
//printf(".......resizing from %d to %d result=[%s]\n",oldPos+size,oldPos+newSize,dest.data());
}
inBuf.addChar(0);
return TRUE;
}
bool recursivelyAddGroupListToTitle ( OutputList ol,
Definition d,
bool  root 
)

Definition at line 6581 of file util.cpp.

References OutputList::disableAllBut(), GroupDef::getOutputFileBase(), Definition::getReference(), GroupDef::groupTitle(), OutputGenerator::Html, Definition::partOfGroups(), OutputList::popGeneratorState(), OutputList::pushGeneratorState(), OutputList::writeObjectLink(), and OutputList::writeString().

Referenced by addGroupListToTitle().

{
GroupList *groups = d->partOfGroups();
if (groups) // write list of group to which this definition belongs
{
if (root)
{
ol.writeString("<div class=\"ingroups\">");
}
GroupListIterator gli(*groups);
GroupDef *gd;
bool first=true;
for (gli.toFirst();(gd=gli.current());++gli)
{
if (recursivelyAddGroupListToTitle(ol, gd, FALSE))
{
ol.writeString(" &raquo; ");
}
if (!first) { ol.writeString(" &#124; "); } else first=FALSE;
}
if (root)
{
ol.writeString("</div>");
}
return true;
}
return false;
}
QCString relativePathToRoot ( const char *  name)

Definition at line 5522 of file util.cpp.

References Config_getBool, and REL_PATH_TO_ROOT.

Referenced by generateBriefDoc(), generateDocbookForClass(), generateDocbookForDir(), generateDocbookForFile(), generateDocbookForGroup(), RTFGenerator::startFile(), LatexGenerator::startFile(), HtmlGenerator::startFile(), and validatingParseDoc().

{
QCString result;
if (Config_getBool(CREATE_SUBDIRS))
{
if (name==0)
{
}
else
{
QCString n = name;
int i = n.findRev('/');
if (i!=-1)
{
}
}
}
return result;
}
QCString removeAnonymousScopes ( const QCString &  s)

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

Referenced by createTagLessInstance(), ClassDef::displayName(), simplifyTypeForTable(), and MemberDef::writeDeclaration().

{
QCString result;
if (s.isEmpty()) return result;
static QRegExp re("[ :]*@[0-9]+[: ]*");
int i,l,sl=s.length();
int p=0;
while ((i=re.match(s,p,&l))!=-1)
{
result+=s.mid(p,i-p);
int c=i;
bool b1=FALSE,b2=FALSE;
while (c<i+l && s.at(c)!='@') if (s.at(c++)==':') b1=TRUE;
c=i+l-1;
while (c>=i && s.at(c)!='@') if (s.at(c--)==':') b2=TRUE;
if (b1 && b2)
{
result+="::";
}
p=i+l;
}
result+=s.right(sl-p);
//printf("removeAnonymousScopes(`%s')=`%s'\n",s.data(),result.data());
return result;
}
QCString removeRedundantWhiteSpace ( const QCString &  s)

Definition at line 1696 of file util.cpp.

References CharAroundSpace::CharElem::after, CharAroundSpace::CharElem::before, CharAroundSpace::charMap, Config_getBool, constScope, isId(), operatorScope, and virtualScope.

Referenced by addMethodToClass(), addVariable(), addVariableToClass(), argListToString(), buildFunctionList(), buildInterfaceAndServiceList(), extractCanonicalType(), findClassRelation(), findDocsForMemberOrCompound(), findMember(), findUsedClassesForClass(), findUsingDeclImports(), getCanonicalTypeForIdentifier(), getResolvedClassRec(), ClassDef::getVariableInstance(), MemberDefImpl::init(), ClassDef::insertTemplateInstance(), matchArgument(), normalizeNonTemplateArgumentsInString(), resolveRef(), tempArgListToString(), and writeExceptionListImpl().

{
static bool cliSupport = Config_getBool(CPP_CLI_SUPPORT);
static bool vhdl = Config_getBool(OPTIMIZE_OUTPUT_VHDL);
if (s.isEmpty() || vhdl) return s;
// We use a static character array to
// improve the performance of this function
static char *growBuf = 0;
static int growBufLen = 0;
if (s.length()*3>growBufLen) // For input character we produce at most 3 output characters,
{
growBufLen = s.length()*3;
growBuf = (char *)realloc(growBuf,growBufLen+1); // add 1 for 0-terminator
}
if (growBuf==0) return s; // should not happen, only we run out of memory
char *src=s.rawData();
char *dst=growBuf;
uint i=0;
uint l=s.length();
uint csp=0;
uint vsp=0;
uint osp=0;
char c;
char pc=0;
// skip leading whitespace
while (i<l && isspace((uchar)src[i]))
{
i++;
}
for (;i<l;i++)
{
c=src[i];
char nc=i<l-1 ? src[i+1] : ' ';
// search for "const"
if (csp<6 && c==constScope[csp] && // character matches substring "const"
(csp>0 || // inside search string
i==0 || // if it is the first character
!isId(pc) // the previous may not be a digit
)
)
csp++;
else // reset counter
csp=0;
// search for "virtual"
if (vsp<8 && c==virtualScope[vsp] && // character matches substring "virtual"
(vsp>0 || // inside search string
i==0 || // if it is the first character
!isId(pc) // the previous may not be a digit
)
)
vsp++;
else // reset counter
vsp=0;
// search for "operator"
if (osp<11 && (osp>=8 || c==operatorScope[osp]) && // character matches substring "operator" followed by 3 arbitrary characters
(osp>0 || // inside search string
i==0 || // if it is the first character
!isId(pc) // the previous may not be a digit
)
)
osp++;
else // reset counter
osp=0;
switch(c)
{
case '"': // quoted string
{
*dst++=c;
pc = c;
i++;
for (;i<l;i++) // find end of string
{
c = src[i];
*dst++=c;
if (c=='\\' && i+1<l)
{
pc = c;
i++;
c = src[i];
*dst+=c;
}
else if (c=='"')
{
break;
}
pc = c;
}
}
break;
case '<': // current char is a <
*dst++=c;
if (i<l-1 &&
(isId(nc)) && // next char is an id char
(osp<8) // string in front is not "operator"
)
{
*dst++=' '; // add extra space
}
break;
case '>': // current char is a >
if (i>0 && !isspace((uchar)pc) &&
(isId(pc) || pc=='*' || pc=='&' || pc=='.') && // prev char is an id char or space or *&.
(osp<8 || (osp==8 && pc!='-')) // string in front is not "operator>" or "operator->"
)
{
*dst++=' '; // add extra space in front
}
*dst++=c;
if (i<l-1 && (nc=='-' || nc=='&')) // '>-' -> '> -'
{
*dst++=' '; // add extra space after
}
break;
case ',': // current char is a ,
*dst++=c;
if (i>0 && !isspace((uchar)pc) &&
((i<l-1 && (isId(nc) || nc=='[')) || // the [ is for attributes (see bug702170)
(i<l-2 && nc=='$' && isId(src[i+2])) || // for PHP: ',$name' -> ', $name'
(i<l-3 && nc=='&' && src[i+2]=='$' && isId(src[i+3])) // for PHP: ',&$name' -> ', &$name'
)
)
{
*dst++=' '; // add extra space after
}
break;
case '^': // CLI 'Type^name' -> 'Type^ name'
case '%': // CLI 'Type%name' -> 'Type% name'
*dst++=c;
if (cliSupport && i<l-1 && (isId(nc) || nc=='-'))
{
*dst++=' '; // add extra space after
}
break;
case ')': // current char is a ) -> ')name' -> ') name'
*dst++=c;
if (i<l-1 && (isId(nc) || nc=='-'))
{
*dst++=' '; // add extra space after
}
break;
case '*':
if (i>0 && pc!=' ' && pc!='\t' && pc!=':' &&
pc!='*' && pc!='&' && pc!='(' && pc!='/' &&
pc!='.' && (osp<9 || (pc=='>' && osp==11)))
// avoid splitting &&, **, .*, operator*, operator->*
{
*dst++=' ';
}
*dst++=c;
break;
case '&':
if (i>0 && isId(pc))
{
*dst++=' ';
}
*dst++=c;
break;
case '@': // '@name' -> ' @name'
case '$': // '$name' -> ' $name'
case '\'': // ''name' -> '' name'
if (i>0 && i<l-1 && pc!='=' && pc!=':' && !isspace(pc) &&
isId(nc) && osp<8) // ")id" -> ") id"
{
*dst++=' ';
}
*dst++=c;
break;
case ':': // current char is a :
if (csp==6) // replace const::A by const ::A
{
*dst++=' ';
csp=0;
}
else if (vsp==8) // replace virtual::A by virtual ::A
{
*dst++=' ';
vsp=0;
}
*dst++=c;
break;
case ' ': // fallthrough
case '\n': // fallthrough
case '\t':
{
if (g_charAroundSpace.charMap[(uchar)pc].before &&
!(pc==',' && nc=='.'))
// remove spaces/tabs
{
*dst++=' ';
}
}
break;
default:
*dst++=c;
if (c=='t' && csp==5 && i<l-1 && // found 't' in 'const'
!(isId(nc) || nc==')' || nc==',' || isspace(nc))
) // prevent const ::A from being converted to const::A
{
*dst++=' ';
csp=0;
}
else if (c=='l' && vsp==7 && i<l-1 && // found 'l' in 'virtual'
!(isId(nc) || nc==')' || nc==',' || isspace(nc))
) // prevent virtual ::A from being converted to virtual::A
{
*dst++=' ';
vsp=0;
}
break;
}
pc=c;
}
*dst++='\0';
return growBuf;
}
static QCString replaceAliasArguments ( const QCString &  aliasValue,
const QCString &  argList 
)
static

Replaces the markers in an alias definition aliasValue with the corresponding values found in the comma separated argument list argList and the returns the result after recursive alias expansion.

Definition at line 7422 of file util.cpp.

References expandAliasRec(), findEndOfCommand(), Marker::number, Marker::pos, Marker::size, and substitute().

Referenced by expandAliasRec().

{
//printf("----- replaceAliasArguments(val=[%s],args=[%s])\n",aliasValue.data(),argList.data());
// first make a list of arguments from the comma separated argument list
QList<QCString> args;
args.setAutoDelete(TRUE);
int i,l=(int)argList.length();
int s=0;
for (i=0;i<l;i++)
{
char c = argList.at(i);
if (c==',' && (i==0 || argList.at(i-1)!='\\'))
{
args.append(new QCString(argList.mid(s,i-s)));
s=i+1; // start of next argument
}
else if (c=='@' || c=='\\')
{
// check if this is the start of another aliased command (see bug704172)
i+=findEndOfCommand(argList.data()+i+1);
}
}
if (l>s) args.append(new QCString(argList.right(l-s)));
//printf("found %d arguments\n",args.count());
// next we look for the positions of the markers and add them to a list
QList<Marker> markerList;
markerList.setAutoDelete(TRUE);
l = aliasValue.length();
int markerStart=0;
int markerEnd=0;
for (i=0;i<l;i++)
{
if (markerStart==0 && aliasValue.at(i)=='\\') // start of a \xx marker
{
markerStart=i+1;
}
else if (markerStart>0 && aliasValue.at(i)>='0' && aliasValue.at(i)<='9')
{
// read digit that make up the marker number
markerEnd=i+1;
}
else
{
if (markerStart>0 && markerEnd>markerStart) // end of marker
{
int markerLen = markerEnd-markerStart;
markerList.append(new Marker(markerStart-1, // include backslash
atoi(aliasValue.mid(markerStart,markerLen)),markerLen+1));
//printf("found marker at %d with len %d and number %d\n",
// markerStart-1,markerLen+1,atoi(aliasValue.mid(markerStart,markerLen)));
}
markerStart=0; // outside marker
markerEnd=0;
}
}
if (markerStart>0)
{
markerEnd=l;
}
if (markerStart>0 && markerEnd>markerStart)
{
int markerLen = markerEnd-markerStart;
markerList.append(new Marker(markerStart-1, // include backslash
atoi(aliasValue.mid(markerStart,markerLen)),markerLen+1));
//printf("found marker at %d with len %d and number %d\n",
// markerStart-1,markerLen+1,atoi(aliasValue.mid(markerStart,markerLen)));
}
// then we replace the markers with the corresponding arguments in one pass
QCString result;
int p=0;
for (i=0;i<(int)markerList.count();i++)
{
Marker *m = markerList.at(i);
result+=aliasValue.mid(p,m->pos-p);
//printf("part before marker %d: '%s'\n",i,aliasValue.mid(p,m->pos-p).data());
if (m->number>0 && m->number<=(int)args.count()) // valid number
{
result+=expandAliasRec(*args.at(m->number-1),TRUE);
//printf("marker index=%d pos=%d number=%d size=%d replacement %s\n",i,m->pos,m->number,m->size,
// args.at(m->number-1)->data());
}
p=m->pos+m->size; // continue after the marker
}
result+=aliasValue.right(l-p); // append remainder
//printf("string after replacement of markers: '%s'\n",result.data());
// expand the result again
result = substitute(result,"\\{","{");
result = substitute(result,"\\}","}");
result = expandAliasRec(substitute(result,"\\,",","));
return result;
}
QCString replaceAnonymousScopes ( const QCString &  s,
const char *  replacement 
)

Definition at line 191 of file util.cpp.

Referenced by generateDEFForMember().

{
QCString result;
if (s.isEmpty()) return result;
static QRegExp re("@[0-9]+");
int i,l,sl=s.length();
int p=0;
while ((i=re.match(s,p,&l))!=-1)
{
result+=s.mid(p,i-p);
if (replacement)
{
result+=replacement;
}
else
{
result+="__anonymous__";
}
p=i+l;
}
result+=s.right(sl-p);
//printf("replaceAnonymousScopes(`%s')=`%s'\n",s.data(),result.data());
return result;
}
QCString replaceColorMarkers ( const char *  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 8010 of file util.cpp.

References Config_getInt, HEXTONUM, and ColoredImage::hsl2rgb().

Referenced by ResourceMgr::copyResourceAs(), HtmlGenerator::writeSearchData(), HtmlGenerator::writeStyleInfo(), and HtmlGenerator::writeStyleSheetFile().

{
QCString result;
QCString s=str;
if (s.isEmpty()) return result;
static QRegExp re("##[0-9A-Fa-f][0-9A-Fa-f]");
static const char hex[] = "0123456789ABCDEF";
static int hue = Config_getInt(HTML_COLORSTYLE_HUE);
static int sat = Config_getInt(HTML_COLORSTYLE_SAT);
static int gamma = Config_getInt(HTML_COLORSTYLE_GAMMA);
int i,l,sl=s.length(),p=0;
while ((i=re.match(s,p,&l))!=-1)
{
result+=s.mid(p,i-p);
QCString lumStr = s.mid(i+2,l-2);
#define HEXTONUM(x) (((x)>='0' && (x)<='9') ? ((x)-'0') : \
((x)>='a' && (x)<='f') ? ((x)-'a'+10) : \
((x)>='A' && (x)<='F') ? ((x)-'A'+10) : 0)
double r,g,b;
int red,green,blue;
int level = HEXTONUM(lumStr[0])*16+HEXTONUM(lumStr[1]);
ColoredImage::hsl2rgb(hue/360.0,sat/255.0,
pow(level/255.0,gamma/100.0),&r,&g,&b);
red = (int)(r*255.0);
green = (int)(g*255.0);
blue = (int)(b*255.0);
char colStr[8];
colStr[0]='#';
colStr[1]=hex[red>>4];
colStr[2]=hex[red&0xf];
colStr[3]=hex[green>>4];
colStr[4]=hex[green&0xf];
colStr[5]=hex[blue>>4];
colStr[6]=hex[blue&0xf];
colStr[7]=0;
//printf("replacing %s->%s (level=%d)\n",lumStr.data(),colStr,level);
result+=colStr;
p=i+l;
}
result+=s.right(sl-p);
return result;
}
void replaceNamespaceAliases ( QCString &  scope,
int  i 
)

Definition at line 6892 of file util.cpp.

References Doxygen::namespaceAliasDict.

Referenced by findClassRelation(), findUsedClassesForClass(), getMemberFromSymbol(), and getResolvedClassRec().

{
while (i>0)
{
QCString ns = scope.left(i);
QCString *s = Doxygen::namespaceAliasDict[ns];
if (s)
{
scope=*s+scope.right(scope.length()-i);
i=s->length();
}
if (i>0 && ns==scope.left(i)) break;
}
}
QCString resolveAliasCmd ( const QCString  aliasCmd)

Definition at line 7653 of file util.cpp.

References expandAliasRec().

{
QCString result;
//printf("Expanding: '%s'\n",aliasCmd.data());
result = expandAliasRec(aliasCmd);
//printf("Expanding result: '%s'->'%s'\n",aliasCmd.data(),result.data());
return result;
}
bool resolveLink ( const char *  scName,
const char *  lr,
bool  ,
Definition **  resContext,
QCString &  resAnchor 
)

Definition at line 4838 of file util.cpp.

References MemberDef::anchor(), ClassDef::anchor(), SectionInfo::definition, Doxygen::directories, Doxygen::exampleSDict, findFileDef(), getClass(), PageDef::getGroupDef(), Doxygen::groupSDict, Doxygen::inputNameDict, DirDef::isLinkable(), FileDef::isLinkable(), SectionInfo::label, Definition::name(), Doxygen::namespaceSDict, Doxygen::pageSDict, resolveRef(), Doxygen::sectionDict, and stripTemplateSpecifiersFromScope().

Referenced by DocLink::DocLink(), DocRef::DocRef(), generateLink(), and LayoutNavEntry::url().

{
*resContext=0;
QCString linkRef=lr;
QCString linkRefWithoutTemplates = stripTemplateSpecifiersFromScope(linkRef,FALSE);
//printf("ResolveLink linkRef=%s\n",lr);
FileDef *fd;
GroupDef *gd;
PageDef *pd;
ClassDef *cd;
DirDef *dir;
SectionInfo *si=0;
bool ambig;
if (linkRef.isEmpty()) // no reference name!
{
return FALSE;
}
else if ((pd=Doxygen::pageSDict->find(linkRef))) // link to a page
{
GroupDef *gd = pd->getGroupDef();
if (gd)
{
if (!pd->name().isEmpty()) si=Doxygen::sectionDict->find(pd->name());
*resContext=gd;
if (si) resAnchor = si->label;
}
else
{
*resContext=pd;
}
return TRUE;
}
else if ((si=Doxygen::sectionDict->find(linkRef)))
{
*resContext=si->definition;
resAnchor = si->label;
return TRUE;
}
else if ((pd=Doxygen::exampleSDict->find(linkRef))) // link to an example
{
*resContext=pd;
return TRUE;
}
else if ((gd=Doxygen::groupSDict->find(linkRef))) // link to a group
{
*resContext=gd;
return TRUE;
}
else if ((fd=findFileDef(Doxygen::inputNameDict,linkRef,ambig)) // file link
&& fd->isLinkable())
{
*resContext=fd;
return TRUE;
}
else if ((cd=getClass(linkRef))) // class link
{
*resContext=cd;
resAnchor=cd->anchor();
return TRUE;
}
else if ((cd=getClass(linkRefWithoutTemplates))) // C#/Java generic class link
{
*resContext=cd;
resAnchor=cd->anchor();
return TRUE;
}
else if ((cd=getClass(linkRef+"-p"))) // Obj-C protocol link
{
*resContext=cd;
resAnchor=cd->anchor();
return TRUE;
}
// else if ((cd=getClass(linkRef+"-g"))) // C# generic link
// {
// *resContext=cd;
// resAnchor=cd->anchor();
// return TRUE;
// }
else if ((nd=Doxygen::namespaceSDict->find(linkRef)))
{
*resContext=nd;
return TRUE;
}
else if ((dir=Doxygen::directories->find(QFileInfo(linkRef).absFilePath().utf8()+"/"))
&& dir->isLinkable()) // TODO: make this location independent like filedefs
{
*resContext=dir;
return TRUE;
}
else // probably a member reference
{
MemberDef *md;
bool res = resolveRef(scName,lr,TRUE,resContext,&md);
if (md) resAnchor=md->anchor();
return res;
}
}
bool resolveRef ( const char *  scName,
const char *  name,
bool  inSeeBlock,
Definition **  resContext,
MemberDef **  resMember,
bool  lookForSpecialization,
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 4564 of file util.cpp.

References SDict< T >::find(), findFileDef(), findParameterList(), getClass(), getDefs(), Definition::getOuterScope(), getScopeDefs(), Doxygen::globalScope, Doxygen::groupSDict, Doxygen::inputNameDict, isLowerCase(), MemberDef::isStrongEnumValue(), removeRedundantWhiteSpace(), resolveRef(), and substitute().

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

{
//printf("resolveRef(scope=%s,name=%s,inSeeBlock=%d)\n",scName,name,inSeeBlock);
QCString tsName = name;
//bool memberScopeFirst = tsName.find('#')!=-1;
QCString fullName = substitute(tsName,"#","::");
if (fullName.find("anonymous_namespace{")==-1)
{
fullName = removeRedundantWhiteSpace(substitute(fullName,".","::"));
}
else
{
fullName = removeRedundantWhiteSpace(fullName);
}
int bracePos=findParameterList(fullName);
int endNamePos=bracePos!=-1 ? bracePos : fullName.length();
int scopePos=fullName.findRev("::",endNamePos);
bool explicitScope = fullName.left(2)=="::" && // ::scope or #scope
(scopePos>2 || // ::N::A
tsName.left(2)=="::" || // ::foo in local scope
scName==0 // #foo in global scope
);
// default result values
*resContext=0;
*resMember=0;
if (bracePos==-1) // simple name
{
ClassDef *cd=0;
NamespaceDef *nd=0;
// the following if() was commented out for releases in the range
// 1.5.2 to 1.6.1, but has been restored as a result of bug report 594787.
if (!inSeeBlock && scopePos==-1 && isLowerCase(tsName))
{ // link to lower case only name => do not try to autolink
return FALSE;
}
//printf("scName=%s fullName=%s\n",scName,fullName.data());
// check if this is a class or namespace reference
if (scName!=fullName && getScopeDefs(scName,fullName,cd,nd))
{
if (cd) // scope matches that of a class
{
*resContext = cd;
}
else // scope matches that of a namespace
{
ASSERT(nd!=0);
*resContext = nd;
}
return TRUE;
}
else if (scName==fullName || (!inSeeBlock && scopePos==-1))
// nothing to link => output plain text
{
//printf("found scName=%s fullName=%s scName==fullName=%d "
// "inSeeBlock=%d scopePos=%d!\n",
// scName,fullName.data(),scName==fullName,inSeeBlock,scopePos);
return FALSE;
}
// continue search...
}
// extract userscope+name
QCString nameStr=fullName.left(endNamePos);
if (explicitScope) nameStr=nameStr.mid(2);
// extract arguments
QCString argsStr;
if (bracePos!=-1) argsStr=fullName.right(fullName.length()-bracePos);
// strip template specifier
// TODO: match against the correct partial template instantiation
int templPos=nameStr.find('<');
bool tryUnspecializedVersion = FALSE;
if (templPos!=-1 && nameStr.find("operator")==-1)
{
int endTemplPos=nameStr.findRev('>');
if (endTemplPos!=-1)
{
if (!lookForSpecialization)
{
nameStr=nameStr.left(templPos)+nameStr.right(nameStr.length()-endTemplPos-1);
}
else
{
tryUnspecializedVersion = TRUE;
}
}
}
QCString scopeStr=scName;
MemberDef *md = 0;
ClassDef *cd = 0;
FileDef *fd = 0;
NamespaceDef *nd = 0;
GroupDef *gd = 0;
// check if nameStr is a member or global.
//printf("getDefs(scope=%s,name=%s,args=%s checkScope=%d)\n",
// scopeStr.data(),nameStr.data(),argsStr.data(),checkScope);
if (getDefs(scopeStr,nameStr,argsStr,
md,cd,fd,nd,gd,
//scopePos==0 && !memberScopeFirst, // forceEmptyScope
explicitScope, // replaces prev line due to bug 600829
currentFile,
TRUE // checkCV
)
)
{
//printf("after getDefs checkScope=%d nameStr=%s cd=%p nd=%p\n",checkScope,nameStr.data(),cd,nd);
if (checkScope && md && md->getOuterScope()==Doxygen::globalScope &&
(!scopeStr.isEmpty() || nameStr.find("::")>0))
{
// we did find a member, but it is a global one while we were explicitly
// looking for a scoped variable. See bug 616387 for an example why this check is needed.
// note we do need to support autolinking to "::symbol" hence the >0
//printf("not global member!\n");
*resContext=0;
*resMember=0;
return FALSE;
}
//printf("after getDefs md=%p cd=%p fd=%p nd=%p gd=%p\n",md,cd,fd,nd,gd);
if (md) { *resMember=md; *resContext=md; }
else if (cd) *resContext=cd;
else if (nd) *resContext=nd;
else if (fd) *resContext=fd;
else if (gd) *resContext=gd;
else { *resContext=0; *resMember=0; return FALSE; }
//printf("member=%s (md=%p) anchor=%s linkable()=%d context=%s\n",
// md->name().data(),md,md->anchor().data(),md->isLinkable(),(*resContext)->name().data());
return TRUE;
}
else if (inSeeBlock && !nameStr.isEmpty() && (gd=Doxygen::groupSDict->find(nameStr)))
{ // group link
*resContext=gd;
return TRUE;
}
else if (tsName.find('.')!=-1) // maybe a link to a file
{
bool ambig;
if (fd && !ambig)
{
*resContext=fd;
return TRUE;
}
}
if (tryUnspecializedVersion)
{
return resolveRef(scName,name,inSeeBlock,resContext,resMember,FALSE,0,checkScope);
}
if (bracePos!=-1) // Try without parameters as well, could be a contructor invocation
{
*resContext=getClass(fullName.left(bracePos));
if (*resContext)
{
return TRUE;
}
}
//printf("resolveRef: %s not found!\n",name);
return FALSE;
}
QCString resolveTypeDef ( Definition context,
const QCString &  qualifiedName,
Definition **  typedefContext 
)

Definition at line 346 of file util.cpp.

References MemberDef::argsString(), DefinitionIntf::definitionType(), SDict< T >::find(), Definition::findInnerCompound(), Doxygen::functionNameSDict, Definition::getOuterScope(), getScopeFragment(), isAccessibleFrom(), MemberDef::isTypedef(), Doxygen::memberNameSDict, resolveTypeDef(), languages::tmp, DefinitionIntf::TypeClass, and MemberDef::typeString().

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

{
//printf("<<resolveTypeDef(%s,%s)\n",
// context ? context->name().data() : "<none>",qualifiedName.data());
QCString result;
if (qualifiedName.isEmpty())
{
//printf(" qualified name empty!\n");
return result;
}
Definition *mContext=context;
if (typedefContext) *typedefContext=context;
// see if the qualified name has a scope part
int scopeIndex = qualifiedName.findRev("::");
QCString resName=qualifiedName;
if (scopeIndex!=-1) // strip scope part for the name
{
resName=qualifiedName.right(qualifiedName.length()-scopeIndex-2);
if (resName.isEmpty())
{
// qualifiedName was of form A:: !
//printf(" qualified name of form A::!\n");
return result;
}
}
MemberDef *md=0;
while (mContext && md==0)
{
// step 1: get the right scope
Definition *resScope=mContext;
if (scopeIndex!=-1)
{
// split-off scope part
QCString resScopeName = qualifiedName.left(scopeIndex);
//printf("resScopeName=`%s'\n",resScopeName.data());
// look-up scope in context
int is,ps=0;
int l;
while ((is=getScopeFragment(resScopeName,ps,&l))!=-1)
{
QCString qualScopePart = resScopeName.mid(is,l);
QCString tmp = resolveTypeDef(mContext,qualScopePart);
if (!tmp.isEmpty()) qualScopePart=tmp;
resScope = resScope->findInnerCompound(qualScopePart);
//printf("qualScopePart=`%s' resScope=%p\n",qualScopePart.data(),resScope);
if (resScope==0) break;
ps=is+l;
}
}
//printf("resScope=%s\n",resScope?resScope->name().data():"<none>");
// step 2: get the member
if (resScope) // no scope or scope found in the current context
{
//printf("scope found: %s, look for typedef %s\n",
// resScope->qualifiedName().data(),resName.data());
{
}
else
{
}
MemberName *mn=mnd->find(resName);
if (mn)
{
MemberDef *tmd=0;
int minDist=-1;
for (;(tmd=mni.current());++mni)
{
//printf("Found member %s resScope=%s outerScope=%s mContext=%p\n",
// tmd->name().data(), resScope->name().data(),
// tmd->getOuterScope()->name().data(), mContext);
if (tmd->isTypedef() /*&& tmd->getOuterScope()==resScope*/)
{
int dist=isAccessibleFrom(resScope,0,tmd);
if (dist!=-1 && (md==0 || dist<minDist))
{
md = tmd;
minDist = dist;
}
}
}
}
}
mContext=mContext->getOuterScope();
}
// step 3: get the member's type
if (md)
{
//printf(">>resolveTypeDef: Found typedef name `%s' in scope `%s' value=`%s' args='%s'\n",
// qualifiedName.data(),context->name().data(),md->typeString(),md->argsString()
// );
result=md->typeString();
QCString args = md->argsString();
if (args.find(")(")!=-1) // typedef of a function/member pointer
{
result+=args;
}
else if (args.find('[')!=-1) // typedef of an array
{
result+=args;
}
if (typedefContext) *typedefContext=md->getOuterScope();
}
else
{
//printf(">>resolveTypeDef: Typedef `%s' not found in scope `%s'!\n",
// qualifiedName.data(),context ? context->name().data() : "<global>");
}
return result;
}
bool rightScopeMatch ( const QCString &  scope,
const QCString &  name 
)

Definition at line 1970 of file util.cpp.

Referenced by findMember(), findScopeFromQualifiedName(), getDefs(), and isRecursiveBaseClass().

{
int sl=scope.length();
int nl=name.length();
return (name==scope || // equal
(scope.right(nl)==name && // substring
sl-nl>1 && scope.at(sl-nl-1)==':' && scope.at(sl-nl-2)==':' // scope
)
);
}
QCString rtfFormatBmkStr ( const char *  name)

Definition at line 6832 of file util.cpp.

Referenced by RTFGenerator::endDoxyAnchor(), RTFDocVisitor::startLink(), RTFGenerator::startTextLink(), RTFDocVisitor::visit(), RTFDocVisitor::visitPre(), RTFGenerator::writeAnchor(), RTFGenerator::writeCodeLink(), RTFGenerator::writeObjectLink(), RTFGenerator::writeRTFReference(), and RTFGenerator::writeStartAnnoItem().

{
static QCString g_nextTag( "AAAAAAAAAA" );
static QDict<QCString> g_tagDict( 5003 );
g_tagDict.setAutoDelete(TRUE);
// To overcome the 40-character tag limitation, we
// substitute a short arbitrary string for the name
// supplied, and keep track of the correspondence
// between names and strings.
QCString key( name );
QCString* tag = g_tagDict.find( key );
if ( !tag )
{
// This particular name has not yet been added
// to the list. Add it, associating it with the
// next tag value, and increment the next tag.
tag = new QCString( g_nextTag.copy() ); // Make sure to use a deep copy!
g_tagDict.insert( key, tag );
// This is the increment part
char* nxtTag = g_nextTag.rawData() + g_nextTag.length() - 1;
for ( unsigned int i = 0; i < g_nextTag.length(); ++i, --nxtTag )
{
if ( ( ++(*nxtTag) ) > 'Z' )
{
*nxtTag = 'A';
}
else
{
// Since there was no carry, we can stop now
break;
}
}
}
return *tag;
}
void setAnchors ( MemberList ml)

Definition at line 2331 of file util.cpp.

References MemberDef::isReference(), and MemberDef::setAnchor().

Referenced by NamespaceDef::computeAnchors(), GroupDef::computeAnchors(), FileDef::computeAnchors(), and ClassDef::computeAnchors().

{
//int count=0;
if (ml==0) return;
MemberDef *md;
for (;(md=mli.current());++mli)
{
if (!md->isReference())
{
//QCString anchor;
//if (groupId==-1)
// anchor.sprintf("%c%d",id,count++);
//else
// anchor.sprintf("%c%d_%d",id,groupId,count++);
//if (cd) anchor.prepend(escapeCharsInString(cd->name(),FALSE));
md->setAnchor();
//printf("setAnchors(): Member %s outputFileBase=%s anchor %s result %s\n",
// md->name().data(),md->getOutputFileBase().data(),anchor.data(),md->anchor().data());
}
}
}
QCString showFileDefMatches ( const FileNameDict fnDict,
const char *  n 
)

Definition at line 5143 of file util.cpp.

References FileDef::absFilePath(), and FileDef::getPath().

Referenced by addIncludeFile(), buildFileList(), findAndCopyImage(), DocDotFile::parse(), DocMscFile::parse(), DocDiaFile::parse(), and readTextFileByName().

{
QCString result;
QCString name=n;
QCString path;
int slashPos=QMAX(name.findRev('/'),name.findRev('\\'));
if (slashPos!=-1)
{
path=name.left(slashPos+1);
name=name.right(name.length()-slashPos-1);
}
FileName *fn;
if ((fn=(*fnDict)[name]))
{
FileNameIterator fni(*fn);
FileDef *fd;
for (fni.toFirst();(fd=fni.current());++fni)
{
if (path.isEmpty() || fd->getPath().right(path.length())==path)
{
result+=" "+fd->absFilePath()+"\n";
}
}
}
return result;
}
void stackTrace ( )

Definition at line 7699 of file util.cpp.

{
#ifdef TRACINGSUPPORT
void *backtraceFrames[128];
int frameCount = backtrace(backtraceFrames, 128);
static char cmd[40960];
char *p = cmd;
p += sprintf(p,"/usr/bin/atos -p %d ", (int)getpid());
for (int x = 0; x < frameCount; x++)
{
p += sprintf(p,"%p ", backtraceFrames[x]);
}
fprintf(stderr,"========== STACKTRACE START ==============\n");
if (FILE *fp = popen(cmd, "r"))
{
char resBuf[512];
while (size_t len = fread(resBuf, 1, sizeof(resBuf), fp))
{
fwrite(resBuf, 1, len, stderr);
}
pclose(fp);
}
fprintf(stderr,"============ STACKTRACE END ==============\n");
//fprintf(stderr,"%s\n", frameStrings[x]);
#endif
}
QCString stripAnonymousNamespaceScope ( const QCString &  s)

Definition at line 218 of file util.cpp.

References getScopeFragment(), and Doxygen::namespaceSDict.

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

{
int i,p=0,l;
QCString newScope;
int sl = s.length();
while ((i=getScopeFragment(s,p,&l))!=-1)
{
//printf("Scope fragment %s\n",s.mid(i,l).data());
if (Doxygen::namespaceSDict->find(s.left(i+l))!=0)
{
if (s.at(i)!='@')
{
if (!newScope.isEmpty()) newScope+="::";
newScope+=s.mid(i,l);
}
}
else if (i<sl)
{
if (!newScope.isEmpty()) newScope+="::";
newScope+=s.right(sl-i);
goto done;
}
p=i+l;
}
done:
//printf("stripAnonymousNamespaceScope(`%s')=`%s'\n",s.data(),newScope.data());
return newScope;
}
static QCString stripDeclKeywords ( const QCString &  s)
static

Definition at line 3405 of file util.cpp.

Referenced by getCanonicalTypeForIdentifier().

{
int i=s.find(" class ");
if (i!=-1) return s.left(i)+s.mid(i+6);
i=s.find(" typename ");
if (i!=-1) return s.left(i)+s.mid(i+9);
i=s.find(" union ");
if (i!=-1) return s.left(i)+s.mid(i+6);
i=s.find(" struct ");
if (i!=-1) return s.left(i)+s.mid(i+7);
return s;
}
QCString stripExtension ( const char *  fName)
QCString stripExtensionGeneral ( const char *  fName,
const char *  ext 
)

Definition at line 6877 of file util.cpp.

Referenced by stripExtension(), writeDefaultHeaderPart1(), and LatexCodeGenerator::writeLineNumber().

{
QCString result=fName;
if (result.right(QCString(ext).length())==QCString(ext))
{
result=result.left(result.length()-QCString(ext).length());
}
return result;
}
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 306 of file util.cpp.

References Config_getList, and stripFromPath().

Referenced by addIncludeFile(), and findFileDef().

{
return stripFromPath(path,Config_getList(STRIP_FROM_INC_PATH));
}
static QCString stripFromPath ( const QCString &  path,
QStrList &  l 
)
static

Definition at line 274 of file util.cpp.

Referenced by DirDef::DirDef(), FileDef::FileDef(), generateXMLForClass(), generateXMLForDir(), generateXMLForFile(), generateXMLForMember(), generateXMLForNamespace(), markdownFileNameToId(), ClassDef::showUsedFiles(), stripFromIncludePath(), stripFromPath(), and writeSingleFileIndex().

{
// look at all the strings in the list and strip the longest match
const char *s=l.first();
QCString potential;
unsigned int length = 0;
while (s)
{
QCString prefix = s;
if (prefix.length() > length &&
qstricmp(path.left(prefix.length()),prefix)==0) // case insensitive compare
{
length = prefix.length();
potential = path.right(path.length()-prefix.length());
}
s = l.next();
}
if (length) return potential;
return path;
}
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 298 of file util.cpp.

References Config_getList, and stripFromPath().

{
return stripFromPath(path,Config_getList(STRIP_FROM_PATH));
}
QCString stripIndentation ( const QCString &  s)

Definition at line 8225 of file util.cpp.

References Config_getInt.

Referenced by DocPara::handleStartCode().

{
if (s.isEmpty()) return s; // empty string -> we're done
//printf("stripIndentation:\n%s\n------\n",s.data());
// compute minimum indentation over all lines
const char *p=s.data();
char c;
int indent=0;
int minIndent=1000000; // "infinite"
bool searchIndent=TRUE;
static int tabSize=Config_getInt(TAB_SIZE);
while ((c=*p++))
{
if (c=='\t') indent+=tabSize - (indent%tabSize);
else if (c=='\n') indent=0,searchIndent=TRUE;
else if (c==' ') indent++;
else if (searchIndent)
{
searchIndent=FALSE;
if (indent<minIndent) minIndent=indent;
}
}
// no indent to remove -> we're done
if (minIndent==0) return s;
// remove minimum indentation for each line
QGString result;
p=s.data();
indent=0;
while ((c=*p++))
{
if (c=='\n') // start of new line
{
indent=0;
result+=c;
}
else if (indent<minIndent) // skip until we reach minIndent
{
if (c=='\t')
{
int newIndent = indent+tabSize-(indent%tabSize);
int i=newIndent;
while (i>minIndent) // if a tab crosses the minIndent boundary fill the rest with spaces
{
result+=' ';
i--;
}
indent=newIndent;
}
else // space
{
indent++;
}
}
else // copy anything until the end of the line
{
result+=c;
}
}
result+='\0';
return result.data();
}
void stripIrrelevantConstVolatile ( QCString &  s)

According to the C++ spec and Ivan Vecerina:

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

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

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

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

Definition at line 2993 of file util.cpp.

References stripIrrelevantString().

Referenced by extractCanonicalType(), matchArgument(), and matchArgument2().

{
//printf("stripIrrelevantConstVolatile(%s)=",s.data());
stripIrrelevantString(s,"volatile");
//printf("%s\n",s.data());
}
static void stripIrrelevantString ( QCString &  target,
const QCString &  str 
)
static

Definition at line 2942 of file util.cpp.

References isId().

Referenced by stripIrrelevantConstVolatile().

{
if (target==str) { target.resize(0); return; }
int i,p=0;
int l=str.length();
bool changed=FALSE;
while ((i=target.find(str,p))!=-1)
{
bool isMatch = (i==0 || !isId(target.at(i-1))) && // not a character before str
(i+l==(int)target.length() || !isId(target.at(i+l))); // not a character after str
if (isMatch)
{
int i1=target.find('*',i+l);
int i2=target.find('&',i+l);
if (i1==-1 && i2==-1)
{
// strip str from target at index i
target=target.left(i)+target.right(target.length()-i-l);
changed=TRUE;
i-=l;
}
else if ((i1!=-1 && i<i1) || (i2!=-1 && i<i2)) // str before * or &
{
// move str to front
target=str+" "+target.left(i)+target.right(target.length()-i-l);
changed=TRUE;
i++;
}
}
p = i+l;
}
if (changed) target=target.stripWhiteSpace();
}
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 6964 of file util.cpp.

Referenced by Definition::_setDocumentation().

{
const char *p = s.data();
if (p==0) return 0;
// search for leading empty lines
int i=0,li=-1,l=s.length();
char c;
while ((c=*p++))
{
if (c==' ' || c=='\t' || c=='\r') i++;
else if (c=='\n') i++,li=i,docLine++;
else break;
}
// search for trailing empty lines
int b=l-1,bi=-1;
p=s.data()+b;
while (b>=0)
{
c=*p; p--;
if (c==' ' || c=='\t' || c=='\r') b--;
else if (c=='\n') bi=b,b--;
else break;
}
// return whole string if no leading or trailing lines where found
if (li==-1 && bi==-1) return s;
// return substring
if (bi==-1) bi=l;
if (li==-1) li=0;
if (bi<=li) return 0; // only empty lines
return s.mid(li,bi-li);
}
QCString stripPath ( const char *  s)

Definition at line 6907 of file util.cpp.

{
QCString result=s;
int i=result.findRev('/');
if (i!=-1)
{
result=result.mid(i+1);
}
i=result.findRev('\\');
if (i!=-1)
{
result=result.mid(i+1);
}
return result;
}
QCString stripScope ( const char *  name)

Definition at line 5691 of file util.cpp.

Referenced by DotClassGraph::addClass(), getCanonicalTypeForIdentifier(), DefinitionImpl::init(), and DiagramItem::label().

{
QCString result = name;
int l=result.length();
int p;
bool done = FALSE;
bool skipBracket=FALSE; // if brackets do not match properly, ignore them altogether
int count=0;
do
{
p=l-1; // start at the end of the string
while (p>=0 && count>=0)
{
char c=result.at(p);
switch (c)
{
case ':':
// only exit in the case of ::
//printf("stripScope(%s)=%s\n",name,result.right(l-p-1).data());
if (p>0 && result.at(p-1)==':') return result.right(l-p-1);
p--;
break;
case '>':
if (skipBracket) // we don't care about brackets
{
p--;
}
else // count open/close brackets
{
if (p>0 && result.at(p-1)=='>') // skip >> operator
{
p-=2;
break;
}
count=1;
//printf("pos < = %d\n",p);
p--;
bool foundMatch=false;
while (p>=0 && !foundMatch)
{
c=result.at(p--);
switch (c)
{
case '>':
count++;
break;
case '<':
if (p>0)
{
if (result.at(p-1) == '<') // skip << operator
{
p--;
break;
}
}
count--;
foundMatch = count==0;
break;
default:
//printf("c=%c count=%d\n",c,count);
break;
}
}
}
//printf("pos > = %d\n",p+1);
break;
default:
p--;
}
}
done = count==0 || skipBracket; // reparse if brackets do not match
skipBracket=TRUE;
}
while (!done); // if < > unbalanced repeat ignoring them
//printf("stripScope(%s)=%s\n",name,name);
return name;
}
QCString stripTemplateSpecifiersFromScope ( const QCString &  fullName,
bool  parentOnly,
QCString *  pLastScopeStripped 
)

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

References getClass().

Referenced by addClassToContext(), addVariable(), buildFunctionList(), computeTemplateClassRelations(), extractClassName(), findMember(), findScopeFromQualifiedName(), findUsingDeclImports(), getDefs(), getResolvedClassRec(), newResolveTypedef(), and resolveLink().

{
QCString result;
int p=0;
int l=fullName.length();
int i=fullName.find('<');
while (i!=-1)
{
//printf("1:result+=%s\n",fullName.mid(p,i-p).data());
int e=i+1;
bool done=FALSE;
int count=1;
while (e<l && !done)
{
char c=fullName.at(e++);
if (c=='<')
{
count++;
}
else if (c=='>')
{
count--;
done = count==0;
}
}
int si= fullName.find("::",e);
if (parentOnly && si==-1) break;
// we only do the parent scope, so we stop here if needed
result+=fullName.mid(p,i-p);
//printf(" trying %s\n",(result+fullName.mid(i,e-i)).data());
if (getClass(result+fullName.mid(i,e-i))!=0)
{
result+=fullName.mid(i,e-i);
//printf(" 2:result+=%s\n",fullName.mid(i,e-i-1).data());
}
else if (pLastScopeStripped)
{
//printf(" last stripped scope '%s'\n",fullName.mid(i,e-i).data());
*pLastScopeStripped=fullName.mid(i,e-i);
}
p=e;
i=fullName.find('<',p);
}
result+=fullName.right(l-p);
//printf("3:result+=%s\n",fullName.right(l-p).data());
return result;
}
QCString substitute ( const QCString &  s,
const QCString &  src,
const QCString &  dst 
)

substitute all occurrences of src in s by dst

Definition at line 5173 of file util.cpp.

Referenced by addEnumValuesToEnums(), addMethodToClass(), addPageToContext(), addVariableToClass(), FilterNoWrap::apply(), buildFunctionList(), buildListOfUsingDecls(), buildNamespaceList(), checkUndocumentedParams(), convertFileId2Var(), ResourceMgr::copyResourceAs(), MemberDef::displayDefinition(), NamespaceDef::displayName(), ClassDef::displayName(), RTFGenerator::endIndexSection(), field2URL(), findDirDocumentation(), findDocsForMemberOrCompound(), findGlobalMember(), findGroupScope(), findMember(), findUsingDeclarations(), findUsingDirectives(), fixSpaces(), format_warn(), VhdlDocGen::getClassName(), getDefs(), DocPara::handleStartCode(), InheritedMemberInfoContext::Private::id(), linkifyText(), linkToText(), markdownFileNameToId(), matchExcludedSymbols(), processLink(), processTagLessClasses(), replaceAliasArguments(), resolveRef(), DotFilePatcher::run(), selectBlock(), SearchIndex::setCurrentDoc(), substituteHtmlKeywords(), substituteKeywords(), unescapeCRef(), validatingParseDoc(), writeAlphabeticalClassList(), MemberDef::writeDeclaration(), MemberList::writeDeclarations(), writeDefaultLayoutFile(), MemberDef::writeDocumentation(), HtmlGenerator::writeNavigationPath(), HtmlGenerator::writeSearchData(), HtmlGenerator::writeSearchPage(), HtmlGenerator::writeStyleInfo(), and HtmlGenerator::writeStyleSheetFile().

{
if (s.isEmpty() || src.isEmpty()) return s;
const char *p, *q;
int srcLen = src.length();
int dstLen = dst.length();
int resLen;
if (srcLen!=dstLen)
{
int count;
for (count=0, p=s.data(); (q=strstr(p,src))!=0; p=q+srcLen) count++;
resLen = s.length()+count*(dstLen-srcLen);
}
else // result has same size as s
{
resLen = s.length();
}
QCString result(resLen+1);
char *r;
for (r=result.rawData(), p=s; (q=strstr(p,src))!=0; p=q+srcLen)
{
int l = (int)(q-p);
memcpy(r,p,l);
r+=l;
if (dst) memcpy(r,dst,dstLen);
r+=dstLen;
}
qstrcpy(r,p);
//printf("substitute(%s,%s,%s)->%s\n",s,src,dst,result.data());
return result;
}
QCString substituteKeywords ( const QCString &  s,
const char *  title,
const char *  projName,
const char *  projNum,
const char *  projBrief 
)

Definition at line 5207 of file util.cpp.

References Config_getString, dateToString(), stripPath(), substitute(), versionString, and yearToString().

Referenced by LatexGenerator::endIndexSection(), LatexGenerator::startIndexSection(), and substituteHtmlKeywords().

{
QCString result = s;
if (title) result = substitute(result,"$title",title);
result = substitute(result,"$datetime",dateToString(TRUE));
result = substitute(result,"$date",dateToString(FALSE));
result = substitute(result,"$year",yearToString());
result = substitute(result,"$doxygenversion",versionString);
result = substitute(result,"$projectname",projName);
result = substitute(result,"$projectnumber",projNum);
result = substitute(result,"$projectbrief",projBrief);
result = substitute(result,"$projectlogo",stripPath(Config_getString(PROJECT_LOGO)));
return result;
}
QCString substituteTemplateArgumentsInString ( const QCString &  name,
ArgumentList formalArgs,
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 6185 of file util.cpp.

References Argument::defval, leftScopeMatch(), Argument::name, substituteTemplateArgumentsInString(), and Argument::type.

Referenced by computeTemplateClassRelations(), MemberDef::createTemplateInstanceMember(), findBaseClassesForClass(), findUsedClassesForClass(), newResolveTypedef(), and substituteTemplateArgumentsInString().

{
//printf("substituteTemplateArgumentsInString(name=%s formal=%s actualArg=%s)\n",
// name.data(),argListToString(formalArgs).data(),argListToString(actualArgs).data());
if (formalArgs==0) return name;
QCString result;
static QRegExp re("[a-z_A-Z\\x80-\\xFF][a-z_A-Z0-9\\x80-\\xFF]*");
int p=0,l,i;
// for each identifier in the base class name (e.g. B<T> -> B and T)
while ((i=re.match(name,p,&l))!=-1)
{
result += name.mid(p,i-p);
QCString n = name.mid(i,l);
ArgumentListIterator formAli(*formalArgs);
ArgumentListIterator actAli(*actualArgs);
Argument *formArg;
Argument *actArg;
// if n is a template argument, then we substitute it
// for its template instance argument.
bool found=FALSE;
for (formAli.toFirst();
(formArg=formAli.current()) && !found;
++formAli,++actAli
)
{
actArg = actAli.current();
if (formArg->type.left(6)=="class " && formArg->name.isEmpty())
{
formArg->name = formArg->type.mid(6);
formArg->type = "class";
}
if (formArg->type.left(9)=="typename " && formArg->name.isEmpty())
{
formArg->name = formArg->type.mid(9);
formArg->type = "typename";
}
if (formArg->type=="class" || formArg->type=="typename" || formArg->type.left(8)=="template")
{
//printf("n=%s formArg->type='%s' formArg->name='%s' formArg->defval='%s'\n",
// n.data(),formArg->type.data(),formArg->name.data(),formArg->defval.data());
//printf(">> formArg->name='%s' actArg->type='%s' actArg->name='%s'\n",
// formArg->name.data(),actArg ? actArg->type.data() : "",actArg ? actArg->name.data() : ""
// );
if (formArg->name==n && actArg && !actArg->type.isEmpty()) // base class is a template argument
{
// replace formal argument with the actual argument of the instance
if (!leftScopeMatch(actArg->type,n))
// the scope guard is to prevent recursive lockup for
// template<class A> class C : public<A::T>,
// where A::T would become A::T::T here,
// since n==A and actArg->type==A::T
// see bug595833 for an example
{
if (actArg->name.isEmpty())
{
result += actArg->type+" ";
found=TRUE;
}
else
// for case where the actual arg is something like "unsigned int"
// the "int" part is in actArg->name.
{
result += actArg->type+" "+actArg->name+" ";
found=TRUE;
}
}
}
else if (formArg->name==n &&
actArg==0 &&
!formArg->defval.isEmpty() &&
formArg->defval!=name /* to prevent recursion */
)
{
result += substituteTemplateArgumentsInString(formArg->defval,formalArgs,actualArgs)+" ";
found=TRUE;
}
}
else if (formArg->name==n &&
actArg==0 &&
!formArg->defval.isEmpty() &&
formArg->defval!=name /* to prevent recursion */
)
{
result += substituteTemplateArgumentsInString(formArg->defval,formalArgs,actualArgs)+" ";
found=TRUE;
}
}
if (!found)
{
result += n;
}
p=i+l;
}
result+=name.right(name.length()-p);
//printf(" Inheritance relation %s -> %s\n",
// name.data(),result.data());
return result.stripWhiteSpace();
}
static QCString substTypedef ( Definition scope,
FileDef fileScope,
const QCString &  name,
MemberDef **  pTypeDef = 0 
)
static

Substitutes a simple unqualified name within scope. Returns the value of the typedef or name if no typedef was found.

Definition at line 666 of file util.cpp.

References DefinitionIntf::definitionType(), isAccessibleFromWithExpScope(), MemberDef::isTypedef(), Doxygen::symbolMap, DefinitionIntf::TypeMember, MemberDef::typeString(), and DefinitionIntf::TypeSymbolList.

Referenced by followPath().

{
QCString result=name;
if (name.isEmpty()) return result;
// lookup scope fragment in the symbol map
if (di==0) return result; // no matches
MemberDef *bestMatch=0;
if (di->definitionType()==DefinitionIntf::TypeSymbolList) // multi symbols
{
// search for the best match
int minDistance=10000; // init at "infinite"
for (dli.toFirst();(d=dli.current());++dli) // foreach definition
{
// only look at members
{
// that are also typedefs
MemberDef *md = (MemberDef *)d;
if (md->isTypedef()) // d is a typedef
{
// test accessibility of typedef within scope.
int distance = isAccessibleFromWithExpScope(scope,fileScope,d,"");
if (distance!=-1 && distance<minDistance)
// definition is accessible and a better match
{
minDistance=distance;
bestMatch = md;
}
}
}
}
}
else if (di->definitionType()==DefinitionIntf::TypeMember) // single symbol
{
// that are also typedefs
MemberDef *md = (MemberDef *)di;
if (md->isTypedef()) // d is a typedef
{
// test accessibility of typedef within scope.
int distance = isAccessibleFromWithExpScope(scope,fileScope,d,"");
if (distance!=-1) // definition is accessible
{
bestMatch = md;
}
}
}
if (bestMatch)
{
result = bestMatch->typeString();
if (pTypeDef) *pTypeDef=bestMatch;
}
//printf("substTypedef(%s,%s)=%s\n",scope?scope->name().data():"<global>",
// name.data(),result.data());
return result;
}
QCString tempArgListToString ( ArgumentList al,
SrcLangExt  lang 
)

Definition at line 2274 of file util.cpp.

References isId(), Argument::name, removeRedundantWhiteSpace(), SrcLangExt_CSharp, SrcLangExt_Java, Argument::type, and Argument::typeConstraint.

Referenced by findMember(), findTemplateInstanceRelation(), ClassDef::qualifiedNameWithTemplateParameters(), searchTemplateSpecs(), and writeDefArgumentList().

{
QCString result;
if (al==0) return result;
result="<";
Argument *a=ali.current();
while (a)
{
if (!a->name.isEmpty()) // add template argument name
{
if (a->type.left(4)=="out") // C# covariance
{
result+="out ";
}
else if (a->type.left(3)=="in") // C# contravariance
{
result+="in ";
}
if (lang==SrcLangExt_Java || lang==SrcLangExt_CSharp)
{
result+=a->type+" ";
}
result+=a->name;
}
else // extract name from type
{
int i=a->type.length()-1;
while (i>=0 && isId(a->type.at(i))) i--;
if (i>0)
{
result+=a->type.right(a->type.length()-i-1);
if (a->type.find("...")!=-1)
{
result+="...";
}
}
else // nothing found -> take whole name
{
result+=a->type;
}
}
if (!a->typeConstraint.isEmpty() && lang==SrcLangExt_Java)
{
result+=" extends "; // TODO: now Java specific, C# has where...
result+=a->typeConstraint;
}
++ali;
a=ali.current();
if (a) result+=", ";
}
result+=">";
return removeRedundantWhiteSpace(result);
}
static int transcodeCharacterBuffer ( const char *  fileName,
BufStr srcBuf,
int  size,
const char *  inputEncoding,
const char *  outputEncoding 
)
static

Definition at line 7726 of file util.cpp.

References BufStr::data(), err(), portable_iconv(), portable_iconv_close(), portable_iconv_open(), and BufStr::shrink().

Referenced by readInputFile().

{
if (inputEncoding==0 || outputEncoding==0) return size;
if (qstricmp(inputEncoding,outputEncoding)==0) return size;
void *cd = portable_iconv_open(outputEncoding,inputEncoding);
if (cd==(void *)(-1))
{
err("unsupported character conversion: '%s'->'%s': %s\n"
"Check the INPUT_ENCODING setting in the config file!\n",
inputEncoding,outputEncoding,strerror(errno));
exit(1);
}
int tmpBufSize=size*4+1;
BufStr tmpBuf(tmpBufSize);
size_t iLeft=size;
size_t oLeft=tmpBufSize;
char *srcPtr = srcBuf.data();
char *dstPtr = tmpBuf.data();
uint newSize=0;
if (!portable_iconv(cd, &srcPtr, &iLeft, &dstPtr, &oLeft))
{
newSize = tmpBufSize-(int)oLeft;
srcBuf.shrink(newSize);
strncpy(srcBuf.data(),tmpBuf.data(),newSize);
//printf("iconv: input size=%d output size=%d\n[%s]\n",size,newSize,srcBuf.data());
}
else
{
err("%s: failed to translate characters from %s to %s: check INPUT_ENCODING\n",
fileName,inputEncoding,outputEncoding);
exit(1);
}
return newSize;
}
QCString transcodeCharacterStringToUTF8 ( const QCString &  input)

Definition at line 2457 of file util.cpp.

References Config_getString, err(), portable_iconv(), portable_iconv_close(), and portable_iconv_open().

Referenced by readCodeFragment().

{
bool error=FALSE;
static QCString inputEncoding = Config_getString(INPUT_ENCODING);
const char *outputEncoding = "UTF-8";
if (inputEncoding.isEmpty() || qstricmp(inputEncoding,outputEncoding)==0) return input;
int inputSize=input.length();
int outputSize=inputSize*4+1;
QCString output(outputSize);
void *cd = portable_iconv_open(outputEncoding,inputEncoding);
if (cd==(void *)(-1))
{
err("unsupported character conversion: '%s'->'%s'\n",
inputEncoding.data(),outputEncoding);
error=TRUE;
}
if (!error)
{
size_t iLeft=inputSize;
size_t oLeft=outputSize;
char *inputPtr = input.rawData();
char *outputPtr = output.rawData();
if (!portable_iconv(cd, &inputPtr, &iLeft, &outputPtr, &oLeft))
{
outputSize-=(int)oLeft;
output.resize(outputSize+1);
output.at(outputSize)='\0';
//printf("iconv: input size=%d output size=%d\n[%s]\n",size,newSize,srcBuf.data());
}
else
{
err("failed to translate characters from %s to %s: check INPUT_ENCODING\ninput=[%s]\n",
inputEncoding.data(),outputEncoding,input.data());
error=TRUE;
}
}
return error ? input : output;
}
void trimBaseClassScope ( BaseClassList bcl,
QCString &  s,
int  level = 0 
)

Definition at line 2843 of file util.cpp.

References ClassDef::baseClasses(), BaseClassDef::classDef, and Definition::name().

Referenced by matchArgument().

{
//printf("trimBaseClassScope level=%d `%s'\n",level,s.data());
for (;(bcd=bcli.current());++bcli)
{
ClassDef *cd=bcd->classDef;
//printf("Trying class %s\n",cd->name().data());
int spos=s.find(cd->name()+"::");
if (spos!=-1)
{
s = s.left(spos)+s.right(
s.length()-spos-cd->name().length()-2
);
}
//printf("base class `%s'\n",cd->name().data());
if (cd->baseClasses())
trimBaseClassScope(cd->baseClasses(),s,level+1);
}
}
static QCString trimScope ( const QCString &  name,
const QCString &  s 
)
static

Definition at line 2817 of file util.cpp.

References findScopePattern(), and languages::tmp.

Referenced by matchArgument().

{
int scopeOffset=name.length();
QCString result=s;
do // for each scope
{
QCString tmp;
QCString scope=name.left(scopeOffset)+"::";
//printf("Trying with scope=`%s'\n",scope.data());
int i,p=0,l;
while ((i=findScopePattern(scope,result,p,&l))!=-1) // for each occurrence
{
tmp+=result.mid(p,i-p); // add part before pattern
p=i+l;
}
tmp+=result.right(result.length()-p); // add trailing part
scopeOffset=name.findRev("::",scopeOffset-1);
result = tmp;
} while (scopeOffset>0);
//printf("trimScope(name=%s,scope=%s)=%s\n",name.data(),s.data(),result.data());
return result;
}
static QCString trimTemplateSpecifiers ( const QCString &  namespaceName,
const QCString &  className,
const QCString &  s 
)
static

Definition at line 2686 of file util.cpp.

References getClass(), getScopeFragment(), mergeScopes(), Definition::name(), and ClassDef::qualifiedNameWithTemplateParameters().

Referenced by matchArgument().

{
//printf("trimTemplateSpecifiers(%s,%s,%s)\n",namespaceName.data(),className.data(),s.data());
QCString scopeName=mergeScopes(namespaceName,className);
ClassDef *cd=getClass(scopeName);
if (cd==0) return s; // should not happen, but guard anyway.
QCString result=s;
int i=className.length()-1;
if (i>=0 && className.at(i)=='>') // template specialization
{
// replace unspecialized occurrences in s, with their specialized versions.
int count=1;
int cl=i+1;
while (i>=0)
{
char c=className.at(i);
if (c=='>') count++,i--;
else if (c=='<') { count--; if (count==0) break; }
else i--;
}
QCString unspecClassName=className.left(i);
int l=i;
int p=0;
while ((i=result.find(unspecClassName,p))!=-1)
{
if (result.at(i+l)!='<') // unspecialized version
{
result=result.left(i)+className+result.right(result.length()-i-l);
l=cl;
}
p=i+l;
}
}
//printf("result after specialization: %s\n",result.data());
QCString qualName=cd->qualifiedNameWithTemplateParameters();
//printf("QualifiedName = %s\n",qualName.data());
// We strip the template arguments following className (if any)
if (!qualName.isEmpty()) // there is a class name
{
int is,ps=0;
int p=0,l,i;
while ((is=getScopeFragment(qualName,ps,&l))!=-1)
{
QCString qualNamePart = qualName.right(qualName.length()-is);
//printf("qualNamePart=%s\n",qualNamePart.data());
while ((i=result.find(qualNamePart,p))!=-1)
{
int ql=qualNamePart.length();
result=result.left(i)+cd->name()+result.right(result.length()-i-ql);
p=i+cd->name().length();
}
ps=is+l;
}
}
//printf("result=%s\n",result.data());
return result.stripWhiteSpace();
}
bool updateLanguageMapping ( const QCString &  extension,
const QCString &  language 
)

Definition at line 7052 of file util.cpp.

References err(), g_lang2extMap, Lang2ExtMap::langName, Lang2ExtMap::parserId, Doxygen::parserManager, and Lang2ExtMap::parserName.

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

{
QCString langName = language.lower();
while (p->langName)
{
if (langName==p->langName) break;
p++;
}
if (!p->langName) return FALSE;
// found the language
SrcLangExt parserId = p->parserId;
QCString extName = extension.lower();
if (extName.isEmpty()) return FALSE;
if (extName.at(0)!='.') extName.prepend(".");
if (g_extLookup.find(extension)!=0) // language was already register for this ext
{
g_extLookup.remove(extension);
}
//printf("registering extension %s\n",extName.data());
g_extLookup.insert(extName,new int(parserId));
if (!Doxygen::parserManager->registerExtension(extName,p->parserName))
{
err("Failed to assign extension %s to parser %s for language %s\n",
extName.data(),p->parserName,language.data());
}
else
{
//msg("Registered extension %s to language parser %s...\n",
// extName.data(),language.data());
}
return TRUE;
}
void writeColoredImgData ( const char *  dir,
ColoredImgDataItem  data[] 
)

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

Definition at line 7980 of file util.cpp.

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

Referenced by ResourceMgr::copyResourceAs().

{
static int hue = Config_getInt(HTML_COLORSTYLE_HUE);
static int sat = Config_getInt(HTML_COLORSTYLE_SAT);
static int gamma = Config_getInt(HTML_COLORSTYLE_GAMMA);
while (data->name)
{
QCString fileName;
fileName=(QCString)dir+"/"+data->name;
QFile f(fileName);
if (f.open(IO_WriteOnly))
{
ColoredImage img(data->width,data->height,data->content,data->alpha,
sat,hue,gamma);
img.save(fileName);
}
else
{
fprintf(stderr,"Warning: Cannot open file %s for writing\n",data->name);
}
data++;
}
}
void writeExample ( OutputList ol,
ExampleSDict ed 
)

Definition at line 2183 of file util.cpp.

References Example::anchor, SDict< T >::at(), SDict< T >::count(), OutputList::disable(), Example::file, OutputGenerator::Html, OutputGenerator::Latex, OutputGenerator::Man, Example::name, OutputList::parseText(), OutputList::popGeneratorState(), OutputList::pushGeneratorState(), OutputGenerator::RTF, theTranslator, Translator::trWriteList(), OutputList::writeObjectLink(), and OutputList::writeString().

Referenced by MemberDef::_writeExamples(), and ClassDef::writeDetailedDocumentationBody().

{
QCString exampleLine=theTranslator->trWriteList(ed->count());
//bool latexEnabled = ol.isEnabled(OutputGenerator::Latex);
//bool manEnabled = ol.isEnabled(OutputGenerator::Man);
//bool htmlEnabled = ol.isEnabled(OutputGenerator::Html);
QRegExp marker("@[0-9]+");
int index=0,newIndex,matchLen;
// now replace all markers in inheritLine with links to the classes
while ((newIndex=marker.match(exampleLine,index,&matchLen))!=-1)
{
bool ok;
ol.parseText(exampleLine.mid(index,newIndex-index));
uint entryIndex = exampleLine.mid(newIndex+1,matchLen-1).toUInt(&ok);
Example *e=ed->at(entryIndex);
if (ok && e)
{
//if (latexEnabled) ol.disable(OutputGenerator::Latex);
// link for Html / man
//printf("writeObjectLink(file=%s)\n",e->file.data());
ol.writeObjectLink(0,e->file,e->anchor,e->name);
//if (latexEnabled) ol.enable(OutputGenerator::Latex);
// link for Latex / pdf with anchor because the sources
// are not hyperlinked (not possible with a verbatim environment).
ol.writeObjectLink(0,e->file,0,e->name);
//if (manEnabled) ol.enable(OutputGenerator::Man);
//if (htmlEnabled) ol.enable(OutputGenerator::Html);
}
index=newIndex+matchLen;
}
ol.parseText(exampleLine.right(exampleLine.length()-index));
ol.writeString(".");
}
void writeExtraLatexPackages ( FTextStream t)

Definition at line 8709 of file util.cpp.

References Config_getList.

Referenced by FormulaList::generateBitmaps(), and writeDefaultHeaderPart1().

{
// User-specified packages
QStrList &extraPackages = Config_getList(EXTRA_PACKAGES);
if (!extraPackages.isEmpty())
{
t << "% Packages requested by user\n";
const char *pkgName=extraPackages.first();
while (pkgName)
{
if ((pkgName[0] == '[') || (pkgName[0] == '{'))
t << "\\usepackage" << pkgName << "\n";
else
t << "\\usepackage{" << pkgName << "}\n";
pkgName=extraPackages.next();
}
t << "\n";
}
}
void writePageRef ( OutputDocInterface od,
const char *  cn,
const char *  mn 
)
void writeTypeConstraints ( OutputList ol,
Definition d,
ArgumentList al 
)
const char* writeUtf8Char ( FTextStream t,
const char *  s 
)

Definition at line 7256 of file util.cpp.

Referenced by HtmlCodeGenerator::codify(), ManGenerator::codify(), RTFGenerator::codify(), and writeXMLCodeString().

{
char c=*s++;
t << c;
if (c<0) // multibyte character
{
if (((uchar)c&0xE0)==0xC0)
{
t << *s++; // 11xx.xxxx: >=2 byte character
}
if (((uchar)c&0xF0)==0xE0)
{
t << *s++; // 111x.xxxx: >=3 byte character
}
if (((uchar)c&0xF8)==0xF0)
{
t << *s++; // 1111.xxxx: >=4 byte character
}
if (((uchar)c&0xFC)==0xF8)
{
t << *s++; // 1111.1xxx: >=5 byte character
}
if (((uchar)c&0xFE)==0xFC)
{
t << *s++; // 1111.1xxx: 6 byte character
}
}
return s;
}
QCString yearToString ( )

Definition at line 2598 of file util.cpp.

Referenced by substituteKeywords().

{
const QDate &d=QDate::currentDate();
QCString result;
result.sprintf("%d", d.year());
return result;
}

Variable Documentation

QDict<void> aliasesProcessed
static

Definition at line 7378 of file util.cpp.

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

Definition at line 1651 of file util.cpp.

Referenced by removeRedundantWhiteSpace().

CharAroundSpace g_charAroundSpace
static

Definition at line 1693 of file util.cpp.

QDict<int> g_extLookup
static

Definition at line 7021 of file util.cpp.

struct Lang2ExtMap g_lang2extMap[]
static
Initial value:
=
{
{ "idl", "c", SrcLangExt_IDL },
{ "java", "c", SrcLangExt_Java },
{ "javascript", "c", SrcLangExt_JS },
{ "csharp", "c", SrcLangExt_CSharp },
{ "d", "c", SrcLangExt_D },
{ "php", "c", SrcLangExt_PHP },
{ "objective-c", "c", SrcLangExt_ObjC },
{ "c", "c", SrcLangExt_Cpp },
{ "c++", "c", SrcLangExt_Cpp },
{ "python", "python", SrcLangExt_Python },
{ "fortran", "fortran", SrcLangExt_Fortran },
{ "fortranfree", "fortranfree", SrcLangExt_Fortran },
{ "fortranfixed", "fortranfixed", SrcLangExt_Fortran },
{ "vhdl", "vhdl", SrcLangExt_VHDL },
{ "xml", "xml", SrcLangExt_XML },
{ "tcl", "tcl", SrcLangExt_Tcl },
{ "md", "md", SrcLangExt_Markdown },
{ 0, 0, (SrcLangExt)0 }
}

Referenced by updateLanguageMapping().

QDict<MemberDef> g_resolvedTypedefs
static

Definition at line 514 of file util.cpp.

Referenced by getResolvedClass(), and newResolveTypedef().

QDict<Definition> g_visitedNamespaces
static

Definition at line 515 of file util.cpp.

Referenced by getMemberFromSymbol(), getResolvedSymbol(), and isAccessibleFromWithExpScope().

const int MAX_STACK_SIZE = 1000

Definition at line 871 of file util.cpp.

Referenced by AccessStack::push().

const int maxInheritanceDepth = 100000

Definition at line 148 of file util.cpp.

Referenced by getDefs(), ClassDef::getMemberByName(), and minClassDistance().

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

Definition at line 1653 of file util.cpp.

Referenced by removeRedundantWhiteSpace().

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

Definition at line 1652 of file util.cpp.

Referenced by removeRedundantWhiteSpace().