diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/classdef.cpp | 49 | ||||
-rw-r--r-- | src/classdef.h | 8 | ||||
-rw-r--r-- | src/code.l | 848 | ||||
-rw-r--r-- | src/config.l | 50 | ||||
-rw-r--r-- | src/definition.cpp | 93 | ||||
-rw-r--r-- | src/definition.h | 25 | ||||
-rw-r--r-- | src/doc.l | 20 | ||||
-rw-r--r-- | src/doxygen.cpp | 45 | ||||
-rw-r--r-- | src/htmlgen.cpp | 10 | ||||
-rw-r--r-- | src/index.cpp | 32 | ||||
-rw-r--r-- | src/latexgen.cpp | 134 | ||||
-rw-r--r-- | src/latexgen.h | 1 | ||||
-rw-r--r-- | src/memberdef.cpp | 1 | ||||
-rw-r--r-- | src/memberlist.cpp | 11 | ||||
-rw-r--r-- | src/memberlist.h | 13 | ||||
-rw-r--r-- | src/scanner.l | 39 | ||||
-rw-r--r-- | src/tagreader.cpp | 1 | ||||
-rw-r--r-- | src/translator.h | 6 | ||||
-rw-r--r-- | src/translator_adapter.h | 19 | ||||
-rw-r--r-- | src/translator_br.h | 2 | ||||
-rw-r--r-- | src/translator_cn.h | 2 | ||||
-rw-r--r-- | src/translator_cz.h | 2 | ||||
-rw-r--r-- | src/translator_de.h | 2 | ||||
-rw-r--r-- | src/translator_en.h | 11 | ||||
-rw-r--r-- | src/translator_fr.h | 2 | ||||
-rw-r--r-- | src/translator_hr.h | 2 | ||||
-rw-r--r-- | src/translator_it.h | 2 | ||||
-rw-r--r-- | src/translator_nl.h | 2 | ||||
-rw-r--r-- | src/translator_pt.h | 2 | ||||
-rw-r--r-- | src/translator_ru.h | 2 | ||||
-rw-r--r-- | src/translator_si.h | 31 | ||||
-rw-r--r-- | src/translator_sk.h | 2 | ||||
-rw-r--r-- | src/translator_ua.h | 2 | ||||
-rw-r--r-- | src/util.cpp | 2 |
34 files changed, 1018 insertions, 455 deletions
diff --git a/src/classdef.cpp b/src/classdef.cpp index 24ca56f..a9cf53b 100644 --- a/src/classdef.cpp +++ b/src/classdef.cpp @@ -1267,8 +1267,11 @@ void ClassDef::writeMemberList(OutputList &ol) QCString name=mi->ambiguityResolutionScope+md->name(); //ol.writeListItem(); ol.writeString(" <tr bgcolor=\"#f0f0f0\"><td>"); - ol.writeObjectLink(cd->getReference(),cd->getOutputFileBase(), + Definition *bd = md->getGroupDef(); + if (bd==0) bd=cd; + ol.writeObjectLink(bd->getReference(),bd->getOutputFileBase(), md->anchor(),name); + if ( md->isFunction() || md->isSignal() || md->isSlot() || (md->isFriend() && md->argsString())) ol.docify(md->argsString()); @@ -2238,23 +2241,18 @@ void ClassDef::addMembersToTemplateInstance(ClassDef *cd,const char *templSpec) //imd->setBriefDescription(md->briefDescription()); imd->setMemberSpecifiers(md->getMemberSpecifiers()); insertMember(imd); - //printf("Adding member=%s%s to class %s\n",imd->name().data(),imd->argsString(),imd->getClassDef()->name().data()); + //printf("Adding member=%s %s%s to class %s templSpec %s\n", + // imd->typeString(),imd->name().data(),imd->argsString(), + // imd->getClassDef()->name().data(),templSpec); // insert imd in the list of all members //printf("Adding member=%s class=%s\n",imd->name().data(),name().data()); -#if 0 - MemberName *mn; - if ((mn=Doxygen::memberNameDict[imd->name()])) - { - mn->append(md); - } - else + MemberName *mn = Doxygen::memberNameSDict[imd->name()]; + if (mn==0) { mn = new MemberName(imd->name()); - mn->append(md); - Doxygen::memberNameDict.insert(imd->name(),mn); - Doxygen::memberNameList.append(mn); + Doxygen::memberNameSDict.append(imd->name(),mn); } -#endif + mn->append(imd); } } } @@ -2378,3 +2376,28 @@ void ClassDef::addListReferences() propertyMembers.addListReferences(this); } +MemberDef *ClassDef::getMemberByName(const QCString &name) +{ + MemberDef *xmd = 0; + MemberNameInfo *mni = m_allMemberNameInfoSDict->find(name); + if (mni) + { + const int maxInheritanceDepth = 100000; + int mdist=maxInheritanceDepth; + MemberNameInfoIterator mnii(*mni); + MemberInfo *mi; + for (mnii.toFirst();(mi=mnii.current());++mnii) + { + ClassDef *mcd=mi->memberDef->getClassDef(); + int m=minClassDistance(this,mcd); + if (m<mdist && mcd->isLinkable()) + { + mdist=m; + xmd=mi->memberDef; + } + } + } + return xmd; +} + + diff --git a/src/classdef.h b/src/classdef.h index e42ef6b..c2b6274 100644 --- a/src/classdef.h +++ b/src/classdef.h @@ -145,6 +145,8 @@ class ClassDef : public Definition /*! Returns the Java package this class is in or 0 if not applicable. */ PackageDef *packageDef() const; + + MemberDef *getMemberByName(const QCString &); /*! Returns TRUE iff \a bcd is a direct or indirect base class of this * class. This function will recusively traverse all branches of the @@ -244,9 +246,9 @@ class ClassDef : public Definition void insertMember(MemberDef *); void insertUsedFile(const char *); void computeAnchors(); - void computeMemberGroups(); - void setAnchor(MemberDef *); - void dumpMembers(); + //void computeMemberGroups(); + //void setAnchor(MemberDef *); + //void dumpMembers(); bool addExample(const char *anchor,const char *name, const char *file); void addMembersToMemberGroup(); void distributeMemberGroupDocumentation(); @@ -36,83 +36,46 @@ #define YY_NEVER_INTERACTIVE 1 +// Toggle for some debugging info +//#define DBG_CTX(x) fprintf x +#define DBG_CTX(x) do { } while(0) + #define SCOPEBLOCK (int *)4 #define INNERBLOCK (int *)8 -/*! local class definition, used for classes that are defined - * inside code fragments. - */ -class CodeClassDef -{ - public: - CodeClassDef() {} - CodeClassDef(const CodeClassDef &d) - { - name = d.name; - bases = d.bases; - } - ~CodeClassDef() {} - - QCString name; - QStrList bases; -}; - -/*! local member definition, used for variables that are defined - * inside code fragments. - */ -class CodeVarDef -{ - public: - CodeVarDef() {} - CodeVarDef(const CodeVarDef &d) - { - name = d.name; - type = d.type; - classScope = d.classScope; - } - ~CodeVarDef() {} - - QCString name; - QCString type; - QCString classScope; -}; - -typedef QDict<CodeClassDef> CodeClassDict; -typedef QList<CodeVarDef> CodeVarList; - /* ----------------------------------------------------------------- * statics */ static OutputDocInterface * g_code; -static CodeClassDict g_codeClassDict(1009); -static CodeVarList g_codeVarList; -static CodeVarList g_codeParmList; + +static ClassSDict g_codeClassSDict(17); +static ClassDef *g_curClassDef; +static QCString g_curClassName; +static QStrList g_curClassBases; + +// TODO: is this still needed? if so, make it work +static bool g_inClass; + +static QCString g_parmType; +static QCString g_parmName; + static const char * g_inputString; //!< the code fragment as text static int g_inputPosition; //!< read offset during parsing static int g_inputLines; //!< number of line in the code fragment static int g_yyLineNr; //!< current line number -static int g_lastCContext; -static int g_lastSpecialCContext; -static int g_lastStringContext; -static int g_bracketCount = 0; -static int g_curlyCount = 0; -static int g_sharpCount = 0; + +static bool g_exampleBlock; +static QCString g_exampleName; +static QCString g_exampleFile; + static bool g_insideTemplate = FALSE; static QCString g_type; static QCString g_name; static QCString g_args; -static QCString g_parmType; -static QCString g_parmName; -static bool g_inClass; static QCString g_classScope; static QCString g_realScope; -static QStack<int> g_scopeStack; // 1 if bracket starts a scope, 2 for internal blocks -static CodeClassDef g_ccd; -static CodeVarDef g_cvd; -static bool g_exampleBlock; -static QCString g_exampleName; -static QCString g_exampleFile; +static QStack<int> g_scopeStack; //!< 1 if bracket starts a scope, 2 for internal blocks static int g_anchorCount; static FileDef * g_sourceFileDef; static Definition * g_currentDefinition; @@ -122,10 +85,179 @@ static const char * g_currentFontClass; static bool g_searchingForBody; static bool g_insideBody; static int g_bodyCurlyCount; -static ClassDef * g_classVar; static QCString g_saveName; static QCString g_saveType; + +static int g_bracketCount = 0; +static int g_curlyCount = 0; +static int g_sharpCount = 0; + +static int g_lastSpecialCContext; +static int g_lastStringContext; static int g_memCallContext; +static int g_lastCContext; + +//------------------------------------------------------------------- + +/*! Represents a stack of variable to class mappings as found in the + * code. Each scope is enclosed in pushScope() and popScope() calls. + * Variables are added by calling addVariables() and one can search + * for variable using findVariable(). + */ +class VariableContext +{ + public: + class Scope : public SDict<ClassDef> + { + public: + Scope() : SDict<ClassDef>(17) {} + }; + + VariableContext() + { + m_scopes.setAutoDelete(TRUE); + } + virtual ~VariableContext() + { + } + + void pushScope() + { + m_scopes.append(new Scope); + DBG_CTX((stderr,"** Push var context %d\n",m_scopes.count())); + } + + void popScope() + { + if (m_scopes.count()>0) + { + DBG_CTX((stderr,"** Pop var context %d\n",m_scopes.count())); + m_scopes.remove(m_scopes.count()-1); + } + else + { + DBG_CTX((stderr,"** ILLEGAL: Pop var context\n")); + } + } + + void clear() + { + m_scopes.clear(); + m_globalScope.clear(); + } + + void clearExceptGlobal() + { + DBG_CTX((stderr,"** Clear var context\n")); + m_scopes.clear(); + } + + void addVariable(const QCString &type,const QCString &name); + ClassDef *findVariable(const QCString &name); + + Scope m_globalScope; + QList<Scope> m_scopes; +}; + +void VariableContext::addVariable(const QCString &type,const QCString &name) +{ + QCString ltype = type.simplifyWhiteSpace(); + QCString lname = name.simplifyWhiteSpace(); + if (ltype.isEmpty() || lname.isEmpty()) return; + DBG_CTX((stderr,"** AddVariable trying: type=%s name=%s\n",ltype.data(),lname.data())); + Scope *scope = m_scopes.count()==0 ? &m_globalScope : m_scopes.getLast(); + ClassDef *varType; + int i=0; + if ( + (varType=g_codeClassSDict[ltype]) || // look for class definitions inside the code block + (varType=getResolvedClass(g_currentDefinition,ltype)) // look for global class definitions + ) + { + DBG_CTX((stderr,"** AddVariable type=%s name=%s\n",ltype.data(),lname.data())); + scope->append(lname,varType); // add it to a list + } + else if ((i=ltype.find('<'))!=-1) + { + // probably a template class, try without arguments as well + addVariable(ltype.left(i),name); + } +} + +ClassDef *VariableContext::findVariable(const QCString &name) +{ + if (name.isEmpty()) return 0; + ClassDef *result = 0; + QListIterator<Scope> sli(m_scopes); + Scope *scope; + // search from inner to outer scope + for (sli.toLast();(scope=sli.current());--sli) + { + result = scope->find(name); + if (result) + { + DBG_CTX((stderr,"** findVariable(%s)=%p\n",name.data(),result)); + return result; + } + } + // nothing found -> also try the global scope + result=m_globalScope.find(name); + DBG_CTX((stderr,"** findVariable(%s)=%p\n",name.data(),result)); + return result; +} + +static VariableContext g_theVarContext; + +//------------------------------------------------------------------- + +class CallContext +{ + public: + CallContext() + { + m_classList.append(0); + } + virtual ~CallContext() {} + void setClass(ClassDef *cd) + { + DBG_CTX((stderr,"** Set call context %s (%p)\n",cd==0 ? "<null>" : cd->name().data(),cd)); + m_classList.removeLast(); + m_classList.append(cd); + } + void pushScope() + { + m_classList.append(0); + DBG_CTX((stderr,"** Push call context %d\n",m_classList.count())); + } + void popScope() + { + if (m_classList.count()>1) + { + DBG_CTX((stderr,"** Pop call context %d\n",m_classList.count())); + m_classList.removeLast(); + } + else + { + DBG_CTX((stderr,"** ILLEGAL: Pop call context\n")); + } + } + void clear() + { + DBG_CTX((stderr,"** Clear call context\n")); + m_classList.clear(); + m_classList.append(0); + } + ClassDef *getClass() const + { + return m_classList.getLast(); + } + + private: + QList<ClassDef> m_classList; +}; + +static CallContext g_theCallContext; + +//------------------------------------------------------------------- /*! add class/namespace name s to the scope */ static void pushScope(const char *s) @@ -318,99 +450,116 @@ static void addParmType() g_parmName.resize(0) ; } -static void addVariable() +void setParameterList(MemberDef *md) { - g_cvd.name=g_name.copy().simplifyWhiteSpace(); - g_cvd.type=g_type.copy().simplifyWhiteSpace(); - if (g_type.isEmpty()) + g_classScope = md->getClassDef() ? md->getClassDef()->name().data() : ""; + ArgumentList *al = md->argumentList(); + if (al==0) return; + Argument *a = al->first(); + while (a) { - return; + g_parmName = a->name.copy(); + g_parmType = a->type.copy(); + int i = g_parmType.find('*'); + if (i!=-1) g_parmType = g_parmType.left(i); + i = g_parmType.find('&'); + if (i!=-1) g_parmType = g_parmType.left(i); + if (g_parmType.left(6)=="const ") g_parmType = g_parmType.right(g_parmType.length()-6); + g_parmType=g_parmType.stripWhiteSpace(); + g_theVarContext.addVariable(g_parmType,g_parmName); + a = al->next(); } - else +} + +static ClassDef *stripClassName(const char *s) +{ + int pos=0; + QCString type = s; + QCString className; + QCString templSpec; + while (extractClassNameFromType(type,pos,className,templSpec)) { - int i; - if ((getResolvedClass(g_currentDefinition,g_cvd.type)) || (g_codeClassDict[g_cvd.type])) + QCString clName=className+templSpec; + ClassDef *cd=0; + if (!g_classScope.isEmpty()) { - //printf("adding variable `%s' `%s'\n",g_cvd.type.data(),g_cvd.name.data()); - g_cvd.classScope=g_classScope; - g_codeVarList.append(new CodeVarDef(g_cvd)); // add it to a list + cd=getResolvedClass(g_currentDefinition,g_classScope+"::"+clName); } - else if ((i=g_cvd.type.find('<'))>0) + if (cd==0) { - g_cvd.type = g_cvd.type.left(i); - if ((getResolvedClass(g_currentDefinition,g_cvd.type)) || (g_codeClassDict[g_cvd.type.left(i)])) - { - //printf("adding template type variable `%s' `%s'\n",g_cvd.type.data(),g_cvd.name.data()); - g_cvd.classScope=g_classScope; - g_codeVarList.append(new CodeVarDef(g_cvd)); - } + cd=getResolvedClass(g_currentDefinition,clName); + } + //printf("stripClass trying `%s' = %p\n",clName.data(),cd); + if (cd) + { + return cd; } - //printf("g_codeVarList.count()=%d\n",g_codeVarList.count()); } + + return 0; } -static void addParameter() +static MemberDef *setCallContextForVar(const QCString &name) { - g_cvd.name=g_parmName.copy().simplifyWhiteSpace(); - g_cvd.type=g_parmType.copy().simplifyWhiteSpace(); - //printf("searching for parameter `%s' `%s'\n",g_cvd.type.data(),g_cvd.name.data()); - if (g_cvd.type.isEmpty()) - { - return; - } - else + if (name.isEmpty()) return 0; + //printf("setCallContextForVar(%s)\n",name.data()); + + int scopeEnd = name.findRev("::"); + if (scopeEnd!=-1) // name with explicit scope { - if (g_cvd.type.left(7)=="struct ") g_cvd.type=g_cvd.type.right(g_cvd.type.length()-7); - int i; - if ((getResolvedClass(g_currentDefinition,g_cvd.type)) || (g_codeClassDict[g_cvd.type])) - { - //printf("adding parameter `%s' `%s'\n",g_cvd.type.data(),g_cvd.name.data()); - g_cvd.classScope=g_classScope; - g_codeParmList.append(new CodeVarDef(g_cvd)); // add it to a list - } - else if ((i=g_cvd.type.find('<'))>0) + QCString scope = name.left(scopeEnd); + QCString locName = name.right(name.length()-scopeEnd-2); + //printf("name=%s scope=%s\n",locName.data(),scope.data()); + ClassDef *mcd = getClass(scope); // TODO: check namespace as well + if (mcd && !locName.isEmpty()) { - g_cvd.type = g_cvd.type.left(i); - if ((getResolvedClass(g_currentDefinition,g_cvd.type)) || (g_codeClassDict[g_cvd.type.left(i)])) + MemberDef *md=mcd->getMemberByName(locName); + if (md) { - //printf("adding template type parameter `%s' `%s'\n",g_cvd.type.data(),g_cvd.name.data()); - g_cvd.classScope=g_classScope; - g_codeParmList.append(new CodeVarDef(g_cvd)); + //printf("name=%s scope=%s\n",locName.data(),scope.data()); + g_theCallContext.setClass(stripClassName(md->typeString())); + return md; } } - else + } + + MemberName *mn; + ClassDef *mcd = g_theVarContext.findVariable(name); + if (mcd) // local variable + { + //printf("local var `%s'\n",name.data()); + g_theCallContext.setClass(mcd); + return 0; + } + + // look for a class member + mcd = getClass(g_classScope); + if (mcd) + { + MemberDef *md=mcd->getMemberByName(name); + if (md) { - //printf("parameter `%s' `%s' not found!\n",g_cvd.type.data(),g_cvd.name.data()); + g_theCallContext.setClass(stripClassName(md->typeString())); + return md; } - //printf("g_codeParmList.count()=%d\n",g_codeParmList.count()); } -} -void setParameterList(MemberDef *md) -{ - g_classScope = md->getClassDef() ? md->getClassDef()->name().data() : ""; - ArgumentList *al = md->argumentList(); - if (al==0) return; - Argument *a = al->first(); - while (a) + // look for a global member + if ((mn=Doxygen::functionNameSDict[name])) { - g_parmName = a->name.copy(); - g_parmType = a->type.copy(); - int i = g_parmType.find('*'); - if (i!=-1) - g_parmType = g_parmType.left(i); - i = g_parmType.find('&'); - if (i!=-1) - g_parmType = g_parmType.left(i); - if (g_parmType.left(6)=="const ") - g_parmType = g_parmType.right(g_parmType.length()-6); - g_parmType=g_parmType.stripWhiteSpace(); - addParameter(); - a = al->next(); + //printf("global var `%s'\n",name.data()); + if (mn->count()>=1) + // TODO: if count>1 link to static members in the same file only + { + MemberDef *md=mn->getFirst(); + g_theCallContext.setClass(stripClassName(md->typeString())); + return md; + } } + return 0; } -static void generateClassLink(OutputDocInterface &ol,char *clName,int *clNameLen=0) +static void generateClassOrGlobalLink(OutputDocInterface &ol,char *clName,int *clNameLen=0) { int i=0; QCString className=clName; @@ -432,12 +581,9 @@ static void generateClassLink(OutputDocInterface &ol,char *clName,int *clNameLen if (cd->addExample(anchor,g_exampleName,g_exampleFile)) { ol.pushGeneratorState(); - //bool latexOn = ol.isEnabled(OutputGenerator::Latex); - //if (latexOn) ol.disable(OutputGenerator::Latex); ol.disable(OutputGenerator::Latex); ol.disable(OutputGenerator::RTF); ol.writeAnchor(0,anchor); - //if (latexOn) ol.enable(OutputGenerator::Latex); ol.popGeneratorState(); g_anchorCount++; } @@ -445,58 +591,38 @@ static void generateClassLink(OutputDocInterface &ol,char *clName,int *clNameLen writeMultiLineCodeLink(ol,cd->getReference(),cd->getOutputFileBase(),0,className); if (clNameLen) *clNameLen=className.length()-i-1; } - else + else { - MemberName *mn; - if (cd==0 && (mn=Doxygen::functionNameSDict[clName])) + if (cd==0) // not a class, see if it is a global enum/variable/typedef. { - if (mn->count()==1) + MemberDef *md = setCallContextForVar(clName); + if (md) { - MemberDef *md=mn->getFirst(); - Definition *d=md->getNamespaceDef(); - if (d==0) d=md->getFileDef(); + Definition *d=md->getOuterScope(); if (d && md->isLinkable()) { - writeMultiLineCodeLink(ol,d->getReference(),d->getOutputFileBase(),md->anchor(),clName); + writeMultiLineCodeLink(ol,d->getReference(),d->getOutputFileBase(),md->anchor(),clName); + if (g_currentMemberDef) + { + if (Config_getBool("REFERENCED_BY_RELATION")) + { + md->addSourceReferencedBy(g_currentMemberDef); + } + if (Config_getBool("REFERENCES_RELATION")) + { + g_currentMemberDef->addSourceReferences(md); + } + } return; } } } + codifyLines(clName); if (clNameLen) *clNameLen=className.length()-1; } } -static ClassDef *stripClassName(const char *s) -{ - QCString tmp=s; - if (tmp.isEmpty()) return 0; - static const QRegExp re("[a-z_A-Z][a-z_A-Z0-9:]*"); - int p=0,i,l; - while ((i=re.match(tmp,p,&l))!=-1) - { - ClassDef *cd=0; - QCString clName = tmp.mid(i,l); - //printf("g_classScope=`%s' clName=`%s'\n",g_classScope.data(),clName.data()); - if (!g_classScope.isEmpty()) - { - cd=getResolvedClass(g_currentDefinition,g_classScope+"::"+clName); - } - if (cd==0) - { - cd=getResolvedClass(g_currentDefinition,clName); - } - if (cd) - { - //printf("stripClassName(%s)=%s\n",s,cd->name().data()); - return cd; - } - p=i+l; - } - //printf("stripClassName(%s)=<null>\n",s); - return 0; -} - static bool getLink(const char *className, const char *memberName,OutputDocInterface &result, const char *text=0) @@ -536,14 +662,20 @@ static bool getLink(const char *className, if (d && d->isLinkable()) { - g_classVar = stripClassName(md->typeString()); + g_theCallContext.setClass(stripClassName(md->typeString())); if (g_currentDefinition && g_currentMemberDef && md!=g_currentMemberDef && g_insideBody) { - md->addSourceReference(g_currentMemberDef); + if (Config_getBool("REFERENCED_BY_RELATION")) + { + md->addSourceReferencedBy(g_currentMemberDef); + } + if (Config_getBool("REFERENCES_RELATION")) + { + g_currentMemberDef->addSourceReferences(md); + } } //printf("d->getOutputBase()=`%s' name=`%s' member name=`%s'\n",d->getOutputFileBase().data(),d->name().data(),md->name().data()); - //printf("g_classVar=`%s' type=`%s'\n",g_classVar ? g_classVar->name().data() : "none",md->typeString()); writeMultiLineCodeLink(result,d->getReference(),d->getOutputFileBase(), md->anchor(),text ? text : memberName); @@ -555,115 +687,90 @@ static bool getLink(const char *className, static bool generateClassMemberLink(OutputDocInterface &ol,ClassDef *mcd,const char *memName) { - //printf("generateClassMemberLink(class=%s,member=%s)\n",mcd->name().data(),memName); - MemberName *mmn=Doxygen::memberNameSDict[memName]; - if (mmn) + if (mcd) { - MemberNameIterator mmni(*mmn); - MemberDef *mmd,*xmd=0; - ClassDef *xcd=0; - const int maxInheritanceDepth = 100000; - int mdist=maxInheritanceDepth; - for (;(mmd=mmni.current());++mmni) - { - int m=minClassDistance(mcd,mmd->getClassDef()); - if (m<mdist && mmd->getClassDef()->isLinkable()) - { - mdist=m; - xcd=mmd->getClassDef(); - xmd=mmd; - } - } - if (mdist!=maxInheritanceDepth) + MemberDef *xmd = mcd->getMemberByName(memName); + //printf("generateClassMemberLink(class=%s,member=%s)=%p\n",mcd->name().data(),memName,xmd); + if (xmd) { // extract class definition of the return type in order to resolve // a->b()->c() like call chains - g_classVar = stripClassName(xmd->typeString()); - //printf("g_classVar=%s->%p\n",xmd->typeString(),g_classVar); + + //printf("type=`%s' args=`%s' class=%s\n", + // xmd->typeString(),xmd->argsString(), + // xmd->getClassDef()->name().data()); - // add usage reference - if (g_currentDefinition && g_currentMemberDef && - xmd!=g_currentMemberDef && g_insideBody) + g_theCallContext.setClass(stripClassName(xmd->typeString())); + + Definition *xd = xmd->getOuterScope(); + if (xd) { - xmd->addSourceReference(g_currentMemberDef); - } - // write the actual link - writeMultiLineCodeLink(ol,xcd->getReference(), - xcd->getOutputFileBase(),xmd->anchor(),memName); - return TRUE; + // add usage reference + if (g_currentDefinition && g_currentMemberDef && + xmd!=g_currentMemberDef && g_insideBody) + { + if (Config_getBool("REFERENCED_BY_RELATION")) + { + xmd->addSourceReferencedBy(g_currentMemberDef); + } + if (Config_getBool("REFERENCES_RELATION")) + { + g_currentMemberDef->addSourceReferences(xmd); + } + } + + // write the actual link + writeMultiLineCodeLink(ol,xd->getReference(), + xd->getOutputFileBase(),xmd->anchor(),memName); + return TRUE; + } } } + return FALSE; } -static void generateMemberLink(OutputDocInterface &ol,const char *varName, +static void generateMemberLink(OutputDocInterface &ol,const QCString &varName, char *memName) { //printf("generateMemberLink(object=%s,mem=%s) classScope=%s\n", - // varName,memName,g_classScope.data()); - CodeVarDef *cvd=g_codeParmList.last(); - while (cvd && cvd->name!=varName) - { - cvd=g_codeParmList.prev(); - } - if (!cvd) - { - cvd=g_codeVarList.last(); - while (cvd && cvd->name!=varName) cvd=g_codeVarList.prev(); - } - if (cvd) // variable found + // varName.data(),memName,g_classScope.data()); + + if (varName.isEmpty()) return; + + // look for the variable in the current context + ClassDef *vcd = g_theVarContext.findVariable(varName); + if (vcd) { - //printf("variable found type=%s!\n",cvd->type.data()); - CodeClassDef *ccd=g_codeClassDict[cvd->type]; - if (ccd) + //printf("Class found!\n"); + OutputDocInterface *result = ol.clone(); + if (getLink(vcd->name(),memName,*result)) { - //printf("Class found!\n"); - OutputDocInterface *result = ol.clone(); - if (getLink(ccd->name,memName,*result)) - { - //printf("Found result!\n"); - ol.append(result); - delete result; - return; - } - char *s=ccd->bases.first(); - while (s) - { - OutputDocInterface *result = ol.clone(); - if (getLink(s,memName,*result)) - { - //printf("Found result!\n"); - ol.append(result); - delete result; - return; - } - s=ccd->bases.next(); - } + //printf("Found result!\n"); + ol.append(result); + delete result; + return; } - else + BaseClassListIterator bcli(*vcd->baseClasses()); + for ( ; bcli.current() ; ++bcli) { - //printf("Class not found!\n"); OutputDocInterface *result = ol.clone(); - //printf("cvd->type=`%s'\n",cvd->type.data()); - if (getLink(cvd->type,memName,*result)) - { - ol.append(result); - } - else + if (getLink(bcli.current()->classDef->name(),memName,*result)) { - codifyLines(memName); + //printf("Found result!\n"); + ol.append(result); + delete result; + return; } - delete result; - return; } } - else + else // variable not in current context, maybe it is { - ClassDef *vcd = getResolvedClass(g_currentDefinition,g_classScope); + vcd = getResolvedClass(g_currentDefinition,g_classScope); if (vcd && vcd->isLinkable()) { - //printf("Found class %s for variable `%s'\n",g_classScope.data(),varName); + //printf("Found class %s for variable `%s'\n",g_classScope.data(),varName.data()); MemberName *vmn=Doxygen::memberNameSDict[varName]; if (vmn==0) { @@ -682,7 +789,7 @@ static void generateMemberLink(OutputDocInterface &ol,const char *varName, MemberDef *vmd; for (;(vmd=vmni.current());++vmni) { - if ((vmd->isVariable() || vmd->isFunction()) && + if (/*(vmd->isVariable() || vmd->isFunction()) && */ vmd->getClassDef()==jcd) { //printf("Found variable type=%s\n",vmd->typeString()); @@ -698,13 +805,13 @@ static void generateMemberLink(OutputDocInterface &ol,const char *varName, } if (vmn) { - //printf("There is a variable with name `%s'\n",varName); + //printf("There is a variable with name `%s'\n",varName); MemberNameIterator vmni(*vmn); MemberDef *vmd; for (;(vmd=vmni.current());++vmni) { - if ((vmd->isVariable() || vmd->isFunction()) && - vmd->getClassDef()==vcd) + if (/*(vmd->isVariable() || vmd->isFunction()) && */ + vmd->getClassDef()==vcd) { //printf("Found variable type=%s\n",vmd->typeString()); ClassDef *mcd=stripClassName(vmd->typeString()); @@ -724,7 +831,8 @@ static void generateMemberLink(OutputDocInterface &ol,const char *varName, static void generateFunctionLink(OutputDocInterface &ol,char *funcName) { OutputDocInterface *result = ol.clone(); - CodeClassDef *ccd=0; + //CodeClassDef *ccd=0; + ClassDef *ccd=0; QCString locScope=g_classScope.copy(); QCString locFunc=removeRedundantWhiteSpace(funcName); int i=locFunc.findRev("::"); @@ -742,19 +850,18 @@ static void generateFunctionLink(OutputDocInterface &ol,char *funcName) } } //printf("generateFunctionLink(%s) classScope=`%s'\n",locFunc.data(),locScope.data()); - if (!locScope.isEmpty() && (ccd=g_codeClassDict[locScope])) + if (!locScope.isEmpty() && (ccd=g_codeClassSDict[locScope])) { //printf("using classScope %s\n",g_classScope.data()); - char *s=ccd->bases.first(); - while (s) + BaseClassListIterator bcli(*ccd->baseClasses()); + for ( ; bcli.current() ; ++bcli) { - if (getLink(s,locFunc,*result,funcName)) + if (getLink(bcli.current()->classDef->name(),locFunc,*result,funcName)) { ol.append(result); delete result; return; } - s=ccd->bases.next(); } } if (getLink(locScope,locFunc,*result,funcName)) @@ -763,7 +870,8 @@ static void generateFunctionLink(OutputDocInterface &ol,char *funcName) } else { - codifyLines(funcName); + //codifyLines(funcName); + generateClassOrGlobalLink(ol,funcName); } delete result; return; @@ -845,6 +953,7 @@ TYPEKW ("bool"|"char"|"double"|"float"|"int"|"long"|"short"|"signed"|"unsigned" %x Bases %x SkipSharp %x ReadInclude +%x TemplDecl %% @@ -902,7 +1011,10 @@ TYPEKW ("bool"|"char"|"double"|"float"|"int"|"long"|"short"|"signed"|"unsigned" g_code->codify(yytext); } <Body>"{" { + g_theVarContext.pushScope(); + g_scopeStack.push(INNERBLOCK); + if (g_searchingForBody) { g_searchingForBody=FALSE; @@ -910,19 +1022,31 @@ TYPEKW ("bool"|"char"|"double"|"float"|"int"|"long"|"short"|"signed"|"unsigned" } g_code->codify(yytext); g_curlyCount++; - if (g_insideBody) g_bodyCurlyCount++; + if (g_insideBody) + { + g_bodyCurlyCount++; + } g_type.resize(0); g_name.resize(0); } <Body>"}" { - if (g_scopeStack.pop()==SCOPEBLOCK) popScope(); + g_theVarContext.popScope(); + + if (g_scopeStack.pop()==SCOPEBLOCK) + { + popScope(); + } + g_code->codify(yytext); + + // TODO: remove g_inClass=FALSE; if (--g_curlyCount<=0) { //g_classScope.resize(0); - g_codeParmList.clear(); + //g_codeParmList.clear(); } + if (--g_bodyCurlyCount<=0) { g_insideBody=FALSE; @@ -938,22 +1062,25 @@ TYPEKW ("bool"|"char"|"double"|"float"|"int"|"long"|"short"|"signed"|"unsigned" g_code->codify(yytext); } <ClassName>{ID} { - g_ccd.name=yytext; + //g_ccd.name=yytext; + g_curClassName=yytext; addType(); - generateClassLink(*g_code,yytext); + generateClassOrGlobalLink(*g_code,yytext); BEGIN( ClassVar ); } <ClassVar>{ID} { - g_type = g_ccd.name.copy(); + g_type = g_curClassName.copy(); g_name = yytext; - addVariable(); + g_theVarContext.addVariable(g_type,g_name); g_code->codify(yytext); } <ClassName,ClassVar>[ \t\n]*":"[ \t\n]* { codifyLines(yytext); + g_curClassBases.clear(); BEGIN( Bases ); } <Bases,ClassName,ClassVar>[ \t]*"{"[ \t]* { + g_theVarContext.pushScope(); g_code->codify(yytext); g_curlyCount++; g_inClass=TRUE; @@ -963,20 +1090,39 @@ TYPEKW ("bool"|"char"|"double"|"float"|"int"|"long"|"short"|"signed"|"unsigned" g_insideBody=TRUE; } if (g_insideBody) g_bodyCurlyCount++; - if (!g_ccd.name.isEmpty()) + if (!g_curClassName.isEmpty()) // valid class name { g_scopeStack.push(SCOPEBLOCK); - pushScope(g_ccd.name); - //g_classScope=g_ccd.name.copy(); - CodeClassDef *cd=new CodeClassDef(g_ccd); - //g_codeClassList.append(cd); - g_codeClassDict.insert(cd->name,cd); + pushScope(g_curClassName); + //CodeClassDef *cd=new CodeClassDef(g_ccd); + //g_codeClassDict.insert(cd->name,cd); + if (getResolvedClass(g_currentDefinition,g_curClassName)==0) + { + g_curClassDef=new ClassDef("<code>",1, + g_curClassName,ClassDef::Class); + g_codeClassSDict.append(g_curClassName,g_curClassDef); + // insert base classes. + char *s=g_curClassBases.first(); + while (s) + { + ClassDef *bcd; + bcd=g_codeClassSDict[s]; + if (bcd==0) bcd=getResolvedClass(g_currentDefinition,s); + if (bcd) + { + g_curClassDef->insertBaseClass(bcd,s,Public,Normal); + } + s=g_curClassBases.next(); + } + } //printf("g_codeClassList.count()=%d\n",g_codeClassList.count()); } - else + else // not a class name -> assume inner block { g_scopeStack.push(INNERBLOCK); } + g_curClassName.resize(0); + g_curClassBases.clear(); BEGIN( Body ); } <Bases>"virtual"|"public"|"protected"|"private" { @@ -986,8 +1132,8 @@ TYPEKW ("bool"|"char"|"double"|"float"|"int"|"long"|"short"|"signed"|"unsigned" } <Bases>{ID} { //printf("%s:addBase(%s)\n",g_ccd.name.data(),yytext); - g_ccd.bases.inSort(yytext); - generateClassLink(*g_code,yytext); + g_curClassBases.inSort(yytext); + generateClassOrGlobalLink(*g_code,yytext); } <Bases>"<" { g_code->codify(yytext); @@ -1011,7 +1157,7 @@ TYPEKW ("bool"|"char"|"double"|"float"|"int"|"long"|"short"|"signed"|"unsigned" <Body>{SCOPEPREFIX}?"operator"{B}*"()"{B}*/"(" { addType(); generateFunctionLink(*g_code,yytext); - g_bracketCount=1; + g_bracketCount=0; g_args.resize(0); g_name+=yytext; BEGIN( FuncCall ); @@ -1019,12 +1165,12 @@ TYPEKW ("bool"|"char"|"double"|"float"|"int"|"long"|"short"|"signed"|"unsigned" <Body>{SCOPEPREFIX}?"operator"{B}*[^\(\n]+/"(" { addType(); generateFunctionLink(*g_code,yytext); - g_bracketCount=1; + g_bracketCount=0; g_args.resize(0); g_name+=yytext; BEGIN( FuncCall ); } -<Body>"template"/([^a-zA-Z0-9]) { +<Body,TemplDecl>"template"/([^a-zA-Z0-9]) { startFontClass("keyword"); codifyLines(yytext); endFontClass(); @@ -1066,21 +1212,49 @@ TYPEKW ("bool"|"char"|"double"|"float"|"int"|"long"|"short"|"signed"|"unsigned" <Body>[\\|\)\+\-\/\%\~\!] { g_code->codify(yytext); g_name.resize(0);g_type.resize(0); + if (*yytext==')') + { + g_theCallContext.popScope(); + } } -<Body>{TYPEKW}/{B}* { +<Body,TemplDecl>{TYPEKW}/{B}* { startFontClass("keywordtype"); g_code->codify(yytext); endFontClass(); addType(); g_name+=yytext; } +<Body>"template"/{B}*"<"[^\n\/\-\.\{\"\>]*">"{B}* { // template<...> + startFontClass("keyword"); + g_code->codify(yytext); + endFontClass(); + g_sharpCount=0; + BEGIN(TemplDecl); + } +<TemplDecl>"class"|"typename" { + startFontClass("keyword"); + codifyLines(yytext); + endFontClass(); + } +<TemplDecl>"<" { + g_code->codify(yytext); + g_sharpCount++; + } +<TemplDecl>">" { + g_code->codify(yytext); + g_sharpCount--; + if (g_sharpCount<=0) + { + BEGIN(Body); + } + } <Body>{SCOPENAME}{B}*"<"[^\n\/\-\.\{\"\>]*">"/{B}* { // A<T> *pt; - generateClassLink(*g_code,yytext); + generateClassOrGlobalLink(*g_code,yytext); addType(); g_name+=yytext; } <Body>{SCOPENAME}/{B}* { // p->func() - generateClassLink(*g_code,yytext); + generateClassOrGlobalLink(*g_code,yytext); addType(); g_name+=yytext; } @@ -1095,7 +1269,8 @@ TYPEKW ("bool"|"char"|"double"|"float"|"int"|"long"|"short"|"signed"|"unsigned" <Body>{SCOPETNAME}/{B}*"(" { // a() or c::a() or t<A,B>::a() addType(); generateFunctionLink(*g_code,yytext); - g_bracketCount=1; + g_theVarContext.addVariable(g_type,yytext); + g_bracketCount=0; g_args.resize(0); g_name+=yytext; BEGIN( FuncCall ); @@ -1153,19 +1328,12 @@ TYPEKW ("bool"|"char"|"double"|"float"|"int"|"long"|"short"|"signed"|"unsigned" BEGIN( MemberCall ); } <MemberCall>{SCOPETNAME}/{B}*"(" { - //printf("g_name=`%s' g_classVar=`%s'\n",g_name.data(),g_classVar?g_classVar->name().data():"<none>"); - if (!g_name.isEmpty()) + if (g_theCallContext.getClass()) { - generateMemberLink(*g_code,g_name,yytext); - g_name=yytext; - } - else if (g_classVar) - { - if (!generateClassMemberLink(*g_code,g_classVar,yytext)) + if (!generateClassMemberLink(*g_code,g_theCallContext.getClass(),yytext)) { g_code->codify(yytext); } - g_classVar=0; g_name.resize(0); } else @@ -1185,19 +1353,12 @@ TYPEKW ("bool"|"char"|"double"|"float"|"int"|"long"|"short"|"signed"|"unsigned" } } <MemberCall>{SCOPENAME}/{B}* { - //printf("g_name=`%s' g_classVar=`%s'\n",g_name.data(),g_classVar?g_classVar->name().data():"<none>"); - if (!g_name.isEmpty()) - { - generateMemberLink(*g_code,g_name,yytext); - g_name=yytext; - } - else if (g_classVar) + if (g_theCallContext.getClass()) { - if (!generateClassMemberLink(*g_code,g_classVar,yytext)) + if (!generateClassMemberLink(*g_code,g_theCallContext.getClass(),yytext)) { g_code->codify(yytext); } - g_classVar=0; g_name.resize(0); } else @@ -1217,14 +1378,17 @@ TYPEKW ("bool"|"char"|"double"|"float"|"int"|"long"|"short"|"signed"|"unsigned" <Body>[,=;\[] { g_code->codify(yytext); g_saveName = g_name.copy(); - g_saveType = g_name.copy(); + g_saveType = g_type.copy(); if (!g_type.isEmpty()) { - addVariable(); + g_theVarContext.addVariable(g_type,g_name); + g_name.resize(0); + } + if (*yytext==';') + { + g_type.resize(0); g_name.resize(0); } - if (*yytext!=',') g_type.resize(0); - if (*yytext==';') g_name.resize(0); g_args.resize(0); } <Body>"]" { @@ -1260,24 +1424,34 @@ TYPEKW ("bool"|"char"|"double"|"float"|"int"|"long"|"short"|"signed"|"unsigned" g_code->codify(yytext); endFontClass(); } -<MemberCall2,FuncCall>[a-z_A-Z][:a-z_A-Z0-9]*({B}*"<"[^\n\>]*">")? { +<MemberCall2,FuncCall>[a-z_A-Z][:a-z_A-Z0-9]*({B}*"<"[^\n\<\>]*">")? { addParmType(); g_parmName=yytext; - generateClassLink(*g_code,yytext); + generateClassOrGlobalLink(*g_code,yytext); } <MemberCall2,FuncCall>, { g_code->codify(yytext); - addParameter(); + g_theVarContext.addVariable(g_parmType,g_parmName); g_parmType.resize(0);g_parmName.resize(0); } <MemberCall2,FuncCall>"(" { g_code->codify(yytext); g_bracketCount++; + g_theCallContext.pushScope(); + if (YY_START==FuncCall && !g_insideBody) + { + g_theVarContext.pushScope(); + } } <MemberCall2,FuncCall>")" { + g_theCallContext.popScope(); g_code->codify(yytext); if (--g_bracketCount<=0) { + if (!g_insideBody) + { + g_theVarContext.popScope(); + } g_name.resize(0);g_args.resize(0); g_parmType.resize(0);g_parmName.resize(0); BEGIN( Body ); @@ -1288,10 +1462,18 @@ TYPEKW ("bool"|"char"|"double"|"float"|"int"|"long"|"short"|"signed"|"unsigned" g_bracketCount=0; if (yytext[yyleng-1]==';') g_searchingForBody=FALSE; if (!g_inClass && !g_type.isEmpty()) - addVariable(); + { + g_theVarContext.addVariable(g_type,g_name); + } g_parmType.resize(0);g_parmName.resize(0); + g_theCallContext.popScope(); + g_theCallContext.setClass(0); if (yytext[yyleng-1]==';' || g_insideBody) { + if (!g_insideBody) + { + g_theVarContext.popScope(); + } g_name.resize(0);g_type.resize(0); BEGIN( Body ); } @@ -1302,7 +1484,12 @@ TYPEKW ("bool"|"char"|"double"|"float"|"int"|"long"|"short"|"signed"|"unsigned" } } <MemberCall2,FuncCall>")"({BN}"const"|"volatile")*{BN}*"{" { - addParameter(); + if (g_insideBody) + { + g_theVarContext.pushScope(); + } + g_theVarContext.addVariable(g_parmType,g_parmName); + g_theCallContext.popScope(); g_parmType.resize(0);g_parmName.resize(0); if (g_name.find("::")!=-1) { @@ -1356,14 +1543,15 @@ TYPEKW ("bool"|"char"|"double"|"float"|"int"|"long"|"short"|"signed"|"unsigned" BEGIN( Body ); } <SkipInits>{ID} { - generateClassLink(*g_code,yytext); + generateClassOrGlobalLink(*g_code,yytext); } <FuncCall>([a-z_A-Z][a-z_A-Z0-9]*)/"(" { generateFunctionLink(*g_code,yytext); } <FuncCall>([a-z_A-Z][a-z_A-Z0-9]*)/("."|"->") { - g_code->codify(yytext); + //g_code->codify(yytext); g_name=yytext; + generateClassOrGlobalLink(*g_code,yytext); BEGIN( MemberCall2 ); } <FuncCall,MemberCall2>("("{B}*("*"{B}*)*[a-z_A-Z][a-z_A-Z0-9]*{B}*")"{B}*)/("."|"->") { @@ -1377,13 +1565,14 @@ TYPEKW ("bool"|"char"|"double"|"float"|"int"|"long"|"short"|"signed"|"unsigned" if (!g_args.isEmpty()) generateMemberLink(*g_code,g_args,yytext); else - g_code->codify(yytext); + generateClassOrGlobalLink(*g_code,yytext); g_args.resize(0); BEGIN( FuncCall ); } <MemberCall2>([a-z_A-Z][a-z_A-Z0-9]*)/([ \t\n]*("."|"->")) { - g_code->codify(yytext); + //g_code->codify(yytext); g_name=yytext; + generateClassOrGlobalLink(*g_code,yytext); BEGIN( MemberCall2 ); } <MemberCall2>"->"|"." { @@ -1637,6 +1826,14 @@ TYPEKW ("bool"|"char"|"double"|"float"|"int"|"long"|"short"|"signed"|"unsigned" g_lastCContext = YY_START ; BEGIN( SkipCxxComment ) ; } +<*>"(" { + g_code->codify(yytext); + g_theCallContext.pushScope(); + } +<*>")" { + g_code->codify(yytext); + g_theCallContext.popScope(); + } <*>\n { codifyLines(yytext); } @@ -1660,13 +1857,10 @@ TYPEKW ("bool"|"char"|"double"|"float"|"int"|"long"|"short"|"signed"|"unsigned" void initParseCodeContext() { - g_codeClassDict.setAutoDelete(TRUE); - g_codeVarList.setAutoDelete(TRUE); - g_codeParmList.setAutoDelete(TRUE); - g_codeClassDict.clear(); - g_codeVarList.clear(); - g_codeParmList.clear(); - g_ccd.bases.clear(); + g_theVarContext.clear(); + g_codeClassSDict.setAutoDelete(TRUE); + g_codeClassSDict.clear(); + g_curClassBases.clear(); g_anchorCount = 0; } @@ -1692,7 +1886,7 @@ void parseCode(OutputDocInterface &od,const char *className,const QCString &s, g_bracketCount = 0; g_sharpCount = 0; g_insideTemplate = FALSE; - g_classVar = 0; + g_theCallContext.clear(); g_scopeStack.clear(); g_classScope = className; g_exampleBlock = exBlock; diff --git a/src/config.l b/src/config.l index 456330b..5094011 100644 --- a/src/config.l +++ b/src/config.l @@ -1307,18 +1307,6 @@ void Config::create() FALSE ); cb = addBool( - "SOURCE_BROWSER", - "If the SOURCE_BROWSER tag is set to YES then a list of source files will \n" - "be generated. Documented entities will be cross-referenced with these sources. \n", - FALSE - ); - cb = addBool( - "INLINE_SOURCES", - "Setting the INLINE_SOURCES tag to YES will include the body \n" - "of functions and classes directly in the documentation. \n", - FALSE - ); - cb = addBool( "STRIP_CODE_COMMENTS", "Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct \n" "doxygen to hide any special comment blocks from generated source code \n" @@ -1557,6 +1545,14 @@ void Config::create() "and *.h) to filter out the source-files in the directories. If left \n" "blank all files are included. \n" ); + cb = addBool( + "EXAMPLE_RECURSIVE", + "If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be \n" + "searched for input files to be used with the \\include or \\dontinclude \n" + "commands irrespective of the value of the RECURSIVE tag. \n" + "Possible values are YES and NO. If left blank NO is used. \n", + FALSE + ); cl = addList( "IMAGE_PATH", "The IMAGE_PATH tag can be used to specify one or more files or \n" @@ -1581,7 +1577,35 @@ void Config::create() "files to browse. \n", FALSE ); - + //----------------------------------------------------------------------------------------------- + addInfo( "Source Browser","configuration options related to source browsing"); + //----------------------------------------------------------------------------------------------- + cb = addBool( + "SOURCE_BROWSER", + "If the SOURCE_BROWSER tag is set to YES then a list of source files will \n" + "be generated. Documented entities will be cross-referenced with these sources. \n", + FALSE + ); + cb = addBool( + "INLINE_SOURCES", + "Setting the INLINE_SOURCES tag to YES will include the body \n" + "of functions and classes directly in the documentation. \n", + FALSE + ); + cb = addBool( "REFERENCED_BY_RELATION", + "If the REFERENCED_BY_RELATION tag is set to YES (the default) \n" + "then for each documented function all documented \n" + "functions referencing it will be listed. \n", + TRUE + ); + cb->addDependency("SOURCE_BROWSER"); + cb = addBool( "REFERENCES_RELATION", + "If the REFERENCES_RELATION tag is set to YES (the default) \n" + "then for each documented function all documented entities \n" + "called/used by that function will be listed. \n", + TRUE + ); + cb->addDependency("SOURCE_BROWSER"); //----------------------------------------------------------------------------------------------- addInfo( "Index","configuration options related to the alphabetical class index"); //----------------------------------------------------------------------------------------------- diff --git a/src/definition.cpp b/src/definition.cpp index 06d4da7..7597ead 100644 --- a/src/definition.cpp +++ b/src/definition.cpp @@ -44,8 +44,8 @@ Definition::Definition(const char *df,int dl, m_sectionDict=0, m_startBodyLine=m_endBodyLine=-1, m_bodyDef=0; - m_sourceRefList=0; - m_sourceRefDict=0; + m_sourceRefByDict=0; + m_sourceRefsDict=0; m_todoId=0; m_testId=0; m_bugId=0; @@ -55,8 +55,8 @@ Definition::Definition(const char *df,int dl, Definition::~Definition() { delete m_sectionDict; - delete m_sourceRefList; - delete m_sourceRefDict; + delete m_sourceRefByDict; + delete m_sourceRefsDict; } @@ -346,16 +346,17 @@ void Definition::writeInlineCode(OutputList &ol,const char *scopeName) /*! Write a reference to the source code fragments in which this * definition is used. */ -void Definition::writeSourceRefs(OutputList &ol,const char *scopeName) +void Definition::writeSourceRefList(OutputList &ol,const char *scopeName, + const QCString &text,MemberSDict *members) { ol.pushGeneratorState(); - if (Config_getBool("SOURCE_BROWSER") && m_sourceRefList) + if (Config_getBool("SOURCE_BROWSER") && members) { ol.newParagraph(); - parseText(ol,theTranslator->trReferencedBy()); + parseText(ol,text); ol.docify(" "); - QCString ldefLine=theTranslator->trWriteList(m_sourceRefList->count()); + QCString ldefLine=theTranslator->trWriteList(members->count()); QRegExp marker("@[0-9]+"); int index=0,newIndex,matchLen; @@ -365,7 +366,7 @@ void Definition::writeSourceRefs(OutputList &ol,const char *scopeName) bool ok; parseText(ol,ldefLine.mid(index,newIndex-index)); uint entryIndex = ldefLine.mid(newIndex+1,matchLen-1).toUInt(&ok); - MemberDef *md=m_sourceRefList->at(entryIndex); + MemberDef *md=members->at(entryIndex); if (ok && md) { QCString scope=md->getScopeString(); @@ -391,11 +392,27 @@ void Definition::writeSourceRefs(OutputList &ol,const char *scopeName) ol.docify(name); ol.popGeneratorState(); } + else if (md->isLinkable() && md->getOuterScope()) + { + Definition *d = md->getOuterScope(); + // for HTML write a real link + ol.pushGeneratorState(); + ol.disableAllBut(OutputGenerator::Html); + ol.writeObjectLink(d->getReference(),d->getOutputFileBase(), + md->anchor(),name); + ol.popGeneratorState(); + + // for the other output formats just mention the name + ol.pushGeneratorState(); + ol.disable(OutputGenerator::Html); + ol.docify(name); + ol.popGeneratorState(); + } else { ol.docify(name); } - ol.docify("()"); + if (md->isFunction()) ol.docify("()"); } index=newIndex+matchLen; } @@ -406,6 +423,16 @@ void Definition::writeSourceRefs(OutputList &ol,const char *scopeName) ol.popGeneratorState(); } +void Definition::writeSourceReffedBy(OutputList &ol,const char *scopeName) +{ + writeSourceRefList(ol,scopeName,theTranslator->trReferencedBy(),m_sourceRefByDict); +} + +void Definition::writeSourceRefs(OutputList &ol,const char *scopeName) +{ + writeSourceRefList(ol,scopeName,theTranslator->trReferences(),m_sourceRefsDict); +} + bool Definition::hasDocumentation() const { return !m_doc.isEmpty() || // has detailed docs @@ -413,27 +440,48 @@ bool Definition::hasDocumentation() const Config_getBool("EXTRACT_ALL"); // extract everything } -void Definition::addSourceReference(MemberDef *md) +void Definition::addSourceReferencedBy(MemberDef *md) { if (md) { - QCString name=md->name(); - QCString scope=md->getScopeString(); + QCString name = md->name(); + QCString scope = md->getScopeString(); if (!scope.isEmpty()) { name.prepend(scope+"::"); } - if (m_sourceRefList==0) + if (m_sourceRefByDict==0) { - m_sourceRefDict = new MemberDict(53); - m_sourceRefList = new MemberList; + m_sourceRefByDict = new MemberSDict; } - if (m_sourceRefDict->find(name)==0) + if (m_sourceRefByDict->find(name)==0) { - m_sourceRefDict->insert(name,md); - m_sourceRefList->inSort(md); + m_sourceRefByDict->inSort(name,md); + } + } +} + +void Definition::addSourceReferences(MemberDef *md) +{ + if (md) + { + QCString name = md->name(); + QCString scope = md->getScopeString(); + + if (!scope.isEmpty()) + { + name.prepend(scope+"::"); + } + + if (m_sourceRefsDict==0) + { + m_sourceRefsDict = new MemberSDict; + } + if (m_sourceRefsDict->find(name)==0) + { + m_sourceRefsDict->inSort(name,md); } } } @@ -475,3 +523,10 @@ QCString Definition::localName() const return m_localName; } +void Definition::setBodySegment(int bls,int ble) +{ + //printf("setBodySegment(%d,%d) for %s\n",bls,ble,name().data()); + m_startBodyLine=bls; + m_endBodyLine=ble; +} + diff --git a/src/definition.h b/src/definition.h index 090dcd5..b98f0f2 100644 --- a/src/definition.h +++ b/src/definition.h @@ -24,8 +24,9 @@ class FileDef; class OutputList; class SectionDict; -class MemberList; -class MemberDict; +//class MemberList; +//class MemberDict; +class MemberSDict; class MemberDef; /*! The common base class of all entity definitions found in the sources. */ @@ -90,11 +91,7 @@ class Definition void writeDocAnchorsToTagFile(); // source references - void setBodySegment(int bls,int ble) - { - m_startBodyLine=bls; - m_endBodyLine=ble; - } + void setBodySegment(int bls,int ble); void setBodyDef(FileDef *fd) { m_bodyDef=fd; } int getStartBodyLine() const { return m_startBodyLine; } int getEndBodyLine() const { return m_endBodyLine; } @@ -102,7 +99,9 @@ class Definition void writeSourceDef(OutputList &ol,const char *scopeName); void writeInlineCode(OutputList &ol,const char *scopeName); void writeSourceRefs(OutputList &ol,const char *scopeName); - void addSourceReference(MemberDef *d); + void writeSourceReffedBy(OutputList &ol,const char *scopeName); + void addSourceReferencedBy(MemberDef *d); + void addSourceReferences(MemberDef *d); void setRefItems(int todoId,int testId,int bugId) { @@ -141,14 +140,18 @@ class Definition // in the future m_name should become m_localName private: + void writeSourceRefList(OutputList &ol,const char *scopeName, + const QCString &text,MemberSDict *members); //QCString m_qualifiedName; // name of the definition QCString m_brief; // brief description QCString m_doc; // detailed description QCString m_ref; // reference to external documentation SectionDict *m_sectionDict; // dictionary of all sections - MemberList *m_sourceRefList; // list of entities that refer to this - // entity in their definition - MemberDict *m_sourceRefDict; + //MemberList *m_sourceRefList; // list of entities that refer to this + // // entity in their definition + //MemberDict *m_sourceRefDict; + MemberSDict *m_sourceRefByDict; + MemberSDict *m_sourceRefsDict; int m_testId; // id for test list item int m_todoId; // id for todo list item int m_bugId; // id for bug list item @@ -1,6 +1,6 @@ /***************************************************************************** * - * $Id$ + * * * Copyright (C) 1997-2001 by Dimitri van Heesch. * @@ -632,7 +632,9 @@ static void forceEndItemList() endBlock(); } else + { outDoc->endDescription(); + } break; } } @@ -1154,9 +1156,9 @@ OPMASK ({B}*{OPNORM}({OPARG}?))|({OPCAST}{OPARG}) insideArgumentList=TRUE; } } -<DocScan>(({B}*"\n"){2,}{B}*)?{CMD}"par"{B}* { +<DocScan>(({B}*"\n"){2,}{B}*)?{CMD}"par"{B}* { QCString t=yytext; - if (t.contains('\n')>1 && insideItemList) + if (/*t.contains('\n')>1 &&*/ insideItemList) { forceEndItemList(); } @@ -1496,7 +1498,7 @@ OPMASK ({B}*{OPNORM}({OPARG}?))|({OPCAST}{OPARG}) } <DocScan>(({B}*"\n"){2,}{B}*)?{CMD}"param"{BSEP} { QCString t=yytext; - if (t.contains('\n')>1 && insideItemList) + if (/*t.contains('\n')>1 &&*/ insideItemList) { forceEndItemList(); } @@ -1520,7 +1522,7 @@ OPMASK ({B}*{OPNORM}({OPARG}?))|({OPCAST}{OPARG}) } <DocScan>(({B}*"\n"){2,}{B}*)?{CMD}"retval"{BSEP} { QCString t=yytext; - if (t.contains('\n')>1 && insideItemList) + if (/*t.contains('\n')>1 &&*/ insideItemList) { forceEndItemList(); } @@ -1544,7 +1546,7 @@ OPMASK ({B}*{OPNORM}({OPARG}?))|({OPCAST}{OPARG}) } <DocScan>(({B}*"\n"){2,}{B}*)?{CMD}("exception"|"throw")s?{BSEP} { QCString t=yytext; - if (t.contains('\n')>1 && insideItemList) + if (/*t.contains('\n')>1 &&*/ insideItemList) { forceEndItemList(); } @@ -1766,7 +1768,7 @@ OPMASK ({B}*{OPNORM}({OPARG}?))|({OPCAST}{OPARG}) <DocImage>[rR][tT][fF] { BEGIN(DocRtfImageName); } -<DocHtmlImageName>{FILE}|{URLMASK} { +<DocHtmlImageName>[^ \t\n]+ { curImageName = findAndCopyImage(stripQuotes(yytext),IT_Html); curImageCaption.resize(0); if (curImageName.isEmpty()) @@ -2390,6 +2392,7 @@ OPMASK ({B}*{OPNORM}({OPARG}?))|({OPCAST}{OPARG}) { insideArgumentList=FALSE; outDoc->endItemList(); + if (ib) endBlock(); } else if (insideItemList) { @@ -2405,8 +2408,8 @@ OPMASK ({B}*{OPNORM}({OPARG}?))|({OPCAST}{OPARG}) { outDoc->newParagraph(); } + if (ib) endBlock(); } - if (ib) endBlock(); } <DocScan>{BN}+/\n { outDoc->writeChar(' '); @@ -2472,6 +2475,7 @@ void scanDoc(const char *s) void internalParseDocument(const char *s) { + if (s==0) return; const char *oldInputString = inputString; int oldInputPosition = inputPosition; int oldRule = YY_START; diff --git a/src/doxygen.cpp b/src/doxygen.cpp index 9d3788f..005fb56 100644 --- a/src/doxygen.cpp +++ b/src/doxygen.cpp @@ -4958,7 +4958,7 @@ static void addSourceReferences() for (mni.toFirst();(md=mni.current());++mni) { NamespaceDef *nd=md->getNamespaceDef(); - FileDef *fd=md->getBodyDef(); + FileDef *fd=md->getFileDef(); GroupDef *gd=md->getGroupDef(); if (fd && md->getStartBodyLine()!=-1 && md->isLinkableInProject() && ((nd && nd->isLinkableInProject()) || @@ -6075,7 +6075,8 @@ static int readDir(QFileInfo *fi, QStrList *exclPatList, StringList *resultList, StringDict *resultDict, - bool errorIfNotExist + bool errorIfNotExist, + bool recursive ) { QDir dir((const char *)fi->absFilePath()); @@ -6126,13 +6127,14 @@ static int readDir(QFileInfo *fi, if (resultList) resultList->append(rs); if (resultDict) resultDict->insert(cfi->absFilePath(),rs); } - else if (Config_getBool("RECURSIVE") && + else if (recursive && cfi->isDir() && cfi->fileName()!="." && cfi->fileName()!="..") { cfi->setFile(cfi->absFilePath()); totalSize+=readDir(cfi,fnList,fnDict,exclDict, - patList,exclPatList,resultList,resultDict,errorIfNotExist); + patList,exclPatList,resultList,resultDict,errorIfNotExist, + recursive); } } ++it; @@ -6188,6 +6190,7 @@ static int readFileOrDirectory(const char *s, QStrList *exclPatList, StringList *resultList, StringDict *resultDict, + bool recursive, bool errorIfNotExist=TRUE ) { @@ -6233,7 +6236,8 @@ static int readFileOrDirectory(const char *s, } else if (fi.isDir()) // readable dir totalSize+=readDir(&fi,fnList,fnDict,exclDict,patList, - exclPatList,resultList,resultDict,errorIfNotExist); + exclPatList,resultList,resultDict,errorIfNotExist, + recursive); } } return totalSize; @@ -6615,7 +6619,9 @@ void parseInput() compoundKeywordDict.insert("union",(void *)8); compoundKeywordDict.insert("interface",(void *)8); compoundKeywordDict.insert("exception",(void *)8); - + + bool alwaysRecursive = Config_getBool("RECURSIVE"); + /************************************************************************** * Read and preprocess input * **************************************************************************/ @@ -6632,7 +6638,8 @@ void parseInput() pl = Config_getList("FILE_PATTERNS"); } readFileOrDirectory(s,0,Doxygen::includeNameDict,0,&pl, - &Config_getList("EXCLUDE_PATTERNS"),0,0); + &Config_getList("EXCLUDE_PATTERNS"),0,0, + alwaysRecursive); s=includePathList.next(); } @@ -6643,7 +6650,8 @@ void parseInput() { readFileOrDirectory(s,0,Doxygen::exampleNameDict,0, &Config_getList("EXAMPLE_PATTERNS"), - 0,0,0); + 0,0,0, + (alwaysRecursive || Config_getBool("EXAMPLE_RECURSIVE"))); s=examplePathList.next(); } @@ -6653,17 +6661,27 @@ void parseInput() while (s) { readFileOrDirectory(s,0,Doxygen::imageNameDict,0,0, - 0,0,0); + 0,0,0, + alwaysRecursive); s=imagePathList.next(); } + QDictIterator<FileName> fndi(*Doxygen::imageNameDict); + FileName *fn; + for (;(fn=fndi.current());++fndi) + { + printf("File Name %s\n",fn->fileName()); + } + + msg("Searching for dot files...\n"); QStrList &dotFileList=Config_getList("DOTFILE_DIRS"); s=dotFileList.first(); while (s) { readFileOrDirectory(s,0,Doxygen::dotFileNameDict,0,0, - 0,0,0); + 0,0,0, + alwaysRecursive); s=dotFileList.next(); } @@ -6673,7 +6691,9 @@ void parseInput() while (s) { readFileOrDirectory(s,0,0,0,&Config_getList("FILE_PATTERNS"), - 0,0,&excludeNameDict,FALSE); + 0,0,&excludeNameDict, + alwaysRecursive, + FALSE); s=excludeList.next(); } @@ -6692,7 +6712,8 @@ void parseInput() Doxygen::inputNameDict,&excludeNameDict, &Config_getList("FILE_PATTERNS"), &Config_getList("EXCLUDE_PATTERNS"), - &inputFiles,0); + &inputFiles,0, + alwaysRecursive); s=inputList.next(); } diff --git a/src/htmlgen.cpp b/src/htmlgen.cpp index e3ec9e3..3bf5fb3 100644 --- a/src/htmlgen.cpp +++ b/src/htmlgen.cpp @@ -637,13 +637,13 @@ void HtmlGenerator::writeFormula(const char *n,const char *text) { if (text && text[0]=='\\') t << "<p><center>" << endl; t << "<img align="; -#if !defined(_WIN32) - t << "\"top\""; // assume Unix users use Netscape 4.x which does - // not seem to support align == "middle" :-(( -#else +//#if !defined(_WIN32) +// t << "\"top\""; // assume Unix users use Netscape 4.x which does +// // not seem to support align == "middle" :-(( +//#else t << "\"middle\""; // assume Windows users use IE or HtmlHelp which only // displays formulas nicely with align == "middle" -#endif +//#endif t << " src=\"" << n << "\">" << endl; if (text && text[0]=='\\') t << "</center><p>" << endl; } diff --git a/src/index.cpp b/src/index.cpp index 3a9fa12..afcd154 100644 --- a/src/index.cpp +++ b/src/index.cpp @@ -2134,9 +2134,19 @@ void writePageIndex(OutputList &ol) ftvHelp->incContentsDepth(); } parseText(ol,theTranslator->trRelatedPagesDescription()); - //ol.newParagraph(); ol.endTextBlock(); - ol.startItemList(); + { + // UGLY HACK! + ol.pushGeneratorState(); + ol.disable(OutputGenerator::Man); + ol.disable(OutputGenerator::Html); + ol.startIndexList(); + ol.enableAll(); + ol.disable(OutputGenerator::Latex); + ol.disable(OutputGenerator::RTF); + ol.startItemList(); + ol.popGeneratorState(); + } PageSDict::Iterator pdi(*Doxygen::pageSDict); PageInfo *pi=0; for (pdi.toFirst();(pi=pdi.current());++pdi) @@ -2162,15 +2172,23 @@ void writePageIndex(OutputList &ol) ol.docify(" [external]"); ol.endTypewriter(); } - //ol.writeStartAnnoItem("pages",pageName,0,pageTitle); - ////ol.writeObjectLink(0,pageName,0,pageTitle); - //ol.writeEndAnnoItem(pageName); ol.writeString("\n"); if (hasHtmlHelp) htmlHelp->addContentsItem(FALSE,pageTitle,pageName); if (hasFtvHelp) ftvHelp->addContentsItem(FALSE,0,pageName,0,pageTitle); } } - ol.endItemList(); + { + // UGLY HACK! + ol.pushGeneratorState(); + ol.disable(OutputGenerator::Man); + ol.disable(OutputGenerator::Html); + ol.endIndexList(); + ol.enableAll(); + ol.disable(OutputGenerator::Latex); + ol.disable(OutputGenerator::RTF); + ol.endItemList(); + ol.popGeneratorState(); + } if (hasHtmlHelp) { htmlHelp->decContentsDepth(); @@ -2273,7 +2291,7 @@ void writeGroupTreeNode(OutputList &ol, GroupDef *gd,bool subLevel) htmlHelp->addContentsItem(isDir,gd->groupTitle(),gd->getOutputFileBase()); htmlHelp->incContentsDepth(); } - if(ftvHelp) + if (ftvHelp) { ftvHelp->addContentsItem(isDir,gd->getReference(),gd->getOutputFileBase(), 0,gd->groupTitle()); diff --git a/src/latexgen.cpp b/src/latexgen.cpp index 7b2b2bb..0f24f6e 100644 --- a/src/latexgen.cpp +++ b/src/latexgen.cpp @@ -199,6 +199,13 @@ void LatexGenerator::init() << "\tmakeindex refman.idx" << endl << "\techo \"Rerunning latex....\"" << endl << "\tlatex refman.tex" << endl + << "\tlatex_count=5" << endl + << "\twhile egrep -s 'Rerun (LaTeX|to get cross-references right)' refman.log && [ $latex_count -gt 0 ] ;\\" << endl + << "\t do \\" << endl + << "\t echo \"Rerunning latex....\" ;\\" << endl + << "\t latex refman.tex ;\\" << endl + << "\t latex_count=`expr $latex_count - 1` ;\\" << endl + << "\t done" << endl << endl << "clean:" << endl << "\trm -f *.ps *.dvi *.aux *.toc *.idx *.ind *.ilg *.log *.out" << endl; } @@ -1257,6 +1264,119 @@ void LatexGenerator::writeSectionRefItem(const char *,const char *lab, // docifyStatic(t,str); //} +/*! + * Function converts Latin2 character to latex strin] representin the same + * character. + */ +void LatexGenerator::latin2ToLatex(unsigned char c) +{ + switch (c) + { + case 0xA1: t << c; break; + case 0xA2: t << c; break; + case 0xA3: t << c; break; + case 0xA4: t << c; break; + case 0xA5: t << c; break; + case 0xA6: t << "\\'{S}"; break; + case 0xA7: t << c; break; + case 0xA8: t << c; break; + case 0xA9: t << "\\v{S}"; break; + case 0xAA: t << "\\c{S}"; break; + case 0xAB: t << "\\v{T}"; break; + case 0xAC: t << "\\'{Z}"; break; + case 0xAD: t << c; break; + case 0xAE: t << "\\v{Z}"; break; + case 0xAF: t << "\\.{Z}"; break; + + case 0xB0: t << c; break; + case 0xB1: t << c; break; + case 0xB2: t << c; break; + case 0xB3: t << c; break; + case 0xB4: t << c; break; + case 0xB5: t << c; break; + case 0xB6: t << "\\'{s}"; break; + case 0xB7: t << c; break; + case 0xB8: t << c; break; + case 0xB9: t << "\\v{s}"; break; + case 0xBA: t << "\\c{s}"; break; + case 0xBB: t << "\\v{t}"; break; + case 0xBC: t << "\\'{z}"; break; + case 0xBD: t << c; break; + case 0xBE: t << "\\v{z}"; break; + case 0xBF: t << "\\.{z}"; break; + + case 0xC0: t << "\\'{R}"; break; + case 0xC1: t << "\\'{A}"; break; + case 0xC2: t << "\\^{A}"; break; + case 0xC3: t << "\\u{A}"; break; + case 0xC4: t << "\\\"{A}"; break; + case 0xC5: t << "\\'{L}"; break; + case 0xC6: t << "\\'{C}"; break; + case 0xC7: t << "\\c{C}"; break; + case 0xC8: t << "\\v{C}"; break; + case 0xC9: t << "\\'{E}"; break; + case 0xCA: t << "\\c{E}"; break; + case 0xCB: t << "\\\"{E}"; break; + case 0xCC: t << "\\v{E}"; break; + case 0xCD: t << "\\'{I}"; break; + case 0xCE: t << "\\^{I}"; break; + case 0xCF: t << "\\v{D}"; break; + + case 0xD0: t << "\\bar{D}"; break; + case 0xD1: t << "\\'{N}"; break; + case 0xD2: t << "\\v{N}"; break; + case 0xD3: t << "\\'{O}"; break; + case 0xD4: t << "\\^{O}"; break; + case 0xD5: t << "\\H{O}"; break; + case 0xD6: t << "\\\"{O}"; break; + case 0xD7: t << c; break; + case 0xD8: t << "\\v{R}"; break; + case 0xD9: t << c; break; + case 0xDA: t << "\\'{U}"; break; + case 0xDB: t << "\\H{U}"; break; + case 0xDC: t << "\\\"{U}"; break; + case 0xDD: t << "\\'{Y}"; break; + case 0xDE: t << "\\c{T}"; break; + case 0xDF: t << "\\ss"; break; + + case 0xE0: t << "\\'{r}"; break; + case 0xE1: t << "\\'{a}"; break; + case 0xE2: t << "\\^{a}"; break; + case 0xE3: t << c; break; + case 0xE4: t << "\\\"{a}"; break; + case 0xE5: t << "\\'{l}"; break; + case 0xE6: t << "\\'{c}"; break; + case 0xE7: t << "\\c{c}"; break; + case 0xE8: t << "\\v{c}"; break; + case 0xE9: t << "\\'{e}"; break; + case 0xEA: t << c; break; + case 0xEB: t << "\\\"{e}"; break; + case 0xEC: t << "\\v{e}"; break; + case 0xED: t << "\\'{\\i}"; break; + case 0xEE: t << "\\^{\\i}"; break; + case 0xEF: t << "\\v{d}"; break; + + case 0xF0: t << "\\bar{d}"; break; + case 0xF1: t << "\\'{n}"; break; + case 0xF2: t << "\\v{n}"; break; + case 0xF3: t << "\\'{o}"; break; + case 0xF4: t << "\\^{o}"; break; + case 0xF5: t << "\\H{o}"; break; + case 0xF6: t << "\\\"{o}"; break; + case 0xF7: t << c; break; + case 0xF8: t << "\\v{r}"; break; + case 0xF9: t << c; break; + case 0xFA: t << "\\'{u}"; break; + case 0xFB: t << "\\H{u}"; break; + case 0xFC: t << "\\\"{u}"; break; + case 0xFD: t << "\\'{y}"; break; + case 0xFE: t << c; break; + case 0xFF: t << c; break; + + default: t << c; + } +} + //void LatexGenerator::docifyStatic(QTextStream &t,const char *str) void LatexGenerator::docify(const char *str) { @@ -1266,6 +1386,7 @@ void LatexGenerator::docify(const char *str) static bool isRussian = theTranslator->idLanguage()=="russian"; static bool isUkrainian = theTranslator->idLanguage()=="ukrainian"; static bool isChinese = theTranslator->idLanguage()=="chinese"; + static bool isLatin2 = theTranslator->idLanguageCharset()=="iso-8859-2"; if (str) { const unsigned char *p=(const unsigned char *)str; @@ -1360,6 +1481,19 @@ void LatexGenerator::docify(const char *str) t << (char)c; } } + else if (isLatin2) + { + if (c>=128) + { + latin2ToLatex(c); + } + else + { + // see if we can insert an hyphenation hint + if (isupper(c) && islower(pc) && !insideTabbing) t << "\\-"; + t << (char)c; + } + } else // language is other than Czech, Russian or Japanese { switch(c) diff --git a/src/latexgen.h b/src/latexgen.h index dccabdf..fd37132 100644 --- a/src/latexgen.h +++ b/src/latexgen.h @@ -258,6 +258,7 @@ class LatexGenerator : public OutputGenerator void endFontClass() {} private: + void latin2ToLatex(unsigned char); LatexGenerator(const LatexGenerator &); LatexGenerator &operator=(const LatexGenerator &); int col; diff --git a/src/memberdef.cpp b/src/memberdef.cpp index 7b8245a..f0e4d5f 100644 --- a/src/memberdef.cpp +++ b/src/memberdef.cpp @@ -1459,6 +1459,7 @@ void MemberDef::writeDocumentation(MemberList *ml,OutputList &ol, // write reference to the source writeSourceDef(ol,cname); writeSourceRefs(ol,cname); + writeSourceReffedBy(ol,cname); writeInlineCode(ol,cname); ol.endIndent(); diff --git a/src/memberlist.cpp b/src/memberlist.cpp index 77906f9..af318e3 100644 --- a/src/memberlist.cpp +++ b/src/memberlist.cpp @@ -44,7 +44,7 @@ int MemberList::compareItems(GCI item1, GCI item2) { MemberDef *c1=(MemberDef *)item1; MemberDef *c2=(MemberDef *)item2; - return strcmp(c1->name(),c2->name()); + return stricmp(c1->name(),c2->name()); } /*! Count the number of members in this list that are visible in @@ -575,3 +575,12 @@ void MemberList::addListReferences(Definition *def) } } +//-------------------------------------------------------------------------- + +int MemberSDict::compareItems(GCI item1, GCI item2) +{ + MemberDef *c1=(MemberDef *)item1; + MemberDef *c2=(MemberDef *)item2; + return stricmp(c1->name(),c2->name()); +} + diff --git a/src/memberlist.h b/src/memberlist.h index 3dec524..c0b6b17 100644 --- a/src/memberlist.h +++ b/src/memberlist.h @@ -20,6 +20,8 @@ #include <qlist.h> #include "memberdef.h" +#include "sortdict.h" + class GroupDef; class MemberGroup; class MemberGroupList; @@ -69,13 +71,22 @@ class MemberListIterator : public QListIterator<MemberDef> { public: MemberListIterator(const QList<MemberDef> &list); + virtual ~MemberListIterator() {} }; class MemberDict : public QDict<MemberDef> { public: MemberDict(int size) : QDict<MemberDef>(size) {} - ~MemberDict() {} + virtual ~MemberDict() {} +}; + +class MemberSDict : public SDict<MemberDef> +{ + public: + MemberSDict(int size=17) : SDict<MemberDef>(size) {} + virtual ~MemberSDict() {} + int compareItems(GCI item1,GCI item2); }; diff --git a/src/scanner.l b/src/scanner.l index 5873d2e..fc6a7eb 100644 --- a/src/scanner.l +++ b/src/scanner.l @@ -581,6 +581,7 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'")) %x NSAliasName %x NSAliasArg %x PackageName +%x GetCallType %% @@ -1628,9 +1629,13 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'")) <FindFieldArg>"," { unput(*yytext); BEGIN(FindFields); } */ <ReadBody>[^\r\n{}"'/]* { current->program += yytext ; } -<ReadBody>"//".* { current->program += yytext ; } -<ReadBody>\"[^\r\n"]*\" { current->program += yytext ; } -<ReadBody>"/*"{B}* { current->program += yytext ; +<ReadBody>"//".* { current->program += yytext ; } +<ReadBody>\" { current->program += yytext ; + pCopyQuotedString = ¤t->program; + lastStringContext=YY_START; + BEGIN( CopyString ); + } +<ReadBody>"/*"{B}* { current->program += yytext ; lastContext = ReadBody ; BEGIN( Comment ) ; } @@ -1919,6 +1924,32 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'")) <FuncFuncType>. { current->type += *yytext; } +<FindMembers>"("/{BN}*{ID}{BN}*"*" { // for catching typedef void (__stdcall *f)() like definitions + if (current->type.left(7)=="typedef" && current->bodyLine==-1) + // the bodyLine check is to prevent this guard to be true more than once + { + current->bodyLine = yyLineNr; + BEGIN( GetCallType ); + } + else if (!current->name.isEmpty()) // normal function + { + current->args = yytext; + current->bodyLine = yyLineNr; + currentArgumentContext = FuncQual; + fullArgString=current->args.copy(); + copyArgString=¤t->args; + BEGIN( ReadFuncArgType ) ; + //printf(">>> Read function arguments!\n"); + } + } +<GetCallType>{BN}*{ID}{BN}*"*" { + lineCount(); + addType(current); + funcPtrType="("; + funcPtrType+=yytext; + roundCount=0; + BEGIN( FuncPtr ); + } <FindMembers>"(" { if (!current->name.isEmpty()) { @@ -3905,7 +3936,7 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'")) <Doc,ClassDoc,PageDoc,ExampleDoc,AfterDoc>"\\"[a-z_A-Z][a-z_A-Z0-9]*[\\] { // directory type of text current->doc+=yytext; } -<Doc,ClassDoc,PageDoc,ExampleDoc,AfterDoc,SkipSection>{CMD}[a-z_A-Z][a-z_A-Z0-9]* { +<Doc,ClassDoc,PageDoc,ExampleDoc,AfterDoc>{CMD}[a-z_A-Z][a-z_A-Z0-9]* { QCString *pValue=Doxygen::aliasDict[yytext+1]; if (pValue) { diff --git a/src/tagreader.cpp b/src/tagreader.cpp index 3425132..207d977 100644 --- a/src/tagreader.cpp +++ b/src/tagreader.cpp @@ -986,6 +986,7 @@ void TagFileParser::buildLists(Entry *root) for (;(argName=sli.current());++sli) { Argument *a = new Argument; + a->type = "class"; a->name = *argName; al->append(a); } diff --git a/src/translator.h b/src/translator.h index 81fd7ff..cc75d94 100644 --- a/src/translator.h +++ b/src/translator.h @@ -355,6 +355,12 @@ class Translator virtual QCString trAuthor(bool first_capital, bool singular) = 0; +////////////////////////////////////////////////////////////////////////// +// new since 1.2.11 +////////////////////////////////////////////////////////////////////////// + + virtual QCString trReferences() = 0; + }; #endif diff --git a/src/translator_adapter.h b/src/translator_adapter.h index a38307e..1b9a7d6 100644 --- a/src/translator_adapter.h +++ b/src/translator_adapter.h @@ -37,7 +37,6 @@ class TranslatorAdapterCVS : public Translator vs += versionString; // the one from the version.cpp return createUpdateNeededMessage(idLanguage(), vs); } - //----------------------------------------------------------------------- // The things below this line should go to the new // TranslatorAdapter_1_2_x, as public methods. The things above @@ -45,19 +44,31 @@ class TranslatorAdapterCVS : public Translator // The first five lines below should be uncommented, and the // release number at the fifth of those lines should be set. -// class TranslatorAdapter_1_2_8 : public TranslatorAdapterCVS +// class TranslatorAdapter_1_2_x : public TranslatorAdapterCVS // { // public: // virtual QCString updateNeededMessage() -// { return createUpdateNeededMessage(idLanguage(),"release 1.2.7"); } +// { return createUpdateNeededMessage(idLanguage(),"release 1.2.x"); } // Put new adapter methods below... // }; +class TranslatorAdapter_1_2_11 : public TranslatorAdapterCVS +{ + public: + virtual QCString updateNeededMessage() + { return createUpdateNeededMessage(idLanguage(),"release 1.2.11"); } + + // Put new adapter methods below... + // + virtual QCString trReferences() + { return english.trReferences(); } + +}; -class TranslatorAdapter_1_2_7 : public TranslatorAdapterCVS +class TranslatorAdapter_1_2_7 : public TranslatorAdapter_1_2_11 { public: virtual QCString updateNeededMessage() diff --git a/src/translator_br.h b/src/translator_br.h index 8446771..6c60bae 100644 --- a/src/translator_br.h +++ b/src/translator_br.h @@ -17,7 +17,7 @@ #ifndef TRANSLATOR_BR_H #define TRANSLATOR_BR_H -class TranslatorBrazilian: public Translator +class TranslatorBrazilian: public TranslatorAdapter_1_2_11 { public: diff --git a/src/translator_cn.h b/src/translator_cn.h index 30375d7..7d9ebe0 100644 --- a/src/translator_cn.h +++ b/src/translator_cn.h @@ -26,7 +26,7 @@ */ #define CN_SPC -class TranslatorChinese : public Translator +class TranslatorChinese : public TranslatorAdapter_1_2_11 { public: /*! Used for identification of the language. The identification diff --git a/src/translator_cz.h b/src/translator_cz.h index 9ea3ba2..36e785c 100644 --- a/src/translator_cz.h +++ b/src/translator_cz.h @@ -148,7 +148,7 @@ // probably slightly faster. -class TranslatorCzech : public Translator +class TranslatorCzech : public TranslatorAdapter_1_2_11 { private: /*! The decode() inline assumes the source written in the diff --git a/src/translator_de.h b/src/translator_de.h index 8e95779..aacd20e 100644 --- a/src/translator_de.h +++ b/src/translator_de.h @@ -65,7 +65,7 @@ #ifndef TRANSLATOR_DE_H #define TRANSLATOR_DE_H -class TranslatorGerman : public Translator +class TranslatorGerman : public TranslatorAdapter_1_2_11 { public: diff --git a/src/translator_en.h b/src/translator_en.h index 13062fe..e07b51f 100644 --- a/src/translator_en.h +++ b/src/translator_en.h @@ -1361,6 +1361,17 @@ class TranslatorEnglish : public Translator return result; } +////////////////////////////////////////////////////////////////////////// +// new since 1.2.11 +////////////////////////////////////////////////////////////////////////// + + /*! This text is put before the list of members referenced by a member + */ + virtual QCString trReferences() + { + return "References"; + } + }; #endif diff --git a/src/translator_fr.h b/src/translator_fr.h index bb3d415..490e45c 100644 --- a/src/translator_fr.h +++ b/src/translator_fr.h @@ -23,7 +23,7 @@ #ifndef TRANSLATOR_FR_H #define TRANSLATOR_FR_H -class TranslatorFrench : public Translator +class TranslatorFrench : public TranslatorAdapter_1_2_11 { public: QCString idLanguage() diff --git a/src/translator_hr.h b/src/translator_hr.h index 7525942..54cfaaa 100644 --- a/src/translator_hr.h +++ b/src/translator_hr.h @@ -42,7 +42,7 @@ #ifndef TRANSLATOR_HR_H #define TRANSLATOR_HR_H -class TranslatorCroatian : public Translator +class TranslatorCroatian : public TranslatorAdapter_1_2_11 { private: /*! to avoid macro redefinition from translator_cz.h */ diff --git a/src/translator_it.h b/src/translator_it.h index 615e797..1744c4b 100644 --- a/src/translator_it.h +++ b/src/translator_it.h @@ -59,7 +59,7 @@ #ifndef TRANSLATOR_IT_H #define TRANSLATOR_IT_H -class TranslatorItalian : public Translator +class TranslatorItalian : public TranslatorAdapter_1_2_11 { public: diff --git a/src/translator_nl.h b/src/translator_nl.h index 7f014ea..e5a749a 100644 --- a/src/translator_nl.h +++ b/src/translator_nl.h @@ -18,7 +18,7 @@ #ifndef TRANSLATOR_NL_H #define TRANSLATOR_NL_H -class TranslatorDutch : public Translator +class TranslatorDutch : public TranslatorAdapter_1_2_11 { public: QCString idLanguage() diff --git a/src/translator_pt.h b/src/translator_pt.h index a691b15..08c1e82 100644 --- a/src/translator_pt.h +++ b/src/translator_pt.h @@ -27,7 +27,7 @@ #ifndef TRANSLATOR_PT_H #define TRANSLATOR_PT_H -class TranslatorPortuguese : public Translator +class TranslatorPortuguese : public TranslatorAdapter_1_2_11 { public: diff --git a/src/translator_ru.h b/src/translator_ru.h index 1473cf0..c96bdae 100644 --- a/src/translator_ru.h +++ b/src/translator_ru.h @@ -50,7 +50,7 @@ #ifndef TRANSLATOR_RU_H #define TRANSLATOR_RU_H -class TranslatorRussian : public Translator +class TranslatorRussian : public TranslatorAdapter_1_2_11 { private: /*! The Decode() inline assumes the source written in the diff --git a/src/translator_si.h b/src/translator_si.h index 0e7bf6e..831cb3f 100644 --- a/src/translator_si.h +++ b/src/translator_si.h @@ -21,7 +21,7 @@ #define TRANSLATOR_SI_H -class TranslatorSlovene : public Translator +class TranslatorSlovene : public TranslatorAdapter_1_2_11 { public: QCString idLanguage() @@ -50,11 +50,11 @@ class TranslatorSlovene : public Translator QCString trDetailedDescription() { return "Podroben opis"; } QCString trMemberTypedefDocumentation() - { return "Opis <code> uporabniško definiranih tipov (typedef) </code>"; } + { return "Opis uporabniško definiranih tipov"; } QCString trMemberEnumerationDocumentation() - { return "Opis komponent <code> naštevnih tipov </code>"; } + { return "Opis komponent naštevnih tipov"; } QCString trEnumerationValueDocumentation() - { return "Opis vrednosti <code> naštevnih tipov (enum) </code> "; } + { return "Opis vrednosti naštevnih tipov (enum) "; } QCString trMemberFunctionDocumentation() { return "Opis metod"; } QCString trMemberDataDocumentation() @@ -231,7 +231,7 @@ class TranslatorSlovene : public Translator QCString trParameters() { return "Parametri"; } QCString trExceptions() - { return "Prekinitve (Exceptions)"; } + { return "Prekinitve"; } QCString trGeneratedBy() { return "Izdelano s pomočjo"; } @@ -240,7 +240,7 @@ class TranslatorSlovene : public Translator ////////////////////////////////////////////////////////////////////////// QCString trNamespaceList() - { return "seznam imenskih prostorov"; } + { return "imenski prostori"; } QCString trNamespaceListDescription(bool extractAll) { QCString result="Seznam "; @@ -267,14 +267,14 @@ class TranslatorSlovene : public Translator bool /*isTemplate*/) // used as the title of the HTML page of a class/struct/union { - QCString result="Opis "; + QCString result=""; switch(compType) { - case ClassDef::Class: result+=" razreda "; break; - case ClassDef::Struct: result+=" strukture "; break; - case ClassDef::Union: result+=" unije "; break; - case ClassDef::Interface: result+=" vmesnika (interface) "; break; - case ClassDef::Exception: result+=" prekinitve (exception) "; break; + case ClassDef::Class: result+=" Razred "; break; + case ClassDef::Struct: result+=" Struktura "; break; + case ClassDef::Union: result+=" Množica "; break; + case ClassDef::Interface: result+=" IDL vmesnik "; break; + case ClassDef::Exception: result+=" IDL prekinitev "; break; } result += (QCString)clName; @@ -283,14 +283,14 @@ class TranslatorSlovene : public Translator QCString trFileReference(const char *fileName) // used as the title of the HTML page of a file { - QCString result="Vsebina datoteke "; + QCString result="Datoteka "; result+=fileName; return result; } QCString trNamespaceReference(const char *namespaceName) // used as the title of the HTML page of a namespace { - QCString result ="Opis imenskega prostora "; + QCString result ="Imenski prostor "; result+=namespaceName; return result; @@ -497,7 +497,8 @@ class TranslatorSlovene : public Translator "direktno ali indirektno vključuje. Pravokotniki ponazarjajo datoteke, puščice " "predstavljajo relacije med njimi. " "Črn pravokotnik ponazarja datoteko "+fName+". Puščice A->B ponazarjajo " - "usmerjeno relacijo \"A vključuje B\"."; + "usmerjeno relacijo \"A vključuje B\"." +; } /*! header that is put before the list of constructor/destructors. */ QCString trConstructorDocumentation() diff --git a/src/translator_sk.h b/src/translator_sk.h index 05ad9d9..77eb802 100644 --- a/src/translator_sk.h +++ b/src/translator_sk.h @@ -23,7 +23,7 @@ #ifndef TRANSLATOR_SK_H #define TRANSLATOR_SK_H -class TranslatorSlovak : public Translator +class TranslatorSlovak : public TranslatorAdapter_1_2_11 { private: /*! The Decode() inline assumes the source written in the diff --git a/src/translator_ua.h b/src/translator_ua.h index 3275d9c..b3238c7 100644 --- a/src/translator_ua.h +++ b/src/translator_ua.h @@ -20,7 +20,7 @@ #ifndef TRANSLATOR_UA_H #define TRANSLATOR_UA_H -class TranslatorUkrainian : public Translator +class TranslatorUkrainian : public TranslatorAdapter_1_2_11 { private: /*! The Decode() inline assumes the source written in the diff --git a/src/util.cpp b/src/util.cpp index 4d2e130..adb3172 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -3230,6 +3230,8 @@ QCString substituteTemplateArgumentsInString( ++formAli,actArg=actualArgs->next() ) { + //printf("n=%s formArg->type=%s formArg->name=%s\n", + // n.data(),formArg->type.data(),formArg->name.data()); if (formArg->type=="class" || formArg->type=="typename") { if (formArg->name==n && actArg && !actArg->type.isEmpty()) // base class is a template argument |