My Project
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Classes | Functions
util.h File Reference

A bunch of utility functions. More...

#include <qlist.h>
#include <ctype.h>
#include "types.h"
#include "sortdict.h"
#include "docparser.h"

Go to the source code of this file.

Classes

class  TextGeneratorIntf
 
class  TextGeneratorOLImpl
 
class  LetterToIndexMap< T >
 maps a unicode character code to a list of T::ElementType's More...
 
struct  ColoredImgDataItem
 

Functions

QCString langToString (SrcLangExt lang)
 
QCString getLanguageSpecificSeparator (SrcLangExt lang, bool classScope=FALSE)
 
void linkifyText (const TextGeneratorIntf &ol, Definition *scope, FileDef *fileScope, Definition *self, const char *text, bool autoBreak=FALSE, bool external=TRUE, bool keepSpaces=FALSE, int indentLevel=0)
 
void setAnchors (MemberList *ml)
 
QCString fileToString (const char *name, bool filter=FALSE, bool isSourceCode=FALSE)
 
QCString dateToString (bool)
 
bool getDefs (const QCString &scopeName, const QCString &memberName, const char *, MemberDef *&md, ClassDef *&cd, FileDef *&fd, NamespaceDef *&nd, GroupDef *&gd, bool forceEmptyScope=FALSE, FileDef *currentFile=0, bool checkCV=FALSE, const char *forceTagFile=0)
 
QCString getFileFilter (const char *name, bool isSourceCode)
 
bool resolveRef (const char *scName, const char *name, bool inSeeBlock, Definition **resContext, MemberDef **resMember, bool lookForSpecializations=TRUE, FileDef *currentFile=0, bool checkScope=FALSE)
 
bool resolveLink (const char *scName, const char *lr, bool inSeeBlock, Definition **resContext, QCString &resAnchor)
 
bool generateLink (OutputDocInterface &od, const char *, const char *, bool inSeeBlock, const char *)
 
void generateFileRef (OutputDocInterface &od, const char *, const char *linkTxt=0)
 
void writePageRef (OutputDocInterface &od, const char *cn, const char *mn)
 
QCString getCanonicalTemplateSpec (Definition *d, FileDef *fs, const QCString &spec)
 
bool matchArguments2 (Definition *srcScope, FileDef *srcFileScope, ArgumentList *srcAl, Definition *dstScope, FileDef *dstFileScope, ArgumentList *dstAl, bool checkCV)
 
void mergeArguments (ArgumentList *, ArgumentList *, bool forceNameOverwrite=FALSE)
 
QCString substituteClassNames (const QCString &s)
 
QCString substitute (const QCString &s, const QCString &src, const QCString &dst)
 substitute all occurrences of src in s by dst
 
QCString clearBlock (const char *s, const char *begin, const char *end)
 Clear a text block s from begin to end markers.
 
QCString selectBlock (const QCString &s, const QCString &name, bool which)
 
QCString resolveDefines (const char *n)
 
ClassDefgetClass (const char *key)
 
ClassDefgetResolvedClass (Definition *scope, FileDef *fileScope, const char *key, MemberDef **pTypeDef=0, QCString *pTemplSpec=0, bool mayBeUnlinkable=FALSE, bool mayBeHidden=FALSE, QCString *pResolvedType=0)
 
NamespaceDefgetResolvedNamespace (const char *key)
 
FileDeffindFileDef (const FileNameDict *fnDict, const char *n, bool &ambig)
 
QCString showFileDefMatches (const FileNameDict *fnDict, const char *n)
 
int guessSection (const char *name)
 
bool isId (int c)
 
QCString removeRedundantWhiteSpace (const QCString &s)
 
QCString argListToString (ArgumentList *al, bool useCanonicalType=FALSE, bool showDefVals=TRUE)
 
QCString tempArgListToString (ArgumentList *al, SrcLangExt lang)
 
QCString generateMarker (int id)
 
void writeExample (OutputList &ol, ExampleSDict *el)
 
QCString stripAnonymousNamespaceScope (const QCString &s)
 
QCString stripFromPath (const QCString &path)
 
QCString stripFromIncludePath (const QCString &path)
 
bool rightScopeMatch (const QCString &scope, const QCString &name)
 
bool leftScopeMatch (const QCString &scope, const QCString &name)
 
QCString substituteKeywords (const QCString &s, const char *title, const char *projName, const char *projNum, const char *projBrief)
 
int getPrefixIndex (const QCString &name)
 
QCString removeAnonymousScopes (const QCString &s)
 
QCString replaceAnonymousScopes (const QCString &s, const char *replacement=0)
 
void initClassHierarchy (ClassSDict *cl)
 
bool hasVisibleRoot (BaseClassList *bcl)
 
bool classHasVisibleChildren (ClassDef *cd)
 
bool namespaceHasVisibleChild (NamespaceDef *nd, bool includeClasses)
 
bool classVisibleInIndex (ClassDef *cd)
 
int minClassDistance (const ClassDef *cd, const ClassDef *bcd, int level=0)
 
Protection classInheritedProtectionLevel (ClassDef *cd, ClassDef *bcd, Protection prot=Public, int level=0)
 
QCString convertNameToFile (const char *name, bool allowDots=FALSE, bool allowUnderscore=FALSE)
 
void extractNamespaceName (const QCString &scopeName, QCString &className, QCString &namespaceName, bool allowEmptyClass=FALSE)
 
QCString insertTemplateSpecifierInScope (const QCString &scope, const QCString &templ)
 
QCString stripScope (const char *name)
 
QCString convertToId (const char *s)
 
QCString convertToHtml (const char *s, bool keepEntities=TRUE)
 
QCString convertToLaTeX (const QCString &s, bool insideTabbing=FALSE, bool keepSpaces=FALSE)
 
QCString convertToXML (const char *s)
 
QCString convertToJSString (const char *s)
 
QCString getOverloadDocs ()
 
void addMembersToMemberGroup (MemberList *ml, MemberGroupSDict **ppMemberGroupSDict, Definition *context)
 
int extractClassNameFromType (const QCString &type, int &pos, QCString &name, QCString &templSpec, SrcLangExt=SrcLangExt_Unknown)
 
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=TRUE, QCString *lastScopeStripped=0)
 
QCString resolveTypeDef (Definition *d, const QCString &name, Definition **typedefContext=0)
 
QCString mergeScopes (const QCString &leftScope, const QCString &rightScope)
 
int getScopeFragment (const QCString &s, int p, int *l)
 
int filterCRLF (char *buf, int len)
 
void addRefItem (const QList< ListItemInfo > *sli, const char *prefix, const char *key, const char *name, const char *title, const char *args, Definition *scope)
 
PageDefaddRelatedPage (const char *name, const QCString &ptitle, const QCString &doc, QList< SectionInfo > *anchors, const char *fileName, int startLine, const QList< ListItemInfo > *sli, GroupDef *gd=0, TagInfo *tagInfo=0, SrcLangExt lang=SrcLangExt_Unknown)
 
QCString escapeCharsInString (const char *name, bool allowDots, bool allowUnderscore=FALSE)
 
void addGroupListToTitle (OutputList &ol, Definition *d)
 
void filterLatexString (FTextStream &t, const char *str, bool insideTabbing=FALSE, bool insidePre=FALSE, bool insideItem=FALSE, bool keepSpaces=FALSE)
 
QCString latexEscapeLabelName (const char *s, bool insideTabbing)
 
QCString latexEscapeIndexChars (const char *s, bool insideTabbing)
 
QCString latexEscapePDFString (const char *s)
 
QCString rtfFormatBmkStr (const char *name)
 
QCString linkToText (SrcLangExt lang, const char *link, bool isFileName)
 
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)
 
int isAccessibleFrom (Definition *scope, FileDef *fileScope, Definition *item)
 
int isAccessibleFromWithExpScope (Definition *scope, FileDef *fileScope, Definition *item, const QCString &explicitScopePart)
 
int computeQualifiedIndex (const QCString &name)
 
void addDirPrefix (QCString &fileName)
 
QCString relativePathToRoot (const char *name)
 
void createSubDirs (QDir &d)
 
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 &parser)
 
SrcLangExt getLanguageFromFileName (const QCString fileName)
 
void initDefaultExtensionMapping ()
 
void addCodeOnlyMappings ()
 
MemberDefgetMemberFromSymbol (Definition *scope, FileDef *fileScope, const char *n)
 
bool checkIfTypedef (Definition *scope, FileDef *fileScope, const char *n)
 
ClassDefnewResolveTypedef (FileDef *fileScope, MemberDef *md, MemberDef **pMemType=0, QCString *pTemplSpec=0, QCString *pResolvedType=0, ArgumentList *actTemplParams=0)
 
QCString parseCommentAsText (const Definition *scope, const MemberDef *member, const QCString &doc, const QCString &fileName, int lineNr)
 
QCString transcodeCharacterStringToUTF8 (const QCString &input)
 
QCString recodeString (const QCString &str, const char *fromEncoding, const char *toEncoding)
 
QCString extractAliasArgs (const QCString &args, int pos)
 
int countAliasArguments (const QCString argList)
 
QCString resolveAliasCmd (const QCString aliasCmd)
 
QCString expandAlias (const QCString &aliasName, const QCString &aliasValue)
 
void writeTypeConstraints (OutputList &ol, Definition *d, ArgumentList *al)
 
QCString convertCharEntitiesToUTF8 (const QCString &s)
 
void stackTrace ()
 
bool readInputFile (const char *fileName, BufStr &inBuf, bool filter=TRUE, bool isSourceCode=FALSE)
 read a file name fileName and optionally filter and transcode it
 
QCString filterTitle (const QCString &title)
 
bool patternMatch (const QFileInfo &fi, const QStrList *patList)
 
QCString externalLinkTarget ()
 
QCString externalRef (const QCString &relPath, const QCString &ref, bool href)
 
int nextUtf8CharPosition (const QCString &utf8Str, int len, int startPos)
 
const char * writeUtf8Char (FTextStream &t, const char *s)
 
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 correctURL (const QCString &url, const QCString &relPath)
 
QCString processMarkup (const QCString &s)
 
bool protectionLevelVisible (Protection prot)
 
QCString stripIndentation (const QCString &s)
 
QCString getDotImageExtension (void)
 
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.
 
QCString extractDirection (QCString &docs)
 
void convertProtectionLevel (MemberListType inListType, Protection inProt, int *outListType1, int *outListType2)
 
bool mainPageHasTitle ()
 
bool openOutputFile (const char *outFile, QFile &f)
 
void writeExtraLatexPackages (FTextStream &t)
 

Detailed Description

A bunch of utility functions.

Definition in file util.h.

Function Documentation

void addCodeOnlyMappings ( )

Definition at line 7147 of file util.cpp.

References updateLanguageMapping().

Referenced by generateOutput().

{
updateLanguageMapping(".xml", "xml");
}
void addDirPrefix ( QCString &  fileName)
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 *  prefix,
const char *  key,
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 > *  anchors,
const char *  fileName,
int  startLine,
const QList< ListItemInfo > *  sli,
GroupDef gd = 0,
TagInfo tagInfo = 0,
SrcLangExt  lang = SrcLangExt_Unknown 
)

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

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 = Public,
int  level = 0 
)

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();
}
QCString clearBlock ( const char *  s,
const char *  begin,
const char *  end 
)

Clear a text block s from begin to end markers.

Definition at line 110 of file htmlgen.cpp.

Referenced by selectBlock().

{
if (s==0 || begin==0 || end==0) return s;
const char *p, *q;
int beginLen = qstrlen(begin);
int endLen = qstrlen(end);
int resLen = 0;
for (p=s; (q=strstr(p,begin))!=0; p=q+endLen)
{
resLen+=(int)(q-p);
p=q+beginLen;
if ((q=strstr(p,end))==0)
{
resLen+=beginLen;
break;
}
}
resLen+=qstrlen(p);
// resLen is the length of the string without the marked block
QCString result(resLen+1);
char *r;
for (r=result.rawData(), p=s; (q=strstr(p,begin))!=0; p=q+endLen)
{
int l = (int)(q-p);
memcpy(r,p,l);
r+=l;
p=q+beginLen;
if ((q=strstr(p,end))==0)
{
memcpy(r,begin,beginLen);
r+=beginLen;
break;
}
}
qstrcpy(r,p);
return result;
}
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 = FALSE,
bool  keepSpaces = FALSE 
)

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  )

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);
}
QCString escapeCharsInString ( const char *  name,
bool  allowDots,
bool  allowUnderscore = FALSE 
)

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();
}
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;
}
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();
}
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 = FALSE,
bool  insidePre = FALSE,
bool  insideItem = FALSE,
bool  keepSpaces = FALSE 
)

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;
}
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;
}
void generateFileRef ( OutputDocInterface od,
const char *  ,
const char *  linkTxt = 0 
)

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 *  ,
const char *  ,
bool  inSeeBlock,
const char *   
)

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;
}
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;
}
}
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 *  key,
MemberDef **  pTypeDef = 0,
QCString *  pTemplSpec = 0,
bool  mayBeUnlinkable = FALSE,
bool  mayBeHidden = FALSE,
QCString *  pResolvedType = 0 
)

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;
}
NamespaceDef* getResolvedNamespace ( const char *  key)

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
{
}
}
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)
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;
}
bool isId ( int  c)
inline
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 ol,
Definition scope,
FileDef fileScope,
Definition self,
const char *  text,
bool  autoBreak = FALSE,
bool  external = TRUE,
bool  keepSpaces = FALSE,
int  indentLevel = 0 
)

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
{
out.writeLink(md->getReference(),md->getOutputFileBase(),
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;
}
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 ,
ArgumentList ,
bool  forceNameOverwrite = FALSE 
)

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

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 member,
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;
}
QCString processMarkup ( const QCString &  s)
bool protectionLevelVisible ( Protection  prot)
bool readInputFile ( const char *  fileName,
BufStr inBuf,
bool  filter = TRUE,
bool  isSourceCode = FALSE 
)

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;
}
QCString recodeString ( const QCString &  str,
const char *  fromEncoding,
const char *  toEncoding 
)
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;
}
QCString replaceAnonymousScopes ( const QCString &  s,
const char *  replacement = 0 
)

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;
}
QCString resolveDefines ( const char *  n)
bool resolveLink ( const char *  scName,
const char *  lr,
bool  inSeeBlock,
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 d,
const QCString &  name,
Definition **  typedefContext = 0 
)

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;
}
QCString selectBlock ( const QCString &  s,
const QCString &  name,
bool  which 
)

Definition at line 150 of file htmlgen.cpp.

References clearBlock(), and substitute().

Referenced by substituteHtmlKeywords().

{
// TODO: this is an expensive function that is called a lot -> optimize it
const QCString begin = "<!--BEGIN " + name + "-->";
const QCString end = "<!--END " + name + "-->";
const QCString nobegin = "<!--BEGIN !" + name + "-->";
const QCString noend = "<!--END !" + name + "-->";
QCString result = s;
if (enable)
{
result = substitute(result, begin, "");
result = substitute(result, end, "");
result = clearBlock(result, nobegin, noend);
}
else
{
result = substitute(result, nobegin, "");
result = substitute(result, noend, "");
result = clearBlock(result, begin, end);
}
return result;
}
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;
}
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));
}
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();
}
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 substituteClassNames ( const QCString &  s)
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();
}
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);
}
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;
}
bool updateLanguageMapping ( const QCString &  extension,
const QCString &  parser 
)

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

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;
}