Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
D
doxverilog
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Commits
Open sidebar
Elphel
doxverilog
Commits
744d1ca5
Commit
744d1ca5
authored
Dec 29, 2013
by
Dimitri van Heesch
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
More work on the template and context mechanisms
parent
2912829c
Changes
14
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
1284 additions
and
306 deletions
+1284
-306
classdef.cpp
src/classdef.cpp
+13
-9
classdef.h
src/classdef.h
+6
-2
context.cpp
src/context.cpp
+832
-96
context.h
src/context.h
+41
-1
filedef.cpp
src/filedef.cpp
+15
-5
filedef.h
src/filedef.h
+4
-0
memberdef.cpp
src/memberdef.cpp
+18
-9
memberdef.h
src/memberdef.h
+2
-1
message.cpp
src/message.cpp
+7
-2
message.h
src/message.h
+2
-0
namespacedef.cpp
src/namespacedef.cpp
+33
-23
namespacedef.h
src/namespacedef.h
+1
-0
template.cpp
src/template.cpp
+264
-124
template.h
src/template.h
+46
-34
No files found.
src/classdef.cpp
View file @
744d1ca5
...
...
@@ -1767,20 +1767,24 @@ void ClassDef::writeMoreLink(OutputList &ol,const QCString &anchor)
}
}
bool
ClassDef
::
visibleInParentsDeclList
()
const
{
static
bool
extractPrivate
=
Config_getBool
(
"EXTRACT_PRIVATE"
);
static
bool
hideUndocClasses
=
Config_getBool
(
"HIDE_UNDOC_CLASSES"
);
static
bool
extractLocalClasses
=
Config_getBool
(
"EXTRACT_LOCAL_CLASSES"
);
bool
linkable
=
isLinkable
();
return
(
name
().
find
(
'@'
)
==-
1
&&
!
isExtension
()
&&
(
protection
()
!=::
Private
||
extractPrivate
)
&&
(
linkable
||
(
!
hideUndocClasses
&&
(
!
isLocal
()
||
extractLocalClasses
)))
);
}
void
ClassDef
::
writeDeclarationLink
(
OutputList
&
ol
,
bool
&
found
,
const
char
*
header
,
bool
localNames
)
{
//static bool fortranOpt = Config_getBool("OPTIMIZE_FOR_FORTRAN");
//static bool vhdlOpt = Config_getBool("OPTIMIZE_OUTPUT_VHDL");
static
bool
hideUndocClasses
=
Config_getBool
(
"HIDE_UNDOC_CLASSES"
);
static
bool
extractLocalClasses
=
Config_getBool
(
"EXTRACT_LOCAL_CLASSES"
);
bool
isLink
=
isLinkable
();
SrcLangExt
lang
=
getLanguage
();
if
(
isLink
||
(
!
hideUndocClasses
&&
(
!
isLocal
()
||
extractLocalClasses
)
)
)
if
(
visibleInParentsDeclList
())
{
if
(
!
found
)
// first class
{
...
...
@@ -1820,7 +1824,7 @@ void ClassDef::writeDeclarationLink(OutputList &ol,bool &found,const char *heade
ol
.
writeString
(
" "
);
ol
.
insertMemberAlign
();
}
if
(
isLink
)
if
(
isLink
able
()
)
{
ol
.
writeObjectLink
(
getReference
(),
getOutputFileBase
(),
...
...
src/classdef.h
View file @
744d1ca5
...
...
@@ -168,6 +168,9 @@ class ClassDef : public Definition
/** the class is visible in a class diagram, or class hierarchy */
bool
isVisibleInHierarchy
();
/** show this class in the declaration section of its parent? */
bool
visibleInParentsDeclList
()
const
;
/** Returns the template arguments of this class
* Will return 0 if not applicable.
*/
...
...
@@ -310,14 +313,13 @@ class ClassDef : public Definition
QCString
generatedFromFiles
()
const
;
const
FileList
&
usedFiles
()
const
;
QCString
includeStatement
()
const
;
const
ArgumentList
*
typeConstraints
()
const
;
const
ExampleSDict
*
exampleList
()
const
;
bool
hasExamples
()
const
;
QCString
getMemberListFileName
()
const
;
bool
subGrouping
()
const
;
//-----------------------------------------------------------------------------------
// --- setters ----
//-----------------------------------------------------------------------------------
...
...
@@ -432,6 +434,8 @@ class ClassDef : public Definition
QPtrDict
<
void
>
*
visitedClasses
);
void
getTitleForMemberListType
(
MemberListType
type
,
QCString
&
title
,
QCString
&
subtitle
);
QCString
includeStatement
()
const
;
ClassDefImpl
*
m_impl
;
...
...
src/context.cpp
View file @
744d1ca5
...
...
@@ -27,6 +27,8 @@
// TODO: pass the current file to Dot*::writeGraph, so the user can put dot graphs in other
// files as well
#define ADD_PROPERTY(name) addProperty(#name,this,&Private::name);
struct
ContextGlobals
{
enum
OutputFormat
...
...
@@ -453,6 +455,18 @@ class TranslateContext::Private : public PropertyMapper
}
return
TemplateVariant
();
}
TemplateVariant
handleIncludeDependencyGraph
(
const
QValueList
<
TemplateVariant
>
&
args
)
const
{
if
(
args
.
count
()
==
1
)
{
return
theTranslator
->
trInclDepGraph
(
args
[
0
].
toString
());
}
else
{
err
(
"tr.includeDependencyGraph should take one string argument, got %d
\n
"
,
args
.
count
());
}
return
TemplateVariant
();
}
...
...
@@ -483,6 +497,8 @@ class TranslateContext::Private : public PropertyMapper
TemplateVariant
classes
()
const
{
return
theTranslator
->
trClasses
();
// TODO: VHDL: trVhdlType(VhdlDocGen::ENTITY,FALSE)
// TODO: Fortran: trDataTypes()
}
TemplateVariant
classList
()
const
{
...
...
@@ -669,6 +685,34 @@ class TranslateContext::Private : public PropertyMapper
{
return
theTranslator
->
trAdditionalInheritedMembers
();
}
TemplateVariant
includeDependencyGraph
()
const
{
return
TemplateVariant
::
Delegate
::
fromMethod
<
Private
,
&
Private
::
handleIncludeDependencyGraph
>
(
this
);
}
TemplateVariant
includedByDependencyGraph
()
const
{
return
theTranslator
->
trInclByDepGraph
();
}
TemplateVariant
gotoSourceCode
()
const
{
return
theTranslator
->
trGotoSourceCode
();
}
TemplateVariant
gotoDocumentation
()
const
{
return
theTranslator
->
trGotoDocumentation
();
}
TemplateVariant
constantgroups
()
const
{
return
theTranslator
->
trConstantGroups
();
}
TemplateVariant
classDocumentation
()
const
{
return
theTranslator
->
trClassDocumentation
();
}
TemplateVariant
compoundMembers
()
const
{
return
theTranslator
->
trCompoundMembers
();
}
Private
()
{
//%% string generatedBy
...
...
@@ -761,6 +805,20 @@ class TranslateContext::Private : public PropertyMapper
addProperty
(
"inheritedFrom"
,
this
,
&
Private
::
inheritedFrom
);
//%% string addtionalInheritedMembers
addProperty
(
"additionalInheritedMembers"
,
this
,
&
Private
::
additionalInheritedMembers
);
//%% string includeDependencyGraph:container_name
addProperty
(
"includeDependencyGraph"
,
this
,
&
Private
::
includeDependencyGraph
);
//%% string includedByDependencyGraph
addProperty
(
"includedByDependencyGraph"
,
this
,
&
Private
::
includedByDependencyGraph
);
//%% string gotoSourceCode
addProperty
(
"gotoSourceCode"
,
this
,
&
Private
::
gotoSourceCode
);
//%% string gotoDocumentation
addProperty
(
"gotoDocumentation"
,
this
,
&
Private
::
gotoDocumentation
);
//%% string constantgroups
addProperty
(
"constantgroups"
,
this
,
&
Private
::
constantgroups
);
//%% string classDocumentation
addProperty
(
"classDocumentation"
,
this
,
&
Private
::
classDocumentation
);
//%% string compoundMembers
addProperty
(
"compoundMembers"
,
this
,
&
Private
::
compoundMembers
);
m_javaOpt
=
Config_getBool
(
"OPTIMIZE_OUTPUT_JAVA"
);
m_fortranOpt
=
Config_getBool
(
"OPTIMIZE_FOR_FORTRAN"
);
...
...
@@ -823,6 +881,31 @@ static TemplateVariant parseCode(MemberDef *md,const QCString &scopeName,const Q
return
TemplateVariant
(
s
.
data
(),
TRUE
);
}
static
TemplateVariant
parseCode
(
FileDef
*
fd
,
const
QCString
&
relPath
)
{
static
bool
filterSourceFiles
=
Config_getBool
(
"FILTER_SOURCE_FILES"
);
ParserInterface
*
pIntf
=
Doxygen
::
parserManager
->
getParser
(
fd
->
getDefFileExtension
());
pIntf
->
resetCodeParserState
();
QGString
s
;
FTextStream
t
(
&
s
);
HtmlCodeGenerator
codeGen
(
t
,
relPath
);
pIntf
->
parseCode
(
codeGen
,
0
,
fileToString
(
fd
->
absFilePath
(),
filterSourceFiles
,
TRUE
),
// the sources
fd
->
getLanguage
(),
// lang
FALSE
,
// isExampleBlock
0
,
// exampleName
fd
,
// fileDef
-
1
,
// startLine
-
1
,
// endLine
FALSE
,
// inlineFragment
0
,
// memberDef
TRUE
,
// showLineNumbers
0
,
// searchCtx
TRUE
// collectXRefs, TODO: should become FALSE
);
return
TemplateVariant
(
s
.
data
(),
TRUE
);
}
//------------------------------------------------------------------------
//%% struct Symbol: shared info for all symbols
...
...
@@ -1027,7 +1110,10 @@ class DefinitionContext : public PropertyMapper
if
(
!
m_cache
.
navPath
)
{
TemplateList
*
list
=
new
TemplateList
;
fillPath
(
m_def
,
list
);
if
(
m_def
->
getOuterScope
()
&&
m_def
->
getOuterScope
()
!=
Doxygen
::
globalScope
)
{
fillPath
(
m_def
->
getOuterScope
(),
list
);
}
m_cache
.
navPath
.
reset
(
list
);
}
return
m_cache
.
navPath
.
get
();
...
...
@@ -1058,7 +1144,7 @@ class DefinitionContext : public PropertyMapper
class
IncludeInfoContext
::
Private
:
public
PropertyMapper
{
public
:
Private
(
IncludeInfo
*
info
,
SrcLangExt
lang
)
:
Private
(
const
IncludeInfo
*
info
,
SrcLangExt
lang
)
:
m_info
(
info
),
m_fileContext
(
info
&&
info
->
fileDef
?
info
->
fileDef
:
0
),
m_lang
(
lang
)
...
...
@@ -1096,12 +1182,12 @@ class IncludeInfoContext::Private : public PropertyMapper
return
m_info
->
includeName
;
}
private
:
IncludeInfo
*
m_info
;
const
IncludeInfo
*
m_info
;
FileContext
m_fileContext
;
SrcLangExt
m_lang
;
};
IncludeInfoContext
::
IncludeInfoContext
(
IncludeInfo
*
info
,
SrcLangExt
lang
)
IncludeInfoContext
::
IncludeInfoContext
(
const
IncludeInfo
*
info
,
SrcLangExt
lang
)
{
p
=
new
Private
(
info
,
lang
);
}
...
...
@@ -1119,14 +1205,59 @@ TemplateVariant IncludeInfoContext::get(const char *n) const
//------------------------------------------------------------------------
//%% list IncludeInfoList[Class] : list of nested classes
class
IncludeInfoListContext
::
Private
:
public
GenericNodeListContext
<
IncludeInfoContext
>
{
public
:
Private
(
const
QList
<
IncludeInfo
>
&
list
,
SrcLangExt
lang
)
{
QListIterator
<
IncludeInfo
>
li
(
list
);
IncludeInfo
*
ii
;
for
(
li
.
toFirst
();(
ii
=
li
.
current
());
++
li
)
{
if
(
!
ii
->
indirect
)
{
append
(
new
IncludeInfoContext
(
ii
,
lang
));
}
}
}
};
IncludeInfoListContext
::
IncludeInfoListContext
(
const
QList
<
IncludeInfo
>
&
list
,
SrcLangExt
lang
)
{
p
=
new
Private
(
list
,
lang
);
}
IncludeInfoListContext
::~
IncludeInfoListContext
()
{
delete
p
;
}
// TemplateListIntf
int
IncludeInfoListContext
::
count
()
const
{
return
p
->
count
();
}
TemplateVariant
IncludeInfoListContext
::
at
(
int
index
)
const
{
return
p
->
at
(
index
);
}
TemplateListIntf
::
ConstIterator
*
IncludeInfoListContext
::
createIterator
()
const
{
return
p
->
createIterator
();
}
//------------------------------------------------------------------------
//%% struct Class(Symbol): class information
//%% {
class
ClassContext
::
Private
:
public
DefinitionContext
<
ClassContext
::
Private
>
{
public
:
Private
(
ClassDef
*
cd
)
:
DefinitionContext
<
ClassContext
::
Private
>
(
cd
)
,
m_classDef
(
cd
),
m_usedFiles
(
cd
),
m_includeInfo
(
cd
?
cd
->
includeInfo
()
:
0
,
cd
?
cd
->
getLanguage
()
:
SrcLangExt_Unknown
)
Private
(
ClassDef
*
cd
)
:
DefinitionContext
<
ClassContext
::
Private
>
(
cd
),
m_classDef
(
cd
),
m_usedFiles
(
cd
)
{
addProperty
(
"title"
,
this
,
&
Private
::
title
);
addProperty
(
"highlight"
,
this
,
&
Private
::
highlight
);
...
...
@@ -1139,7 +1270,6 @@ class ClassContext::Private : public DefinitionContext<ClassContext::Private>
addProperty
(
"hasCollaborationDiagram"
,
this
,
&
Private
::
hasCollaborationDiagram
);
addProperty
(
"collaborationDiagram"
,
this
,
&
Private
::
collaborationDiagram
);
addProperty
(
"includeInfo"
,
this
,
&
Private
::
includeInfo
);
addProperty
(
"includeStatement"
,
this
,
&
Private
::
includeStatement
);
addProperty
(
"inherits"
,
this
,
&
Private
::
inherits
);
addProperty
(
"inheritedBy"
,
this
,
&
Private
::
inheritedBy
);
addProperty
(
"unoIDLServices"
,
this
,
&
Private
::
unoIDLServices
);
...
...
@@ -1182,7 +1312,7 @@ class ClassContext::Private : public DefinitionContext<ClassContext::Private>
addProperty
(
"detailedVariables"
,
this
,
&
Private
::
detailedVariables
);
addProperty
(
"detailedProperties"
,
this
,
&
Private
::
detailedProperties
);
addProperty
(
"detailedEvents"
,
this
,
&
Private
::
detailedEvents
);
addProperty
(
"
nestedClasses"
,
this
,
&
Private
::
nestedC
lasses
);
addProperty
(
"
classes"
,
this
,
&
Private
::
c
lasses
);
addProperty
(
"compoundType"
,
this
,
&
Private
::
compoundType
);
addProperty
(
"templateDecls"
,
this
,
&
Private
::
templateDecls
);
addProperty
(
"typeConstraints"
,
this
,
&
Private
::
typeConstraints
);
...
...
@@ -1317,19 +1447,19 @@ class ClassContext::Private : public DefinitionContext<ClassContext::Private>
TemplateVariant
includeInfo
()
const
{
if
(
m_classDef
->
includeInfo
())
if
(
!
m_cache
.
includeInfo
&&
m_classDef
->
includeInfo
())
{
m_cache
.
includeInfo
.
reset
(
new
IncludeInfoContext
(
m_classDef
->
includeInfo
(),
m_classDef
->
getLanguage
()));
}
if
(
m_cache
.
includeInfo
)
{
return
TemplateVariant
(
&
m_includeInfo
);
return
m_cache
.
includeInfo
.
get
(
);
}
else
{
return
TemplateVariant
(
FALSE
);
}
}
TemplateVariant
includeStatement
()
const
{
return
m_classDef
->
includeStatement
();
}
TemplateVariant
inherits
()
const
{
if
(
!
m_cache
.
inheritsList
)
...
...
@@ -1530,12 +1660,9 @@ class ClassContext::Private : public DefinitionContext<ClassContext::Private>
{
return
getMemberList
(
m_cache
.
detailedEvents
,
MemberListType_eventMembers
,
theTranslator
->
trEventDocumentation
(),
TRUE
);
}
TemplateVariant
nestedC
lasses
()
const
TemplateVariant
c
lasses
()
const
{
static
bool
extractPrivate
=
Config_getBool
(
"EXTRACT_PRIVATE"
);
static
bool
hideUndocClasses
=
Config_getBool
(
"HIDE_UNDOC_CLASSES"
);
static
bool
extractLocalClasses
=
Config_getBool
(
"EXTRACT_LOCAL_CLASSES"
);
if
(
!
m_cache
.
nestedClasses
)
if
(
!
m_cache
.
classes
)
{
NestedClassListContext
*
classList
=
new
NestedClassListContext
;
if
(
m_classDef
->
getClassSDict
())
...
...
@@ -1544,20 +1671,15 @@ class ClassContext::Private : public DefinitionContext<ClassContext::Private>
ClassDef
*
cd
;
for
(
sdi
.
toFirst
();(
cd
=
sdi
.
current
());
++
sdi
)
{
bool
linkable
=
cd
->
isLinkable
();
if
(
cd
->
name
().
find
(
'@'
)
==-
1
&&
!
cd
->
isExtension
()
&&
(
cd
->
protection
()
!=::
Private
||
extractPrivate
)
&&
(
linkable
||
(
!
hideUndocClasses
&&
(
!
cd
->
isLocal
()
||
extractLocalClasses
)))
)
if
(
cd
->
visibleInParentsDeclList
())
{
classList
->
append
(
cd
);
}
}
}
m_cache
.
nestedC
lasses
.
reset
(
classList
);
m_cache
.
c
lasses
.
reset
(
classList
);
}
return
m_cache
.
nestedC
lasses
.
get
();
return
m_cache
.
c
lasses
.
get
();
}
TemplateVariant
compoundType
()
const
{
...
...
@@ -1764,71 +1886,70 @@ class ClassContext::Private : public DefinitionContext<ClassContext::Private>
private
:
ClassDef
*
m_classDef
;
UsedFilesContext
m_usedFiles
;
IncludeInfoContext
m_includeInfo
;
struct
Cachable
{
Cachable
()
:
inheritanceNodes
(
-
1
)
{
templateArgList
.
setAutoDelete
(
TRUE
);
exampleList
.
setAutoDelete
(
TRUE
);
allMembers
.
setAutoDelete
(
TRUE
);
}
ScopedPtr
<
IncludeInfoContext
>
includeInfo
;
ScopedPtr
<
InheritanceListContext
>
inheritsList
;
ScopedPtr
<
InheritanceListContext
>
inheritedByList
;
ScopedPtr
<
DotClassGraph
>
classGraph
;
ScopedPtr
<
DotClassGraph
>
collaborationGraph
;
ScopedPtr
<
NestedClassListContext
>
nestedC
lasses
;
ScopedPtr
<
MemberListInfoContext
>
publicTypes
;
ScopedPtr
<
MemberListInfoContext
>
publicMethods
;
ScopedPtr
<
MemberListInfoContext
>
publicStaticMethods
;
ScopedPtr
<
MemberListInfoContext
>
publicAttributes
;
ScopedPtr
<
MemberListInfoContext
>
publicStaticAttributes
;
ScopedPtr
<
MemberListInfoContext
>
publicSlots
;
ScopedPtr
<
MemberListInfoContext
>
protectedTypes
;
ScopedPtr
<
MemberListInfoContext
>
protectedMethods
;
ScopedPtr
<
MemberListInfoContext
>
protectedStaticMethods
;
ScopedPtr
<
MemberListInfoContext
>
protectedAttributes
;
ScopedPtr
<
MemberListInfoContext
>
protectedStaticAttributes
;
ScopedPtr
<
MemberListInfoContext
>
protectedSlots
;
ScopedPtr
<
MemberListInfoContext
>
privateTypes
;
ScopedPtr
<
MemberListInfoContext
>
privateMethods
;
ScopedPtr
<
MemberListInfoContext
>
privateStaticMethods
;
ScopedPtr
<
MemberListInfoContext
>
privateAttributes
;
ScopedPtr
<
MemberListInfoContext
>
privateStaticAttributes
;
ScopedPtr
<
MemberListInfoContext
>
privateSlots
;
ScopedPtr
<
MemberListInfoContext
>
packageTypes
;
ScopedPtr
<
MemberListInfoContext
>
packageMethods
;
ScopedPtr
<
MemberListInfoContext
>
packageStaticMethods
;
ScopedPtr
<
MemberListInfoContext
>
packageAttributes
;
ScopedPtr
<
MemberListInfoContext
>
packageStaticAttributes
;
ScopedPtr
<
MemberListInfoContext
>
unoIDLServices
;
ScopedPtr
<
MemberListInfoContext
>
unoIDLInterfaces
;
ScopedPtr
<
MemberListInfoContext
>
signals
;
ScopedPtr
<
MemberListInfoContext
>
properties
;
ScopedPtr
<
MemberListInfoContext
>
events
;
ScopedPtr
<
MemberListInfoContext
>
friends
;
ScopedPtr
<
MemberListInfoContext
>
related
;
ScopedPtr
<
MemberListInfoContext
>
detailedTypedefs
;
ScopedPtr
<
MemberListInfoContext
>
detailedEnums
;
ScopedPtr
<
MemberListInfoContext
>
detailedServices
;
ScopedPtr
<
MemberListInfoContext
>
detailedInterfaces
;
ScopedPtr
<
MemberListInfoContext
>
detailedConstructors
;
ScopedPtr
<
MemberListInfoContext
>
detailedMethods
;
ScopedPtr
<
MemberListInfoContext
>
detailedRelated
;
ScopedPtr
<
MemberListInfoContext
>
detailedVariables
;
ScopedPtr
<
MemberListInfoContext
>
detailedProperties
;
ScopedPtr
<
MemberListInfoContext
>
detailedEvents
;
ScopedPtr
<
NestedClassListContext
>
c
lasses
;
ScopedPtr
<
MemberListInfoContext
>
publicTypes
;
ScopedPtr
<
MemberListInfoContext
>
publicMethods
;
ScopedPtr
<
MemberListInfoContext
>
publicStaticMethods
;
ScopedPtr
<
MemberListInfoContext
>
publicAttributes
;
ScopedPtr
<
MemberListInfoContext
>
publicStaticAttributes
;
ScopedPtr
<
MemberListInfoContext
>
publicSlots
;
ScopedPtr
<
MemberListInfoContext
>
protectedTypes
;
ScopedPtr
<
MemberListInfoContext
>
protectedMethods
;
ScopedPtr
<
MemberListInfoContext
>
protectedStaticMethods
;
ScopedPtr
<
MemberListInfoContext
>
protectedAttributes
;
ScopedPtr
<
MemberListInfoContext
>
protectedStaticAttributes
;
ScopedPtr
<
MemberListInfoContext
>
protectedSlots
;
ScopedPtr
<
MemberListInfoContext
>
privateTypes
;
ScopedPtr
<
MemberListInfoContext
>
privateMethods
;
ScopedPtr
<
MemberListInfoContext
>
privateStaticMethods
;
ScopedPtr
<
MemberListInfoContext
>
privateAttributes
;
ScopedPtr
<
MemberListInfoContext
>
privateStaticAttributes
;
ScopedPtr
<
MemberListInfoContext
>
privateSlots
;
ScopedPtr
<
MemberListInfoContext
>
packageTypes
;
ScopedPtr
<
MemberListInfoContext
>
packageMethods
;
ScopedPtr
<
MemberListInfoContext
>
packageStaticMethods
;
ScopedPtr
<
MemberListInfoContext
>
packageAttributes
;
ScopedPtr
<
MemberListInfoContext
>
packageStaticAttributes
;
ScopedPtr
<
MemberListInfoContext
>
unoIDLServices
;
ScopedPtr
<
MemberListInfoContext
>
unoIDLInterfaces
;
ScopedPtr
<
MemberListInfoContext
>
signals
;
ScopedPtr
<
MemberListInfoContext
>
properties
;
ScopedPtr
<
MemberListInfoContext
>
events
;
ScopedPtr
<
MemberListInfoContext
>
friends
;
ScopedPtr
<
MemberListInfoContext
>
related
;
ScopedPtr
<
MemberListInfoContext
>
detailedTypedefs
;
ScopedPtr
<
MemberListInfoContext
>
detailedEnums
;
ScopedPtr
<
MemberListInfoContext
>
detailedServices
;
ScopedPtr
<
MemberListInfoContext
>
detailedInterfaces
;
ScopedPtr
<
MemberListInfoContext
>
detailedConstructors
;
ScopedPtr
<
MemberListInfoContext
>
detailedMethods
;
ScopedPtr
<
MemberListInfoContext
>
detailedRelated
;
ScopedPtr
<
MemberListInfoContext
>
detailedVariables
;
ScopedPtr
<
MemberListInfoContext
>
detailedProperties
;
ScopedPtr
<
MemberListInfoContext
>
detailedEvents
;
ScopedPtr
<
MemberGroupListContext
>
memberGroups
;
ScopedPtr
<
AllMembersListContext
>
allMembersList
;
ScopedPtr
<
ArgumentListContext
>
typeConstraints
;
ScopedPtr
<
TemplateList
>
examples
;
ScopedPtr
<
TemplateList
>
templateDecls
;
ScopedPtr
<
AllMembersListContext
>
allMembersList
;
ScopedPtr
<
ArgumentListContext
>
typeConstraints
;
ScopedPtr
<
TemplateList
>
examples
;
ScopedPtr
<
TemplateList
>
templateDecls
;
ScopedPtr
<
InheritedMemberInfoListContext
>
additionalInheritedMembers
;
ScopedPtr
<
MemberListContext
>
members
;
QList
<
ArgumentListContext
>
templateArgList
;
int
inheritanceNodes
;
QList
<
TemplateStruct
>
exampleList
;
MemberList
allMembers
;
ScopedPtr
<
MemberListContext
>
members
;
QList
<
ArgumentListContext
>
templateArgList
;
int
inheritanceNodes
;
QList
<
TemplateStruct
>
exampleList
;
MemberList
allMembers
;
};
mutable
Cachable
m_cache
;
};
...
...
@@ -1862,6 +1983,7 @@ class NamespaceContext::Private : public DefinitionContext<NamespaceContext::Pri
addProperty
(
"title"
,
this
,
&
Private
::
title
);
addProperty
(
"highlight"
,
this
,
&
Private
::
highlight
);
addProperty
(
"subhighlight"
,
this
,
&
Private
::
subHighlight
);
addProperty
(
"compoundType"
,
this
,
&
Private
::
compoundType
);
}
TemplateVariant
title
()
const
{
...
...
@@ -1875,6 +1997,10 @@ class NamespaceContext::Private : public DefinitionContext<NamespaceContext::Pri
{
return
TemplateVariant
(
""
);
}
TemplateVariant
compoundType
()
const
{
return
m_namespaceDef
->
compoundTypeString
();
}
private
:
NamespaceDef
*
m_namespaceDef
;
};
...
...
@@ -1904,10 +2030,34 @@ class FileContext::Private : public DefinitionContext<FileContext::Private>
public
:
Private
(
FileDef
*
fd
)
:
DefinitionContext
<
FileContext
::
Private
>
(
fd
)
,
m_fileDef
(
fd
)
{
addProperty
(
"title"
,
this
,
&
Private
::
title
);
addProperty
(
"highlight"
,
this
,
&
Private
::
highlight
);
addProperty
(
"subhighlight"
,
this
,
&
Private
::
subHighlight
);
addProperty
(
"versionInfo"
,
this
,
&
Private
::
versionInfo
);
addProperty
(
"title"
,
this
,
&
Private
::
title
);
addProperty
(
"highlight"
,
this
,
&
Private
::
highlight
);
addProperty
(
"subhighlight"
,
this
,
&
Private
::
subHighlight
);
addProperty
(
"versionInfo"
,
this
,
&
Private
::
versionInfo
);
addProperty
(
"includeList"
,
this
,
&
Private
::
includeList
);
addProperty
(
"hasIncludeGraph"
,
this
,
&
Private
::
hasIncludeGraph
);
addProperty
(
"hasIncludedByGraph"
,
this
,
&
Private
::
hasIncludedByGraph
);
addProperty
(
"includeGraph"
,
this
,
&
Private
::
includeGraph
);
addProperty
(
"includedByGraph"
,
this
,
&
Private
::
includedByGraph
);
addProperty
(
"hasDetails"
,
this
,
&
Private
::
hasDetails
);
addProperty
(
"hasSourceFile"
,
this
,
&
Private
::
hasSourceFile
);
addProperty
(
"sources"
,
this
,
&
Private
::
sources
);
addProperty
(
"version"
,
this
,
&
Private
::
version
);
addProperty
(
"classes"
,
this
,
&
Private
::
classes
);
addProperty
(
"namespaces"
,
this
,
&
Private
::
namespaces
);
addProperty
(
"constantgroups"
,
this
,
&
Private
::
constantgroups
);
addProperty
(
"macros"
,
this
,
&
Private
::
macros
);
addProperty
(
"typedefs"
,
this
,
&
Private
::
typedefs
);
addProperty
(
"enums"
,
this
,
&
Private
::
enums
);
addProperty
(
"functions"
,
this
,
&
Private
::
functions
);
addProperty
(
"variables"
,
this
,
&
Private
::
variables
);
addProperty
(
"memberGroups"
,
this
,
&
Private
::
memberGroups
);
addProperty
(
"detailedMacros"
,
this
,
&
Private
::
detailedMacros
);
addProperty
(
"detailedTypedefs"
,
this
,
&
Private
::
detailedTypedefs
);
addProperty
(
"detailedEnums"
,
this
,
&
Private
::
detailedEnums
);
addProperty
(
"detailedFunctions"
,
this
,
&
Private
::
detailedFunctions
);
addProperty
(
"detailedVariables"
,
this
,
&
Private
::
detailedVariables
);
addProperty
(
"inlineClasses"
,
this
,
&
Private
::
inlineClasses
);
}
TemplateVariant
title
()
const
{
...
...
@@ -1925,8 +2075,302 @@ class FileContext::Private : public DefinitionContext<FileContext::Private>
{
return
m_fileDef
->
getVersion
();
}
TemplateVariant
includeList
()
const
{
if
(
!
m_cache
.
includeInfoList
&&
m_fileDef
->
includeFileList
())
{
m_cache
.
includeInfoList
.
reset
(
new
IncludeInfoListContext
(
*
m_fileDef
->
includeFileList
(),
m_fileDef
->
getLanguage
()));
}
if
(
m_cache
.
includeInfoList
)
{
return
m_cache
.
includeInfoList
.
get
();
}
else
{
return
TemplateVariant
(
FALSE
);
}
}
DotInclDepGraph
*
getIncludeGraph
()
const
{
if
(
!
m_cache
.
includeGraph
)
{
m_cache
.
includeGraph
.
reset
(
new
DotInclDepGraph
(
m_fileDef
,
FALSE
));
}
return
m_cache
.
includeGraph
.
get
();
}
TemplateVariant
hasIncludeGraph
()
const
{
static
bool
haveDot
=
Config_getBool
(
"HAVE_DOT"
);
DotInclDepGraph
*
incGraph
=
getIncludeGraph
();
return
(
haveDot
&&
!
incGraph
->
isTooBig
()
&&
!
incGraph
->
isTrivial
());
}
TemplateVariant
includeGraph
()
const
{
static
bool
haveDot
=
Config_getBool
(
"HAVE_DOT"
);
QGString
result
;
if
(
haveDot
)
{
DotInclDepGraph
*
cg
=
getIncludeGraph
();
FTextStream
t
(
&
result
);
cg
->
writeGraph
(
t
,
BITMAP
,
g_globals
.
outputDir
,
g_globals
.
outputDir
+
portable_pathSeparator
()
+
m_fileDef
->
getOutputFileBase
()
+
Doxygen
::
htmlFileExtension
,
relPathAsString
(),
TRUE
,
g_globals
.
dynSectionId
);
}
g_globals
.
dynSectionId
++
;
return
TemplateVariant
(
result
.
data
(),
TRUE
);
}
DotInclDepGraph
*
getIncludedByGraph
()
const
{
if
(
!
m_cache
.
includedByGraph
)
{
m_cache
.
includedByGraph
.
reset
(
new
DotInclDepGraph
(
m_fileDef
,
TRUE
));
}
return
m_cache
.
includedByGraph
.
get
();
}
TemplateVariant
hasIncludedByGraph
()
const
{
static
bool
haveDot
=
Config_getBool
(
"HAVE_DOT"
);
DotInclDepGraph
*
incGraph
=
getIncludedByGraph
();
return
(
haveDot
&&
!
incGraph
->
isTooBig
()
&&
!
incGraph
->
isTrivial
());
}
TemplateVariant
includedByGraph
()
const
{
static
bool
haveDot
=
Config_getBool
(
"HAVE_DOT"
);
QGString
result
;
if
(
haveDot
)
{
DotInclDepGraph
*
cg
=
getIncludedByGraph
();
FTextStream
t
(
&
result
);
cg
->
writeGraph
(
t
,
BITMAP
,
g_globals
.
outputDir
,
g_globals
.
outputDir
+
portable_pathSeparator
()
+
m_fileDef
->
getOutputFileBase
()
+
Doxygen
::
htmlFileExtension
,
relPathAsString
(),
TRUE
,
g_globals
.
dynSectionId
);
}
g_globals
.
dynSectionId
++
;
return
TemplateVariant
(
result
.
data
(),
TRUE
);
}
TemplateVariant
hasDetails
()
const
{
return
m_fileDef
->
hasDetailedDescription
();
}
TemplateVariant
hasSourceFile
()
const
{
return
m_fileDef
->
generateSourceFile
();
}
TemplateVariant
sources
()
const
{
if
(
!
m_cache
.
sources
)
{
if
(
m_fileDef
->
generateSourceFile
())
{
m_cache
.
sources
.
reset
(
new
TemplateVariant
(
parseCode
(
m_fileDef
,
relPathAsString
())));
}
else
{
m_cache
.
sources
.
reset
(
new
TemplateVariant
(
""
));
}
}
return
*
m_cache
.
sources
;
}
TemplateVariant
version
()
const
{
return
m_fileDef
->
fileVersion
();
}
TemplateVariant
classes
()
const
{
if
(
!
m_cache
.
classes
)
{
NestedClassListContext
*
classList
=
new
NestedClassListContext
;
if
(
m_fileDef
->
getClassSDict
())
{
ClassSDict
::
Iterator
sdi
(
*
m_fileDef
->
getClassSDict
());
ClassDef
*
cd
;
for
(
sdi
.
toFirst
();(
cd
=
sdi
.
current
());
++
sdi
)
{
if
(
cd
->
visibleInParentsDeclList
())
{
classList
->
append
(
cd
);
}
}
}
m_cache
.
classes
.
reset
(
classList
);
}
return
m_cache
.
classes
.
get
();
}
TemplateVariant
namespaces
()
const
{
if
(
!
m_cache
.
namespaces
)
{
NestedNamespaceListContext
*
namespaceList
=
new
NestedNamespaceListContext
;
if
(
m_fileDef
->
getNamespaceSDict
())
{
NamespaceSDict
::
Iterator
sdi
(
*
m_fileDef
->
getNamespaceSDict
());
NamespaceDef
*
nd
;
for
(
sdi
.
toFirst
();(
nd
=
sdi
.
current
());
++
sdi
)
{
if
(
nd
->
isLinkable
()
&&
!
nd
->
isConstantGroup
())
{
namespaceList
->
append
(
nd
);
}
}
}
m_cache
.
namespaces
.
reset
(
namespaceList
);
}
return
m_cache
.
namespaces
.
get
();
}
TemplateVariant
constantgroups
()
const
{
if
(
!
m_cache
.
constantgroups
)
{
NestedNamespaceListContext
*
namespaceList
=
new
NestedNamespaceListContext
;
if
(
m_fileDef
->
getNamespaceSDict
())
{
NamespaceSDict
::
Iterator
sdi
(
*
m_fileDef
->
getNamespaceSDict
());
NamespaceDef
*
nd
;
for
(
sdi
.
toFirst
();(
nd
=
sdi
.
current
());
++
sdi
)
{
if
(
nd
->
isLinkable
()
&&
nd
->
isConstantGroup
())
{
namespaceList
->
append
(
nd
);
}
}
}
m_cache
.
constantgroups
.
reset
(
namespaceList
);
}
return
m_cache
.
constantgroups
.
get
();
}
TemplateVariant
getMemberList
(
ScopedPtr
<
MemberListInfoContext
>
&
list
,
MemberListType
type
,
const
char
*
title
,
bool
detailed
=
FALSE
)
const
{
if
(
!
list
)
{
MemberList
*
ml
=
m_fileDef
->
getMemberList
(
type
);
if
(
ml
)
{
list
.
reset
(
new
MemberListInfoContext
(
m_fileDef
,
relPathAsString
(),
ml
,
title
,
detailed
));
}
}
if
(
list
)
{
return
list
.
get
();
}
else
{
return
TemplateVariant
(
FALSE
);
}
}
TemplateVariant
macros
()
const
{
return
getMemberList
(
m_cache
.
macros
,
MemberListType_decDefineMembers
,
theTranslator
->
trDefines
());
}
TemplateVariant
typedefs
()
const
{
return
getMemberList
(
m_cache
.
typedefs
,
MemberListType_decTypedefMembers
,
theTranslator
->
trTypedefs
());
}
TemplateVariant
enums
()
const
{
return
getMemberList
(
m_cache
.
enums
,
MemberListType_decEnumMembers
,
theTranslator
->
trEnumerations
());
}
TemplateVariant
functions
()
const
{
// TODO: Fortran: trSubprograms()
// TODO: VHDL: VhdlDocGen::trFunctionAndProc()
return
getMemberList
(
m_cache
.
functions
,
MemberListType_decFuncMembers
,
theTranslator
->
trFunctions
());
}
TemplateVariant
variables
()
const
{
return
getMemberList
(
m_cache
.
variables
,
MemberListType_decVarMembers
,
theTranslator
->
trVariables
());
}
TemplateVariant
memberGroups
()
const
{
if
(
!
m_cache
.
memberGroups
)
{
if
(
m_fileDef
->
getMemberGroupSDict
())
{
m_cache
.
memberGroups
.
reset
(
new
MemberGroupListContext
(
m_fileDef
,
relPathAsString
(),
m_fileDef
->
getMemberGroupSDict
(),
m_fileDef
->
subGrouping
()));
}
else
{
m_cache
.
memberGroups
.
reset
(
new
MemberGroupListContext
);
}
}
return
m_cache
.
memberGroups
.
get
();
}
TemplateVariant
detailedMacros
()
const
{
return
getMemberList
(
m_cache
.
detailedMacros
,
MemberListType_docDefineMembers
,
theTranslator
->
trDefineDocumentation
());
}
TemplateVariant
detailedTypedefs
()
const
{
return
getMemberList
(
m_cache
.
detailedTypedefs
,
MemberListType_docTypedefMembers
,
theTranslator
->
trTypedefDocumentation
());
}
TemplateVariant
detailedEnums
()
const
{
return
getMemberList
(
m_cache
.
detailedEnums
,
MemberListType_docEnumMembers
,
theTranslator
->
trEnumerationTypeDocumentation
());
}
TemplateVariant
detailedFunctions
()
const
{
// TODO: Fortran: trSubprogramDocumentation()
return
getMemberList
(
m_cache
.
detailedFunctions
,
MemberListType_docFuncMembers
,
theTranslator
->
trFunctionDocumentation
());
}
TemplateVariant
detailedVariables
()
const
{
return
getMemberList
(
m_cache
.
detailedVariables
,
MemberListType_docVarMembers
,
theTranslator
->
trVariableDocumentation
());
}
TemplateVariant
inlineClasses
()
const
{
if
(
!
m_cache
.
inlineClasses
)
{
NestedClassListContext
*
classList
=
new
NestedClassListContext
;
if
(
m_fileDef
->
getClassSDict
())
{
ClassSDict
::
Iterator
sdi
(
*
m_fileDef
->
getClassSDict
());
ClassDef
*
cd
;
for
(
sdi
.
toFirst
();(
cd
=
sdi
.
current
());
++
sdi
)
{
if
(
cd
->
name
().
find
(
'@'
)
==-
1
&&
cd
->
isLinkableInProject
()
&&
cd
->
isEmbeddedInOuterScope
()
&&
cd
->
partOfGroups
()
==
0
)
{
classList
->
append
(
cd
);
}
}
}
m_cache
.
inlineClasses
.
reset
(
classList
);
}
return
m_cache
.
inlineClasses
.
get
();
}
private
:
FileDef
*
m_fileDef
;
struct
Cachable
{
ScopedPtr
<
IncludeInfoListContext
>
includeInfoList
;
ScopedPtr
<
DotInclDepGraph
>
includeGraph
;
ScopedPtr
<
DotInclDepGraph
>
includedByGraph
;
ScopedPtr
<
TemplateVariant
>
sources
;
ScopedPtr
<
NestedClassListContext
>
classes
;
ScopedPtr
<
NestedNamespaceListContext
>
namespaces
;
ScopedPtr
<
NestedNamespaceListContext
>
constantgroups
;
ScopedPtr
<
MemberListInfoContext
>
macros
;
ScopedPtr
<
MemberListInfoContext
>
typedefs
;
ScopedPtr
<
MemberListInfoContext
>
enums
;
ScopedPtr
<
MemberListInfoContext
>
functions
;
ScopedPtr
<
MemberListInfoContext
>
variables
;
ScopedPtr
<
MemberGroupListContext
>
memberGroups
;
ScopedPtr
<
MemberListInfoContext
>
detailedMacros
;
ScopedPtr
<
MemberListInfoContext
>
detailedTypedefs
;
ScopedPtr
<
MemberListInfoContext
>
detailedEnums
;
ScopedPtr
<
MemberListInfoContext
>
detailedFunctions
;
ScopedPtr
<
MemberListInfoContext
>
detailedVariables
;
ScopedPtr
<
NestedClassListContext
>
inlineClasses
;
};
mutable
Cachable
m_cache
;
};
//%% }
...
...
@@ -2160,21 +2604,70 @@ class MemberContext::Private : public DefinitionContext<MemberContext::Private>
public
:
Private
(
MemberDef
*
md
)
:
DefinitionContext
<
MemberContext
::
Private
>
(
md
)
,
m_memberDef
(
md
)
{
addProperty
(
"declType"
,
this
,
&
Private
::
declType
);
addProperty
(
"declArgs"
,
this
,
&
Private
::
declArgs
);
addProperty
(
"isSignal"
,
this
,
&
Private
::
isSignal
);
addProperty
(
"isSlot"
,
this
,
&
Private
::
isSlot
);
addProperty
(
"isVariable"
,
this
,
&
Private
::
isVariable
);
addProperty
(
"isEnumeration"
,
this
,
&
Private
::
isEnumeration
);
addProperty
(
"isEnumValue"
,
this
,
&
Private
::
isEnumValue
);
addProperty
(
"isTypedef"
,
this
,
&
Private
::
isTypedef
);
addProperty
(
"isFunction"
,
this
,
&
Private
::
isFunction
);
addProperty
(
"isFunctionPtr"
,
this
,
&
Private
::
isFunctionPtr
);
addProperty
(
"isDefine"
,
this
,
&
Private
::
isDefine
);
addProperty
(
"isFriend"
,
this
,
&
Private
::
isFriend
);
addProperty
(
"isProperty"
,
this
,
&
Private
::
isProperty
);
addProperty
(
"isEvent"
,
this
,
&
Private
::
isEvent
);
addProperty
(
"isRelated"
,
this
,
&
Private
::
isRelated
);
addProperty
(
"isForeign"
,
this
,
&
Private
::
isForeign
);
addProperty
(
"isStatic"
,
this
,
&
Private
::
isStatic
);
addProperty
(
"isInline"
,
this
,
&
Private
::
isInline
);
addProperty
(
"isExplicit"
,
this
,
&
Private
::
isExplicit
);
addProperty
(
"isMutable"
,
this
,
&
Private
::
isMutable
);
addProperty
(
"isGettable"
,
this
,
&
Private
::
isGettable
);
addProperty
(
"isSettable"
,
this
,
&
Private
::
isSettable
);
addProperty
(
"isReadable"
,
this
,
&
Private
::
isReadable
);
addProperty
(
"isWritable"
,
this
,
&
Private
::
isWritable
);
addProperty
(
"isAddable"
,
this
,
&
Private
::
isAddable
);
addProperty
(
"isRemovable"
,
this
,
&
Private
::
isRemovable
);
addProperty
(
"isRaisable"
,
this
,
&
Private
::
isRaisable
);
addProperty
(
"isFinal"
,
this
,
&
Private
::
isFinal
);
addProperty
(
"isAbstract"
,
this
,
&
Private
::
isAbstract
);
addProperty
(
"isOverride"
,
this
,
&
Private
::
isOverride
);
addProperty
(
"isInitonly"
,
this
,
&
Private
::
isInitonly
);
addProperty
(
"isOptional"
,
this
,
&
Private
::
isOptional
);
addProperty
(
"isRequired"
,
this
,
&
Private
::
isRequired
);
addProperty
(
"isNonAtomic"
,
this
,
&
Private
::
isNonAtomic
);
addProperty
(
"isCopy"
,
this
,
&
Private
::
isCopy
);
addProperty
(
"isAssign"
,
this
,
&
Private
::
isAssign
);
addProperty
(
"isRetain"
,
this
,
&
Private
::
isRetain
);
addProperty
(
"isWeak"
,
this
,
&
Private
::
isWeak
);
addProperty
(
"isStrong"
,
this
,
&
Private
::
isStrong
);
addProperty
(
"isUnretained"
,
this
,
&
Private
::
isUnretained
);
addProperty
(
"isNew"
,
this
,
&
Private
::
isNew
);
addProperty
(
"isSealed"
,
this
,
&
Private
::
isSealed
);
addProperty
(
"isImplementation"
,
this
,
&
Private
::
isImplementation
);
addProperty
(
"isExternal"
,
this
,
&
Private
::
isExternal
);
addProperty
(
"isAlias"
,
this
,
&
Private
::
isAlias
);
addProperty
(
"isDefault"
,
this
,
&
Private
::
isDefault
);
addProperty
(
"isDelete"
,
this
,
&
Private
::
isDelete
);
addProperty
(
"isNoExcept"
,
this
,
&
Private
::
isNoExcept
);
addProperty
(
"isAttribute"
,
this
,
&
Private
::
isAttribute
);
addProperty
(
"isUNOProperty"
,
this
,
&
Private
::
isUNOProperty
);
addProperty
(
"isReadonly"
,
this
,
&
Private
::
isReadonly
);
addProperty
(
"isBound"
,
this
,
&
Private
::
isBound
);
addProperty
(
"isConstrained"
,
this
,
&
Private
::
isConstrained
);
addProperty
(
"isTransient"
,
this
,
&
Private
::
isTransient
);
addProperty
(
"isMaybeVoid"
,
this
,
&
Private
::
isMaybeVoid
);
addProperty
(
"isMaybeDefault"
,
this
,
&
Private
::
isMaybeDefault
);
addProperty
(
"isMaybeAmbiguous"
,
this
,
&
Private
::
isMaybeAmbiguous
);
addProperty
(
"isPublished"
,
this
,
&
Private
::
isPublished
);
addProperty
(
"isTemplateSpecialization"
,
this
,
&
Private
::
isTemplateSpecialization
);
addProperty
(
"isObjCMethod"
,
this
,
&
Private
::
isObjCMethod
);
addProperty
(
"isObjCProperty"
,
this
,
&
Private
::
isObjCProperty
);
addProperty
(
"isDefine"
,
this
,
&
Private
::
isDefine
);
addProperty
(
"isImplementation"
,
this
,
&
Private
::
isImplementation
);
addProperty
(
"isEvent"
,
this
,
&
Private
::
isEvent
);
addProperty
(
"isProperty"
,
this
,
&
Private
::
isProperty
);
addProperty
(
"isEnumeration"
,
this
,
&
Private
::
isEnumeration
);
addProperty
(
"isEnumValue"
,
this
,
&
Private
::
isEnumValue
);
addProperty
(
"isAnonymous"
,
this
,
&
Private
::
isAnonymous
);
addProperty
(
"declType"
,
this
,
&
Private
::
declType
);
addProperty
(
"declArgs"
,
this
,
&
Private
::
declArgs
);
addProperty
(
"anonymousType"
,
this
,
&
Private
::
anonymousType
);
addProperty
(
"anonymousMember"
,
this
,
&
Private
::
anonymousMember
);
addProperty
(
"isRelated"
,
this
,
&
Private
::
isRelated
);
addProperty
(
"hasDetails"
,
this
,
&
Private
::
hasDetails
);
addProperty
(
"exception"
,
this
,
&
Private
::
exception
);
addProperty
(
"bitfields"
,
this
,
&
Private
::
bitfields
);
...
...
@@ -2214,6 +2707,7 @@ class MemberContext::Private : public DefinitionContext<MemberContext::Private>
addProperty
(
"callGraph"
,
this
,
&
Private
::
callGraph
);
addProperty
(
"hasCallerGraph"
,
this
,
&
Private
::
hasCallerGraph
);
addProperty
(
"callerGraph"
,
this
,
&
Private
::
callerGraph
);
addProperty
(
"fieldType"
,
this
,
&
Private
::
fieldType
);
if
(
md
&&
md
->
isProperty
())
{
...
...
@@ -2227,6 +2721,10 @@ class MemberContext::Private : public DefinitionContext<MemberContext::Private>
if
(
md
->
isRaisable
())
m_eventAttrs
.
append
(
"raise"
);
}
}
TemplateVariant
fieldType
()
const
{
return
createLinkedText
(
m_memberDef
,
relPathAsString
(),
m_memberDef
->
fieldType
());
}
TemplateVariant
declType
()
const
{
return
createLinkedText
(
m_memberDef
,
relPathAsString
(),
m_memberDef
->
getDeclType
());
...
...
@@ -2259,10 +2757,202 @@ class MemberContext::Private : public DefinitionContext<MemberContext::Private>
{
return
m_memberDef
->
isImplementation
();
}
TemplateVariant
isSignal
()
const
{
return
m_memberDef
->
isSignal
();
}
TemplateVariant
isSlot
()
const
{
return
m_memberDef
->
isSlot
();
}
TemplateVariant
isTypedef
()
const
{
return
m_memberDef
->
isTypedef
();
}
TemplateVariant
isFunction
()
const
{
return
m_memberDef
->
isFunction
();
}
TemplateVariant
isFunctionPtr
()
const
{
return
m_memberDef
->
isFunctionPtr
();
}
TemplateVariant
isFriend
()
const
{
return
m_memberDef
->
isFriend
();
}
TemplateVariant
isForeign
()
const
{
return
m_memberDef
->
isForeign
();
}
TemplateVariant
isEvent
()
const
{
return
m_memberDef
->
isEvent
();
}
TemplateVariant
isInline
()
const
{
return
m_memberDef
->
isInline
();
}
TemplateVariant
isExplicit
()
const
{
return
m_memberDef
->
isExplicit
();
}
TemplateVariant
isMutable
()
const
{
return
m_memberDef
->
isMutable
();
}
TemplateVariant
isGettable
()
const
{
return
m_memberDef
->
isSettable
();
}
TemplateVariant
isSettable
()
const
{
return
m_memberDef
->
isSettable
();
}
TemplateVariant
isReadable
()
const
{
return
m_memberDef
->
isReadable
();
}
TemplateVariant
isWritable
()
const
{
return
m_memberDef
->
isWritable
();
}
TemplateVariant
isAddable
()
const
{
return
m_memberDef
->
isAddable
();
}
TemplateVariant
isRemovable
()
const
{
return
m_memberDef
->
isRemovable
();
}
TemplateVariant
isRaisable
()
const
{
return
m_memberDef
->
isRaisable
();
}
TemplateVariant
isFinal
()
const
{
return
m_memberDef
->
isFinal
();
}
TemplateVariant
isAbstract
()
const
{
return
m_memberDef
->
isAbstract
();
}
TemplateVariant
isOverride
()
const
{
return
m_memberDef
->
isOverride
();
}
TemplateVariant
isInitonly
()
const
{
return
m_memberDef
->
isInitonly
();
}
TemplateVariant
isOptional
()
const
{
return
m_memberDef
->
isOptional
();
}
TemplateVariant
isRequired
()
const
{
return
m_memberDef
->
isRequired
();
}
TemplateVariant
isNonAtomic
()
const
{
return
m_memberDef
->
isNonAtomic
();
}
TemplateVariant
isCopy
()
const
{
return
m_memberDef
->
isCopy
();
}
TemplateVariant
isAssign
()
const
{
return
m_memberDef
->
isAssign
();
}
TemplateVariant
isRetain
()
const
{
return
m_memberDef
->
isRetain
();
}
TemplateVariant
isWeak
()
const
{
return
m_memberDef
->
isWeak
();
}
TemplateVariant
isStrong
()
const
{
return
m_memberDef
->
isStrong
();
}
TemplateVariant
isUnretained
()
const
{
return
m_memberDef
->
isUnretained
();
}
TemplateVariant
isNew
()
const
{
return
m_memberDef
->
isNew
();
}
TemplateVariant
isSealed
()
const
{
return
m_memberDef
->
isSealed
();
}
TemplateVariant
isExternal
()
const
{
return
m_memberDef
->
isExternal
();
}
TemplateVariant
isAlias
()
const
{
return
m_memberDef
->
isAlias
();
}
TemplateVariant
isDefault
()
const
{
return
m_memberDef
->
isDefault
();
}
TemplateVariant
isDelete
()
const
{
return
m_memberDef
->
isDelete
();
}
TemplateVariant
isNoExcept
()
const
{
return
m_memberDef
->
isNoExcept
();
}
TemplateVariant
isAttribute
()
const
{
return
m_memberDef
->
isAttribute
();
}
TemplateVariant
isUNOProperty
()
const
{
return
m_memberDef
->
isUNOProperty
();
}
TemplateVariant
isReadonly
()
const
{
return
m_memberDef
->
isReadonly
();
}
TemplateVariant
isBound
()
const
{
return
m_memberDef
->
isBound
();
}
TemplateVariant
isConstrained
()
const
{
return
m_memberDef
->
isConstrained
();
}
TemplateVariant
isTransient
()
const
{
return
m_memberDef
->
isTransient
();
}
TemplateVariant
isMaybeVoid
()
const
{
return
m_memberDef
->
isMaybeVoid
();
}
TemplateVariant
isMaybeDefault
()
const
{
return
m_memberDef
->
isMaybeDefault
();
}
TemplateVariant
isMaybeAmbiguous
()
const
{
return
m_memberDef
->
isMaybeAmbiguous
();
}
TemplateVariant
isPublished
()
const
{
return
m_memberDef
->
isPublished
();
}
TemplateVariant
isTemplateSpecialization
()
const
{
return
m_memberDef
->
isTemplateSpecialization
();
}
TemplateVariant
isProperty
()
const
{
return
m_memberDef
->
isProperty
();
...
...
@@ -2271,6 +2961,10 @@ class MemberContext::Private : public DefinitionContext<MemberContext::Private>
{
return
m_memberDef
->
isEnumValue
();
}
TemplateVariant
isVariable
()
const
{
return
m_memberDef
->
isVariable
();
}
TemplateVariant
isEnumeration
()
const
{
return
m_memberDef
->
isEnumerate
();
...
...
@@ -2717,10 +3411,10 @@ class MemberContext::Private : public DefinitionContext<MemberContext::Private>
TemplateVariant
functionQualifier
()
const
{
if
(
!
m_memberDef
->
isObjCMethod
()
&&
(
m_memberDef
->
isFunction
()
||
m_memberDef
->
isSlot
()
||
(
m_memberDef
->
isFunction
()
||
m_memberDef
->
isSlot
()
||
m_memberDef
->
isPrototype
()
||
m_memberDef
->
isSignal
()
)
)
)
{
return
"()"
;
}
...
...
@@ -3007,6 +3701,47 @@ void NestedClassListContext::append(ClassDef *cd)
//------------------------------------------------------------------------
//%% list NestedClassList[Class] : list of nested namespaces
class
NestedNamespaceListContext
::
Private
:
public
GenericNodeListContext
<
NamespaceContext
>
{
};
NestedNamespaceListContext
::
NestedNamespaceListContext
()
{
p
=
new
Private
;
}
NestedNamespaceListContext
::~
NestedNamespaceListContext
()
{
delete
p
;
}
// TemplateListIntf
int
NestedNamespaceListContext
::
count
()
const
{
return
p
->
count
();
}
TemplateVariant
NestedNamespaceListContext
::
at
(
int
index
)
const
{
return
p
->
at
(
index
);
}
TemplateListIntf
::
ConstIterator
*
NestedNamespaceListContext
::
createIterator
()
const
{
return
p
->
createIterator
();
}
void
NestedNamespaceListContext
::
append
(
NamespaceDef
*
cd
)
{
if
(
cd
)
{
p
->
append
(
new
NamespaceContext
(
cd
));
}
}
//------------------------------------------------------------------------
//%% list ClassList[Class] : list of classes
class
ClassListContext
::
Private
:
public
GenericNodeListContext
<
ClassContext
>
{
...
...
@@ -5744,7 +6479,7 @@ void generateOutputViaTemplate()
ctx
->
set
(
"exampleList"
,
&
exampleList
);
// render HTML output
Template
*
tpl
=
e
.
loadByName
(
"htmllayout.tpl"
);
Template
*
tpl
=
e
.
loadByName
(
"htmllayout.tpl"
,
1
);
if
(
tpl
)
{
g_globals
.
outputFormat
=
ContextGlobals
::
Html
;
...
...
@@ -5758,6 +6493,7 @@ void generateOutputViaTemplate()
FTextStream
ts
;
tpl
->
render
(
ts
,
ctx
);
}
e
.
unload
(
tpl
);
// TODO: render other outputs
}
...
...
src/context.h
View file @
744d1ca5
...
...
@@ -3,6 +3,7 @@
#include "types.h"
#include "template.h"
#include <qlist.h>
class
Definition
;
class
ClassDef
;
...
...
@@ -108,7 +109,7 @@ class UsedFilesContext : public TemplateListIntf
class
IncludeInfoContext
:
public
TemplateStructIntf
{
public
:
IncludeInfoContext
(
IncludeInfo
*
,
SrcLangExt
lang
);
IncludeInfoContext
(
const
IncludeInfo
*
,
SrcLangExt
lang
);
~
IncludeInfoContext
();
// TemplateStructIntf methods
...
...
@@ -119,6 +120,25 @@ class IncludeInfoContext : public TemplateStructIntf
Private
*
p
;
};
//----------------------------------------------------
class
IncludeInfoListContext
:
public
TemplateListIntf
{
public
:
IncludeInfoListContext
(
const
QList
<
IncludeInfo
>
&
list
,
SrcLangExt
lang
);
~
IncludeInfoListContext
();
// TemplateListIntf
virtual
int
count
()
const
;
virtual
TemplateVariant
at
(
int
index
)
const
;
virtual
TemplateListIntf
::
ConstIterator
*
createIterator
()
const
;
private
:
class
Private
;
Private
*
p
;
};
//----------------------------------------------------
class
ClassContext
:
public
TemplateStructIntf
...
...
@@ -254,6 +274,26 @@ class NestedClassListContext : public TemplateListIntf
//----------------------------------------------------
class
NestedNamespaceListContext
:
public
TemplateListIntf
{
public
:
NestedNamespaceListContext
();
~
NestedNamespaceListContext
();
// TemplateListIntf
virtual
int
count
()
const
;
virtual
TemplateVariant
at
(
int
index
)
const
;
virtual
TemplateListIntf
::
ConstIterator
*
createIterator
()
const
;
void
append
(
NamespaceDef
*
cd
);
private
:
class
Private
;
Private
*
p
;
};
//----------------------------------------------------
class
ClassListContext
:
public
TemplateListIntf
{
public
:
...
...
src/filedef.cpp
View file @
744d1ca5
...
...
@@ -170,12 +170,18 @@ void FileDef::findSectionsInDocumentation()
}
}
bool
FileDef
::
hasDetailedDescription
()
const
{
static
bool
sourceBrowser
=
Config_getBool
(
"SOURCE_BROWSER"
);
return
((
!
briefDescription
().
isEmpty
()
&&
Config_getBool
(
"REPEAT_BRIEF"
))
||
!
documentation
().
stripWhiteSpace
().
isEmpty
()
||
// avail empty section
(
sourceBrowser
&&
getStartBodyLine
()
!=-
1
&&
getBodyDef
())
);
}
void
FileDef
::
writeDetailedDescription
(
OutputList
&
ol
,
const
QCString
&
title
)
{
if
((
!
briefDescription
().
isEmpty
()
&&
Config_getBool
(
"REPEAT_BRIEF"
))
||
!
documentation
().
stripWhiteSpace
().
isEmpty
()
||
// avail empty section
(
Config_getBool
(
"SOURCE_BROWSER"
)
&&
getStartBodyLine
()
!=-
1
&&
getBodyDef
())
)
if
(
hasDetailedDescription
())
{
ol
.
pushGeneratorState
();
ol
.
disable
(
OutputGenerator
::
Html
);
...
...
@@ -379,7 +385,7 @@ void FileDef::writeIncludedByGraph(OutputList &ol)
{
warn_uncond
(
"Included by graph for '%s' not generated, too many nodes. Consider increasing DOT_GRAPH_MAX_NODES.
\n
"
,
name
().
data
());
}
if
(
!
incDepGraph
.
isTrivial
())
else
if
(
!
incDepGraph
.
isTrivial
())
{
ol
.
startTextBlock
();
ol
.
disable
(
OutputGenerator
::
Man
);
...
...
@@ -1800,3 +1806,7 @@ QCString FileDef::title() const
return
theTranslator
->
trFileReference
(
name
());
}
QCString
FileDef
::
fileVersion
()
const
{
return
m_fileVersion
;
}
src/filedef.h
View file @
744d1ca5
...
...
@@ -133,6 +133,10 @@ class FileDef : public Definition
ClassSDict
*
getClassSDict
()
const
{
return
m_classSDict
;
}
QCString
title
()
const
;
bool
hasDetailedDescription
()
const
;
QCString
fileVersion
()
const
;
bool
subGrouping
()
const
{
return
m_subGrouping
;
}
//---------------------------------
...
...
src/memberdef.cpp
View file @
744d1ca5
...
...
@@ -3036,6 +3036,18 @@ static Definition *getClassFromType(Definition *scope,const QCString &type,SrcLa
}
#endif
QCString
MemberDef
::
fieldType
()
const
{
QCString
type
=
m_impl
->
accessorType
;
if
(
type
.
isEmpty
())
{
type
=
m_impl
->
type
;
}
if
(
isTypedef
())
type
.
prepend
(
"typedef "
);
return
simplifyTypeForTable
(
type
);
}
void
MemberDef
::
writeMemberDocSimple
(
OutputList
&
ol
,
Definition
*
container
)
{
Definition
*
scope
=
getOuterScope
();
...
...
@@ -3056,15 +3068,7 @@ void MemberDef::writeMemberDocSimple(OutputList &ol, Definition *container)
ol
.
startInlineMemberType
();
ol
.
startDoxyAnchor
(
cfname
,
cname
,
memAnchor
,
doxyName
,
doxyArgs
);
QCString
type
=
m_impl
->
accessorType
;
if
(
type
.
isEmpty
())
{
type
=
m_impl
->
type
;
}
if
(
isTypedef
())
type
.
prepend
(
"typedef "
);
QCString
ts
=
simplifyTypeForTable
(
type
);
QCString
ts
=
fieldType
();
if
(
cd
)
// cd points to an anonymous struct pointed to by this member
// so we add a link to it from the type column.
...
...
@@ -3855,6 +3859,11 @@ void MemberDef::setAccessorType(ClassDef *cd,const char *t)
m_impl
->
accessorType
=
t
;
}
ClassDef
*
MemberDef
::
accessorClass
()
const
{
return
m_impl
->
accessorClass
;
}
void
MemberDef
::
findSectionsInDocumentation
()
{
docFindSections
(
documentation
(),
this
,
0
,
docFile
());
...
...
src/memberdef.h
View file @
744d1ca5
...
...
@@ -81,6 +81,7 @@ class MemberDef : public Definition
ClassDef
*
getClassDef
()
const
;
FileDef
*
getFileDef
()
const
;
NamespaceDef
*
getNamespaceDef
()
const
;
ClassDef
*
accessorClass
()
const
;
// grabbing the property read/write accessor names
const
char
*
getReadAccessor
()
const
;
...
...
@@ -251,7 +252,7 @@ class MemberDef : public Definition
// overrules
QCString
documentation
()
const
;
QCString
briefDescription
(
bool
abbr
=
FALSE
)
const
;
QCString
fieldType
()
const
;
//-----------------------------------------------------------------------------------
...
...
src/message.cpp
View file @
744d1ca5
...
...
@@ -13,7 +13,6 @@
*
*/
#include <stdarg.h>
#include <stdio.h>
#include <qdatetime.h>
#include "config.h"
...
...
@@ -22,6 +21,7 @@
#include "doxygen.h"
#include "portable.h"
#include "filedef.h"
#include "message.h"
static
QCString
outputFormat
;
static
const
char
*
warning_str
=
"warning: "
;
...
...
@@ -110,7 +110,7 @@ void msg(const char *fmt, ...)
va_list
args
;
va_start
(
args
,
fmt
);
vfprintf
(
stdout
,
fmt
,
args
);
va_end
(
args
);
va_end
(
args
);
}
}
...
...
@@ -172,6 +172,11 @@ void warn(const char *file,int line,const char *fmt, ...)
va_end
(
args
);
}
void
warn
(
const
char
*
file
,
int
line
,
const
char
*
fmt
,
va_list
args
)
{
do_warn
(
"WARNINGS"
,
file
,
line
,
warning_str
,
fmt
,
args
);
}
void
warn_simple
(
const
char
*
file
,
int
line
,
const
char
*
text
)
{
if
(
!
Config_getBool
(
"WARNINGS"
))
return
;
// warning type disabled
...
...
src/message.h
View file @
744d1ca5
...
...
@@ -19,9 +19,11 @@
#define MESSAGE_H
#include <stdio.h>
#include <stdarg.h>
extern
void
msg
(
const
char
*
fmt
,
...);
extern
void
warn
(
const
char
*
file
,
int
line
,
const
char
*
fmt
,
...);
extern
void
warn
(
const
char
*
file
,
int
line
,
const
char
*
fmt
,
va_list
args
);
extern
void
warn_simple
(
const
char
*
file
,
int
line
,
const
char
*
text
);
extern
void
warn_undoc
(
const
char
*
file
,
int
line
,
const
char
*
fmt
,
...);
extern
void
warn_doc_error
(
const
char
*
file
,
int
line
,
const
char
*
fmt
,
...);
...
...
src/namespacedef.cpp
View file @
744d1ca5
...
...
@@ -916,29 +916,9 @@ void NamespaceSDict::writeDeclaration(OutputList &ol,const char *title,
continue
;
// will be output in another pass, see layout_default.xml
ol
.
startMemberDeclaration
();
ol
.
startMemberItem
(
nd
->
getOutputFileBase
(),
0
);
if
(
lang
==
SrcLangExt_Java
||
lang
==
SrcLangExt_CSharp
)
{
ol
.
docify
(
"package "
);
}
else
if
(
lang
==
SrcLangExt_Fortran
)
{
ol
.
docify
(
"module "
);
}
else
if
(
lang
==
SrcLangExt_IDL
)
{
if
(
nd
->
isModule
())
{
ol
.
docify
(
"module "
);
}
else
if
(
nd
->
isConstantGroup
())
{
ol
.
docify
(
"constants"
);
}
else
{
err
(
"Internal inconsistency: namespace in IDL not module or cg
\n
"
);
}
}
QCString
ct
=
nd
->
compoundTypeString
();
ol
.
docify
(
ct
);
ol
.
docify
(
" "
);
ol
.
insertMemberAlign
();
QCString
name
;
if
(
localName
)
...
...
@@ -1103,3 +1083,33 @@ QCString NamespaceDef::title() const
}
return
pageTitle
;
}
QCString
NamespaceDef
::
compoundTypeString
()
const
{
SrcLangExt
lang
=
getLanguage
();
if
(
lang
==
SrcLangExt_Java
||
lang
==
SrcLangExt_CSharp
)
{
return
"package"
;
}
else
if
(
lang
==
SrcLangExt_Fortran
)
{
return
"module"
;
}
else
if
(
lang
==
SrcLangExt_IDL
)
{
if
(
isModule
())
{
return
"module"
;
}
else
if
(
isConstantGroup
())
{
return
"constants"
;
}
else
{
err
(
"Internal inconsistency: namespace in IDL not module or constant group
\n
"
);
}
}
return
""
;
}
src/namespacedef.h
View file @
744d1ca5
...
...
@@ -94,6 +94,7 @@ class NamespaceDef : public Definition
NamespaceSDict
*
getNamespaceSDict
()
const
{
return
namespaceSDict
;
}
QCString
title
()
const
;
QCString
compoundTypeString
()
const
;
bool
visited
;
...
...
src/template.cpp
View file @
744d1ca5
...
...
@@ -29,7 +29,8 @@ class TemplateToken;
//-------------------------------------------------------------------
static
QValueList
<
QCString
>
split
(
const
QCString
&
str
,
const
QCString
&
sep
,
bool
allowEmptyEntries
=
FALSE
,
bool
cleanup
=
TRUE
)
static
QValueList
<
QCString
>
split
(
const
QCString
&
str
,
const
QCString
&
sep
,
bool
allowEmptyEntries
=
FALSE
,
bool
cleanup
=
TRUE
)
{
QValueList
<
QCString
>
lst
;
...
...
@@ -561,7 +562,7 @@ class TemplateBlockContext
class
TemplateContextImpl
:
public
TemplateContext
{
public
:
TemplateContextImpl
();
TemplateContextImpl
(
const
TemplateEngine
*
e
);
virtual
~
TemplateContextImpl
();
// TemplateContext methods
...
...
@@ -589,8 +590,10 @@ class TemplateContextImpl : public TemplateContext
TemplateSpacelessIntf
*
spacelessIntf
()
const
{
return
m_spacelessIntf
;
}
void
enableSpaceless
(
bool
b
)
{
m_spacelessEnabled
=
b
;
}
bool
spacelessEnabled
()
const
{
return
m_spacelessEnabled
&&
m_spacelessIntf
;
}
void
warn
(
const
char
*
fileName
,
int
line
,
const
char
*
fmt
,...)
const
;
private
:
const
TemplateEngine
*
m_engine
;
QCString
m_templateName
;
int
m_line
;
QCString
m_outputDir
;
...
...
@@ -874,7 +877,7 @@ class ExprAstVariable : public ExprAst
TemplateVariant
v
=
c
->
get
(
m_name
);
if
(
!
v
.
isValid
())
{
warn
(
ci
->
templateName
(),
ci
->
line
(),
"undefined variable '%s' in expression"
,
m_name
.
data
());
ci
->
warn
(
ci
->
templateName
(),
ci
->
line
(),
"undefined variable '%s' in expression"
,
m_name
.
data
());
}
return
v
;
}
...
...
@@ -928,7 +931,7 @@ class ExprAstFilter : public ExprAst
TemplateVariant
result
=
TemplateFilterFactory
::
instance
()
->
apply
(
m_name
,
v
,
arg
,
ok
);
if
(
!
ok
)
{
warn
(
ci
->
templateName
(),
ci
->
line
(),
"unknown filter '%s'"
,
m_name
.
data
());
ci
->
warn
(
ci
->
templateName
(),
ci
->
line
(),
"unknown filter '%s'"
,
m_name
.
data
());
}
return
result
;
}
...
...
@@ -1047,6 +1050,46 @@ class ExprAstBinary : public ExprAst
ExprAst
*
m_rhs
;
};
//----------------------------------------------------------
/** @brief Base class of all nodes in a template's AST */
class
TemplateNode
{
public
:
TemplateNode
(
TemplateNode
*
parent
)
:
m_parent
(
parent
)
{}
virtual
~
TemplateNode
()
{}
virtual
void
render
(
FTextStream
&
ts
,
TemplateContext
*
c
)
=
0
;
TemplateNode
*
parent
()
{
return
m_parent
;
}
private
:
TemplateNode
*
m_parent
;
};
//----------------------------------------------------------
/** @brief Parser for templates */
class
TemplateParser
{
public
:
TemplateParser
(
const
TemplateEngine
*
engine
,
const
QCString
&
templateName
,
QList
<
TemplateToken
>
&
tokens
);
void
parse
(
TemplateNode
*
parent
,
int
line
,
const
QStrList
&
stopAt
,
QList
<
TemplateNode
>
&
nodes
);
bool
hasNextToken
()
const
;
TemplateToken
*
takeNextToken
();
void
removeNextToken
();
void
prependToken
(
const
TemplateToken
*
token
);
const
TemplateToken
*
currentToken
()
const
;
QCString
templateName
()
const
{
return
m_templateName
;
}
void
warn
(
const
char
*
fileName
,
int
line
,
const
char
*
fmt
,...)
const
;
private
:
const
TemplateEngine
*
m_engine
;
QCString
m_templateName
;
QList
<
TemplateToken
>
&
m_tokens
;
};
//--------------------------------------------------------------------
/** @brief Recursive decent parser for Django style template expressions.
...
...
@@ -1054,8 +1097,8 @@ class ExprAstBinary : public ExprAst
class
ExpressionParser
{
public
:
ExpressionParser
(
const
QCString
&
templateName
,
int
line
)
:
m_
templateName
(
templateName
),
m_line
(
line
),
m_tokenStream
(
0
)
ExpressionParser
(
const
TemplateParser
*
parser
,
int
line
)
:
m_
parser
(
parser
),
m_line
(
line
),
m_tokenStream
(
0
)
{
}
virtual
~
ExpressionParser
()
...
...
@@ -1153,7 +1196,7 @@ class ExpressionParser
ExprAst
*
expr
=
parseCompareExpression
();
if
(
expr
==
0
)
{
warn
(
m_
templateName
,
m_line
,
"argument missing for not operator"
);
warn
(
m_
parser
->
templateName
()
,
m_line
,
"argument missing for not operator"
);
return
0
;
}
result
=
new
ExprAstNegate
(
expr
);
...
...
@@ -1210,12 +1253,12 @@ class ExpressionParser
default:
if
(
m_curToken
.
type
==
ExprToken
::
Operator
)
{
warn
(
m_
templateName
,
m_line
,
"unexpected operator '%s' in expression"
,
warn
(
m_
parser
->
templateName
()
,
m_line
,
"unexpected operator '%s' in expression"
,
Operator
::
toString
(
m_curToken
.
op
));
}
else
{
warn
(
m_
templateName
,
m_line
,
"unexpected token in expression"
);
warn
(
m_
parser
->
templateName
()
,
m_line
,
"unexpected token in expression"
);
}
}
TRACE
((
"}parsePrimary(%s)
\n
"
,
m_tokenStream
));
...
...
@@ -1461,7 +1504,7 @@ class ExpressionParser
char
s
[
2
];
s
[
0
]
=
c
;
s
[
1
]
=
0
;
warn
(
m_
templateName
,
m_line
,
"Found unknown token %s while parsing %s"
,
s
,
m_tokenStream
);
warn
(
m_
parser
->
templateName
()
,
m_line
,
"Found unknown token %s while parsing %s"
,
s
,
m_tokenStream
);
m_curToken
.
id
=
s
;
p
++
;
}
...
...
@@ -1472,51 +1515,14 @@ class ExpressionParser
return
TRUE
;
}
const
TemplateParser
*
m_parser
;
ExprToken
m_curToken
;
QCString
m_templateName
;
int
m_line
;
const
char
*
m_tokenStream
;
};
//----------------------------------------------------------
/** @brief Base class of all nodes in a template's AST */
class
TemplateNode
{
public
:
TemplateNode
(
TemplateNode
*
parent
)
:
m_parent
(
parent
)
{}
virtual
~
TemplateNode
()
{}
virtual
void
render
(
FTextStream
&
ts
,
TemplateContext
*
c
)
=
0
;
TemplateNode
*
parent
()
{
return
m_parent
;
}
private
:
TemplateNode
*
m_parent
;
};
//----------------------------------------------------------
/** @brief Parser for templates */
class
TemplateParser
{
public
:
TemplateParser
(
const
QCString
&
templateName
,
QList
<
TemplateToken
>
&
tokens
);
void
parse
(
TemplateNode
*
parent
,
int
line
,
const
QStrList
&
stopAt
,
QList
<
TemplateNode
>
&
nodes
);
bool
hasNextToken
()
const
;
TemplateToken
*
takeNextToken
();
void
removeNextToken
();
void
prependToken
(
const
TemplateToken
*
token
);
const
TemplateToken
*
currentToken
()
const
;
QCString
templateName
()
const
{
return
m_templateName
;
}
private
:
QCString
m_templateName
;
QList
<
TemplateToken
>
&
m_tokens
;
};
//----------------------------------------------------------
/** @brief Class representing a lexical token in a template */
class
TemplateToken
{
...
...
@@ -1558,24 +1564,23 @@ class TemplateImpl : public TemplateNode, public Template
{
public
:
TemplateImpl
(
TemplateEngine
*
e
,
const
QCString
&
name
,
const
QCString
&
data
);
~
TemplateImpl
()
{}
void
render
(
FTextStream
&
ts
,
TemplateContext
*
c
);
TemplateEngine
*
engine
()
const
{
return
m_engine
;
}
TemplateBlockContext
*
blockContext
()
{
return
&
m_blockContext
;
}
private
:
TemplateEngine
*
m_engine
;
QCString
m_name
;
TemplateNodeList
m_nodes
;
TemplateEngine
*
m_engine
;
TemplateBlockContext
m_blockContext
;
};
//----------------------------------------------------------
TemplateContextImpl
::
TemplateContextImpl
()
:
m_templateName
(
"<unknown>"
),
m_line
(
1
),
m_escapeIntf
(
0
),
TemplateContextImpl
::
TemplateContextImpl
(
const
TemplateEngine
*
e
)
:
m_
engine
(
e
),
m_
templateName
(
"<unknown>"
),
m_line
(
1
),
m_escapeIntf
(
0
),
m_spacelessIntf
(
0
),
m_spacelessEnabled
(
FALSE
)
{
m_contextStack
.
setAutoDelete
(
TRUE
);
...
...
@@ -1704,6 +1709,15 @@ TemplateBlockContext *TemplateContextImpl::blockContext()
return
&
m_blockContext
;
}
void
TemplateContextImpl
::
warn
(
const
char
*
fileName
,
int
line
,
const
char
*
fmt
,...)
const
{
va_list
args
;
va_start
(
args
,
fmt
);
::
warn
(
fileName
,
line
,
fmt
,
args
);
va_end
(
args
);
m_engine
->
printIncludeContext
(
fileName
,
line
);
}
//----------------------------------------------------------
/** @brief Class representing a piece of plain text in a template */
...
...
@@ -1743,7 +1757,7 @@ class TemplateNodeVariable : public TemplateNode
:
TemplateNode
(
parent
),
m_templateName
(
parser
->
templateName
()),
m_line
(
line
)
{
TRACE
((
"TemplateNodeVariable(%s)
\n
"
,
var
.
data
()));
ExpressionParser
expParser
(
m_templateName
,
line
);
ExpressionParser
expParser
(
parser
,
line
);
m_var
=
expParser
.
parseVariable
(
var
);
}
~
TemplateNodeVariable
()
...
...
@@ -1821,14 +1835,14 @@ class TemplateNodeIf : public TemplateNodeCreator<TemplateNodeIf>
TRACE
((
"{TemplateNodeIf(%s)
\n
"
,
data
.
data
()));
if
(
data
.
isEmpty
())
{
warn
(
m_templateName
,
line
,
"missing argument for if tag"
);
parser
->
warn
(
m_templateName
,
line
,
"missing argument for if tag"
);
}
QStrList
stopAt
;
stopAt
.
append
(
"endif"
);
stopAt
.
append
(
"else"
);
parser
->
parse
(
this
,
line
,
stopAt
,
m_trueNodes
);
TemplateToken
*
tok
=
parser
->
takeNextToken
();
ExpressionParser
ex
(
parser
->
templateName
()
,
line
);
ExpressionParser
ex
(
parser
,
line
);
m_guardAst
=
ex
.
parse
(
data
);
if
(
tok
&&
tok
->
data
==
"else"
)
...
...
@@ -1847,7 +1861,8 @@ class TemplateNodeIf : public TemplateNodeCreator<TemplateNodeIf>
void
render
(
FTextStream
&
ts
,
TemplateContext
*
c
)
{
dynamic_cast
<
TemplateContextImpl
*>
(
c
)
->
setLocation
(
m_templateName
,
m_line
);
TemplateContextImpl
*
ci
=
dynamic_cast
<
TemplateContextImpl
*>
(
c
);
ci
->
setLocation
(
m_templateName
,
m_line
);
//printf("TemplateNodeIf::render #trueNodes=%d #falseNodes=%d\n",m_trueNodes.count(),m_falseNodes.count());
if
(
m_guardAst
)
{
...
...
@@ -1877,7 +1892,7 @@ class TemplateNodeRepeat : public TemplateNodeCreator<TemplateNodeRepeat>
:
TemplateNodeCreator
<
TemplateNodeRepeat
>
(
parser
,
parent
,
line
)
{
TRACE
((
"{TemplateNodeRepeat(%s)
\n
"
,
data
.
data
()));
ExpressionParser
expParser
(
parser
->
templateName
()
,
line
);
ExpressionParser
expParser
(
parser
,
line
);
m_expr
=
expParser
.
parseVariable
(
data
);
QStrList
stopAt
;
stopAt
.
append
(
"endrepeat"
);
...
...
@@ -1891,7 +1906,8 @@ class TemplateNodeRepeat : public TemplateNodeCreator<TemplateNodeRepeat>
}
void
render
(
FTextStream
&
ts
,
TemplateContext
*
c
)
{
dynamic_cast
<
TemplateContextImpl
*>
(
c
)
->
setLocation
(
m_templateName
,
m_line
);
TemplateContextImpl
*
ci
=
dynamic_cast
<
TemplateContextImpl
*>
(
c
);
ci
->
setLocation
(
m_templateName
,
m_line
);
TemplateVariant
v
;
if
(
m_expr
&&
(
v
=
m_expr
->
resolve
(
c
)).
type
()
==
TemplateVariant
::
Integer
)
{
...
...
@@ -1912,7 +1928,7 @@ class TemplateNodeRepeat : public TemplateNodeCreator<TemplateNodeRepeat>
}
else
// simple type...
{
warn
(
m_templateName
,
m_line
,
"for requires a variable of list type!"
);
ci
->
warn
(
m_templateName
,
m_line
,
"for requires a variable of list type!"
);
}
}
private
:
...
...
@@ -1936,15 +1952,15 @@ class TemplateNodeFor : public TemplateNodeCreator<TemplateNodeFor>
{
if
(
data
.
right
(
3
)
==
" in"
)
{
warn
(
m_templateName
,
line
,
"for is missing container after 'in' keyword"
);
parser
->
warn
(
m_templateName
,
line
,
"for is missing container after 'in' keyword"
);
}
else
if
(
data
==
"in"
)
{
warn
(
m_templateName
,
line
,
"for needs at least one iterator variable"
);
parser
->
warn
(
m_templateName
,
line
,
"for needs at least one iterator variable"
);
}
else
{
warn
(
m_templateName
,
line
,
"for is missing 'in' keyword"
);
parser
->
warn
(
m_templateName
,
line
,
"for is missing 'in' keyword"
);
}
}
else
...
...
@@ -1952,7 +1968,7 @@ class TemplateNodeFor : public TemplateNodeCreator<TemplateNodeFor>
m_vars
=
split
(
data
.
left
(
i
),
","
);
if
(
m_vars
.
count
()
==
0
)
{
warn
(
m_templateName
,
line
,
"for needs at least one iterator variable"
);
parser
->
warn
(
m_templateName
,
line
,
"for needs at least one iterator variable"
);
}
int
j
=
data
.
find
(
" reversed"
,
i
);
...
...
@@ -1965,10 +1981,10 @@ class TemplateNodeFor : public TemplateNodeCreator<TemplateNodeFor>
}
if
(
exprStr
.
isEmpty
())
{
warn
(
m_templateName
,
line
,
"for is missing container after 'in' keyword"
);
parser
->
warn
(
m_templateName
,
line
,
"for is missing container after 'in' keyword"
);
}
}
ExpressionParser
expParser
(
parser
->
templateName
()
,
line
);
ExpressionParser
expParser
(
parser
,
line
);
m_expr
=
expParser
.
parseVariable
(
exprStr
);
QStrList
stopAt
;
...
...
@@ -1993,7 +2009,8 @@ class TemplateNodeFor : public TemplateNodeCreator<TemplateNodeFor>
void
render
(
FTextStream
&
ts
,
TemplateContext
*
c
)
{
dynamic_cast
<
TemplateContextImpl
*>
(
c
)
->
setLocation
(
m_templateName
,
m_line
);
TemplateContextImpl
*
ci
=
dynamic_cast
<
TemplateContextImpl
*>
(
c
);
ci
->
setLocation
(
m_templateName
,
m_line
);
//printf("TemplateNodeFor::render #loopNodes=%d #emptyNodes=%d\n",
// m_loopNodes.count(),m_emptyNodes.count());
if
(
m_expr
)
...
...
@@ -2058,7 +2075,7 @@ class TemplateNodeFor : public TemplateNodeCreator<TemplateNodeFor>
}
else
// simple type...
{
warn
(
m_templateName
,
m_line
,
"for requires a variable of list type!"
);
ci
->
warn
(
m_templateName
,
m_line
,
"for requires a variable of list type!"
);
}
}
}
...
...
@@ -2090,6 +2107,7 @@ class TemplateNodeMsg : public TemplateNodeCreator<TemplateNodeMsg>
void
render
(
FTextStream
&
,
TemplateContext
*
c
)
{
TemplateContextImpl
*
ci
=
dynamic_cast
<
TemplateContextImpl
*>
(
c
);
ci
->
setLocation
(
m_templateName
,
m_line
);
TemplateEscapeIntf
*
escIntf
=
ci
->
escapeIntf
();
ci
->
setEscapeIntf
(
0
);
// avoid escaping things we send to standard out
bool
enable
=
ci
->
spacelessEnabled
();
...
...
@@ -2118,7 +2136,7 @@ class TemplateNodeBlock : public TemplateNodeCreator<TemplateNodeBlock>
m_blockName
=
data
;
if
(
m_blockName
.
isEmpty
())
{
warn
(
parser
->
templateName
(),
line
,
"block tag without name"
);
parser
->
warn
(
parser
->
templateName
(),
line
,
"block tag without name"
);
}
QStrList
stopAt
;
stopAt
.
append
(
"endblock"
);
...
...
@@ -2156,14 +2174,18 @@ class TemplateNodeBlock : public TemplateNodeCreator<TemplateNodeBlock>
superBlock
.
set
(
"super"
,
TemplateVariant
(
super
.
data
(),
TRUE
));
ci
->
set
(
"block"
,
&
superBlock
);
// render the overruled block contents
t
->
engine
()
->
enterBlock
(
nb
->
m_templateName
,
nb
->
m_blockName
,
nb
->
m_line
);
nb
->
m_nodes
.
render
(
ts
,
c
);
t
->
engine
()
->
leaveBlock
();
ci
->
pop
();
// re-add block to the context
ci
->
blockContext
()
->
push
(
nb
);
}
else
// block has no overrule
{
t
->
engine
()
->
enterBlock
(
m_templateName
,
m_blockName
,
m_line
);
m_nodes
.
render
(
ts
,
c
);
t
->
engine
()
->
leaveBlock
();
}
}
}
...
...
@@ -2188,10 +2210,10 @@ class TemplateNodeExtend : public TemplateNodeCreator<TemplateNodeExtend>
:
TemplateNodeCreator
<
TemplateNodeExtend
>
(
parser
,
parent
,
line
)
{
TRACE
((
"{TemplateNodeExtend(%s)
\n
"
,
data
.
data
()));
ExpressionParser
ep
(
m_templateName
,
line
);
ExpressionParser
ep
(
parser
,
line
);
if
(
data
.
isEmpty
())
{
warn
(
m_templateName
,
line
,
"extend tag is missing template file argument"
);
parser
->
warn
(
m_templateName
,
line
,
"extend tag is missing template file argument"
);
}
m_extendExpr
=
ep
.
parsePrimary
(
data
);
QStrList
stopAt
;
...
...
@@ -2205,20 +2227,21 @@ class TemplateNodeExtend : public TemplateNodeCreator<TemplateNodeExtend>
void
render
(
FTextStream
&
ts
,
TemplateContext
*
c
)
{
dynamic_cast
<
TemplateContextImpl
*>
(
c
)
->
setLocation
(
m_templateName
,
m_line
);
TemplateContextImpl
*
ci
=
dynamic_cast
<
TemplateContextImpl
*>
(
c
);
ci
->
setLocation
(
m_templateName
,
m_line
);
if
(
m_extendExpr
==
0
)
return
;
QCString
extendFile
=
m_extendExpr
->
resolve
(
c
).
toString
();
if
(
extendFile
.
isEmpty
())
{
warn
(
m_templateName
,
m_line
,
"invalid parameter for extend command"
);
ci
->
warn
(
m_templateName
,
m_line
,
"invalid parameter for extend command"
);
}
// goto root of tree (template node)
TemplateImpl
*
t
=
getTemplate
();
if
(
t
)
{
Template
*
bt
=
t
->
engine
()
->
loadByName
(
extendFile
);
Template
*
bt
=
t
->
engine
()
->
loadByName
(
extendFile
,
m_line
);
TemplateImpl
*
baseTemplate
=
bt
?
dynamic_cast
<
TemplateImpl
*>
(
bt
)
:
0
;
if
(
baseTemplate
)
{
...
...
@@ -2248,11 +2271,11 @@ class TemplateNodeExtend : public TemplateNodeCreator<TemplateNodeExtend>
// clean up
bc
->
clear
();
//delete baseTemplate
;
t
->
engine
()
->
unload
(
t
)
;
}
else
{
warn
(
m_templateName
,
m_line
,
"failed to load template %s for extend"
,
extendFile
.
data
());
ci
->
warn
(
m_templateName
,
m_line
,
"failed to load template %s for extend"
,
extendFile
.
data
());
}
}
}
...
...
@@ -2270,10 +2293,10 @@ class TemplateNodeInclude : public TemplateNodeCreator<TemplateNodeInclude>
:
TemplateNodeCreator
<
TemplateNodeInclude
>
(
parser
,
parent
,
line
)
{
TRACE
((
"TemplateNodeInclude(%s)
\n
"
,
data
.
data
()));
ExpressionParser
ep
(
m_templateName
,
line
);
ExpressionParser
ep
(
parser
,
line
);
if
(
data
.
isEmpty
())
{
warn
(
m_templateName
,
line
,
"include tag is missing template file argument"
);
parser
->
warn
(
m_templateName
,
line
,
"include tag is missing template file argument"
);
}
m_includeExpr
=
ep
.
parsePrimary
(
data
);
}
...
...
@@ -2283,28 +2306,30 @@ class TemplateNodeInclude : public TemplateNodeCreator<TemplateNodeInclude>
}
void
render
(
FTextStream
&
ts
,
TemplateContext
*
c
)
{
dynamic_cast
<
TemplateContextImpl
*>
(
c
)
->
setLocation
(
m_templateName
,
m_line
);
TemplateContextImpl
*
ci
=
dynamic_cast
<
TemplateContextImpl
*>
(
c
);
ci
->
setLocation
(
m_templateName
,
m_line
);
if
(
m_includeExpr
)
{
QCString
includeFile
=
m_includeExpr
->
resolve
(
c
).
toString
();
if
(
includeFile
.
isEmpty
())
{
warn
(
m_templateName
,
m_line
,
"invalid parameter for include command
\n
"
);
ci
->
warn
(
m_templateName
,
m_line
,
"invalid parameter for include command
\n
"
);
}
else
{
TemplateImpl
*
t
=
getTemplate
();
if
(
t
)
{
Template
*
it
=
t
->
engine
()
->
loadByName
(
includeFile
);
Template
*
it
=
t
->
engine
()
->
loadByName
(
includeFile
,
m_line
);
TemplateImpl
*
incTemplate
=
it
?
dynamic_cast
<
TemplateImpl
*>
(
it
)
:
0
;
if
(
incTemplate
)
{
incTemplate
->
render
(
ts
,
c
);
t
->
engine
()
->
unload
(
t
);
}
else
{
warn
(
m_templateName
,
m_line
,
"failed to load template '%s' for include"
,
includeFile
.
data
()
?
includeFile
.
data
()
:
""
);
ci
->
warn
(
m_templateName
,
m_line
,
"failed to load template '%s' for include"
,
includeFile
.
data
()
?
includeFile
.
data
()
:
""
);
}
}
}
...
...
@@ -2325,30 +2350,30 @@ class TemplateNodeCreate : public TemplateNodeCreator<TemplateNodeCreate>
:
TemplateNodeCreator
<
TemplateNodeCreate
>
(
parser
,
parent
,
line
)
{
TRACE
((
"TemplateNodeCreate(%s)
\n
"
,
data
.
data
()));
ExpressionParser
ep
(
m_templateName
,
line
);
ExpressionParser
ep
(
parser
,
line
);
if
(
data
.
isEmpty
())
{
warn
(
m_templateName
,
line
,
"create tag is missing arguments"
);
parser
->
warn
(
m_templateName
,
line
,
"create tag is missing arguments"
);
}
int
i
=
data
.
find
(
" from "
);
if
(
i
==-
1
)
{
if
(
data
.
right
(
3
)
==
" from"
)
{
warn
(
m_templateName
,
line
,
"create is missing template name after 'from' keyword"
);
parser
->
warn
(
m_templateName
,
line
,
"create is missing template name after 'from' keyword"
);
}
else
if
(
data
==
"from"
)
{
warn
(
m_templateName
,
line
,
"create needs a file name and a template name"
);
parser
->
warn
(
m_templateName
,
line
,
"create needs a file name and a template name"
);
}
else
{
warn
(
m_templateName
,
line
,
"create is missing 'from' keyword"
);
parser
->
warn
(
m_templateName
,
line
,
"create is missing 'from' keyword"
);
}
}
else
{
ExpressionParser
ep
(
m_templateName
,
line
);
ExpressionParser
ep
(
parser
,
line
);
m_fileExpr
=
ep
.
parsePrimary
(
data
.
left
(
i
).
stripWhiteSpace
());
m_templateExpr
=
ep
.
parsePrimary
(
data
.
mid
(
i
+
6
).
stripWhiteSpace
());
}
...
...
@@ -2368,18 +2393,18 @@ class TemplateNodeCreate : public TemplateNodeCreator<TemplateNodeCreate>
QCString
outputFile
=
m_fileExpr
->
resolve
(
c
).
toString
();
if
(
templateFile
.
isEmpty
())
{
warn
(
m_templateName
,
m_line
,
"empty template name parameter for create command
\n
"
);
ci
->
warn
(
m_templateName
,
m_line
,
"empty template name parameter for create command
\n
"
);
}
else
if
(
outputFile
.
isEmpty
())
{
warn
(
m_templateName
,
m_line
,
"empty file name parameter for create command
\n
"
);
ci
->
warn
(
m_templateName
,
m_line
,
"empty file name parameter for create command
\n
"
);
}
else
{
TemplateImpl
*
t
=
getTemplate
();
if
(
t
)
{
Template
*
ct
=
t
->
engine
()
->
loadByName
(
templateFile
);
Template
*
ct
=
t
->
engine
()
->
loadByName
(
templateFile
,
m_line
);
TemplateImpl
*
createTemplate
=
ct
?
dynamic_cast
<
TemplateImpl
*>
(
ct
)
:
0
;
if
(
createTemplate
)
{
...
...
@@ -2392,16 +2417,16 @@ class TemplateNodeCreate : public TemplateNodeCreator<TemplateNodeCreate>
{
FTextStream
ts
(
&
f
);
createTemplate
->
render
(
ts
,
c
);
//delete createTemplate
;
t
->
engine
()
->
unload
(
t
)
;
}
else
{
warn
(
m_templateName
,
m_line
,
"failed to open output file '%s' for create command"
,
outputFile
.
data
());
ci
->
warn
(
m_templateName
,
m_line
,
"failed to open output file '%s' for create command"
,
outputFile
.
data
());
}
}
else
{
warn
(
m_templateName
,
m_line
,
"failed to load template '%s' for include"
,
templateFile
.
data
());
ci
->
warn
(
m_templateName
,
m_line
,
"failed to load template '%s' for include"
,
templateFile
.
data
());
}
}
}
...
...
@@ -2431,10 +2456,10 @@ class TemplateNodeTree : public TemplateNodeCreator<TemplateNodeTree>
:
TemplateNodeCreator
<
TemplateNodeTree
>
(
parser
,
parent
,
line
)
{
TRACE
((
"{TemplateNodeTree(%s)
\n
"
,
data
.
data
()));
ExpressionParser
ep
(
m_templateName
,
line
);
ExpressionParser
ep
(
parser
,
line
);
if
(
data
.
isEmpty
())
{
warn
(
m_templateName
,
line
,
"recursetree tag is missing data argument"
);
parser
->
warn
(
m_templateName
,
line
,
"recursetree tag is missing data argument"
);
}
m_treeExpr
=
ep
.
parsePrimary
(
data
);
QStrList
stopAt
;
...
...
@@ -2508,7 +2533,7 @@ class TemplateNodeTree : public TemplateNodeCreator<TemplateNodeTree>
}
else
{
warn
(
m_templateName
,
m_line
,
"recursetree's argument should be a list type"
);
ci
->
warn
(
m_templateName
,
m_line
,
"recursetree's argument should be a list type"
);
}
}
...
...
@@ -2535,7 +2560,7 @@ class TemplateNodeWith : public TemplateNodeCreator<TemplateNodeWith>
{
TRACE
((
"{TemplateNodeWith(%s)
\n
"
,
data
.
data
()));
m_args
.
setAutoDelete
(
TRUE
);
ExpressionParser
expParser
(
parser
->
templateName
()
,
line
);
ExpressionParser
expParser
(
parser
,
line
);
QValueList
<
QCString
>
args
=
split
(
data
,
" "
);
QValueListIterator
<
QCString
>
it
=
args
.
begin
();
while
(
it
!=
args
.
end
())
...
...
@@ -2552,7 +2577,7 @@ class TemplateNodeWith : public TemplateNodeCreator<TemplateNodeWith>
}
else
{
warn
(
parser
->
templateName
(),
line
,
"invalid argument '%s' for with tag"
,
arg
.
data
());
parser
->
warn
(
parser
->
templateName
(),
line
,
"invalid argument '%s' for with tag"
,
arg
.
data
());
}
++
it
;
}
...
...
@@ -2568,6 +2593,7 @@ class TemplateNodeWith : public TemplateNodeCreator<TemplateNodeWith>
void
render
(
FTextStream
&
ts
,
TemplateContext
*
c
)
{
TemplateContextImpl
*
ci
=
dynamic_cast
<
TemplateContextImpl
*>
(
c
);
ci
->
setLocation
(
m_templateName
,
m_line
);
c
->
push
();
QListIterator
<
Mapping
>
it
(
m_args
);
Mapping
*
mapping
;
...
...
@@ -2596,7 +2622,7 @@ class TemplateNodeCycle : public TemplateNodeCreator<TemplateNodeCycle>
TRACE
((
"{TemplateNodeCycle(%s)
\n
"
,
data
.
data
()));
m_args
.
setAutoDelete
(
TRUE
);
m_index
=
0
;
ExpressionParser
expParser
(
parser
->
templateName
()
,
line
);
ExpressionParser
expParser
(
parser
,
line
);
QValueList
<
QCString
>
args
=
split
(
data
,
" "
);
QValueListIterator
<
QCString
>
it
=
args
.
begin
();
while
(
it
!=
args
.
end
())
...
...
@@ -2610,13 +2636,14 @@ class TemplateNodeCycle : public TemplateNodeCreator<TemplateNodeCycle>
}
if
(
m_args
.
count
()
<
2
)
{
warn
(
parser
->
templateName
(),
line
,
"expected at least two arguments for cycle command, got %d"
,
m_args
.
count
());
parser
->
warn
(
parser
->
templateName
(),
line
,
"expected at least two arguments for cycle command, got %d"
,
m_args
.
count
());
}
TRACE
((
"}TemplateNodeCycle(%s)
\n
"
,
data
.
data
()));
}
void
render
(
FTextStream
&
ts
,
TemplateContext
*
c
)
{
TemplateContextImpl
*
ci
=
dynamic_cast
<
TemplateContextImpl
*>
(
c
);
ci
->
setLocation
(
m_templateName
,
m_line
);
if
(
m_index
<
m_args
.
count
())
{
TemplateVariant
v
=
m_args
.
at
(
m_index
)
->
resolve
(
c
);
...
...
@@ -2661,7 +2688,7 @@ class TemplateNodeSet : public TemplateNodeCreator<TemplateNodeSet>
{
TRACE
((
"{TemplateNodeSet(%s)
\n
"
,
data
.
data
()));
m_args
.
setAutoDelete
(
TRUE
);
ExpressionParser
expParser
(
parser
->
templateName
()
,
line
);
ExpressionParser
expParser
(
parser
,
line
);
QValueList
<
QCString
>
args
=
split
(
data
,
" "
);
QValueListIterator
<
QCString
>
it
=
args
.
begin
();
while
(
it
!=
args
.
end
())
...
...
@@ -2678,7 +2705,7 @@ class TemplateNodeSet : public TemplateNodeCreator<TemplateNodeSet>
}
else
{
warn
(
parser
->
templateName
(),
line
,
"invalid argument '%s' for with tag"
,
arg
.
data
());
parser
->
warn
(
parser
->
templateName
(),
line
,
"invalid argument '%s' for with tag"
,
arg
.
data
());
}
++
it
;
}
...
...
@@ -2687,6 +2714,7 @@ class TemplateNodeSet : public TemplateNodeCreator<TemplateNodeSet>
void
render
(
FTextStream
&
,
TemplateContext
*
c
)
{
TemplateContextImpl
*
ci
=
dynamic_cast
<
TemplateContextImpl
*>
(
c
);
ci
->
setLocation
(
m_templateName
,
m_line
);
QListIterator
<
Mapping
>
it
(
m_args
);
Mapping
*
mapping
;
for
(
it
.
toFirst
();(
mapping
=
it
.
current
());
++
it
)
...
...
@@ -2718,6 +2746,7 @@ class TemplateNodeSpaceless : public TemplateNodeCreator<TemplateNodeSpaceless>
void
render
(
FTextStream
&
ts
,
TemplateContext
*
c
)
{
TemplateContextImpl
*
ci
=
dynamic_cast
<
TemplateContextImpl
*>
(
c
);
ci
->
setLocation
(
m_templateName
,
m_line
);
bool
wasSpaceless
=
ci
->
spacelessEnabled
();
ci
->
enableSpaceless
(
TRUE
);
m_nodes
.
render
(
ts
,
c
);
...
...
@@ -2741,11 +2770,11 @@ class TemplateNodeMarkers : public TemplateNodeCreator<TemplateNodeMarkers>
int
w
=
data
.
find
(
" with "
);
if
(
i
==-
1
||
w
==-
1
||
w
<
i
)
{
warn
(
m_templateName
,
line
,
"markers tag as wrong format. Expected: markers <var> in <list> with <string_with_markers>"
);
parser
->
warn
(
m_templateName
,
line
,
"markers tag as wrong format. Expected: markers <var> in <list> with <string_with_markers>"
);
}
else
{
ExpressionParser
expParser
(
parser
->
templateName
()
,
line
);
ExpressionParser
expParser
(
parser
,
line
);
m_var
=
data
.
left
(
i
);
m_listExpr
=
expParser
.
parseVariable
(
data
.
mid
(
i
+
4
,
w
-
i
-
4
));
m_patternExpr
=
expParser
.
parseVariable
(
data
.
right
(
data
.
length
()
-
w
-
6
));
...
...
@@ -2796,11 +2825,11 @@ class TemplateNodeMarkers : public TemplateNodeCreator<TemplateNodeMarkers>
}
else
if
(
!
ok
)
{
warn
(
m_templateName
,
m_line
,
"markers pattern string has invalid markers '%s'"
,
str
.
data
());
ci
->
warn
(
m_templateName
,
m_line
,
"markers pattern string has invalid markers '%s'"
,
str
.
data
());
}
else
if
(
i
<
entryIndex
)
{
warn
(
m_templateName
,
m_line
,
"markers list does not an element for marker position %d"
,
i
);
ci
->
warn
(
m_templateName
,
m_line
,
"markers list does not an element for marker position %d"
,
i
);
}
index
=
newIndex
+
matchLen
;
// set index just after marker
}
...
...
@@ -2809,12 +2838,12 @@ class TemplateNodeMarkers : public TemplateNodeCreator<TemplateNodeMarkers>
}
else
{
warn
(
m_templateName
,
m_line
,
"markers requires a parameter of string type after 'with'!"
);
ci
->
warn
(
m_templateName
,
m_line
,
"markers requires a parameter of string type after 'with'!"
);
}
}
else
{
warn
(
m_templateName
,
m_line
,
"markers requires a parameter of list type after 'in'!"
);
ci
->
warn
(
m_templateName
,
m_line
,
"markers requires a parameter of list type after 'in'!"
);
}
}
}
...
...
@@ -2970,19 +2999,20 @@ void TemplateBlockContext::push(TemplateNodeBlock *block)
class
TemplateLexer
{
public
:
TemplateLexer
(
const
QCString
&
fileName
,
const
QCString
&
data
);
TemplateLexer
(
const
TemplateEngine
*
engine
,
const
QCString
&
fileName
,
const
QCString
&
data
);
void
tokenize
(
QList
<
TemplateToken
>
&
tokens
);
private
:
void
addToken
(
QList
<
TemplateToken
>
&
tokens
,
const
char
*
data
,
int
line
,
int
startPos
,
int
endPos
,
TemplateToken
::
Type
type
);
void
reset
();
const
TemplateEngine
*
m_engine
;
QCString
m_fileName
;
QCString
m_data
;
};
TemplateLexer
::
TemplateLexer
(
const
QCString
&
fileName
,
const
QCString
&
data
)
:
m_fileName
(
fileName
),
m_data
(
data
)
TemplateLexer
::
TemplateLexer
(
const
TemplateEngine
*
engine
,
const
QCString
&
fileName
,
const
QCString
&
data
)
:
m_
engine
(
engine
),
m_
fileName
(
fileName
),
m_data
(
data
)
{
}
...
...
@@ -3049,6 +3079,7 @@ void TemplateLexer::tokenize(QList<TemplateToken> &tokens)
if
(
c
==
'\n'
)
{
warn
(
m_fileName
,
line
,
"unexpected new line inside {%%...%%} block"
);
m_engine
->
printIncludeContext
(
m_fileName
,
line
);
}
else
if
(
c
==
'%'
)
// %} or something else
{
...
...
@@ -3072,6 +3103,7 @@ void TemplateLexer::tokenize(QList<TemplateToken> &tokens)
if
(
c
==
'\n'
)
{
warn
(
m_fileName
,
line
,
"unexpected new line inside {%%...%%} block"
);
m_engine
->
printIncludeContext
(
m_fileName
,
line
);
}
state
=
StateTag
;
}
...
...
@@ -3080,6 +3112,7 @@ void TemplateLexer::tokenize(QList<TemplateToken> &tokens)
if
(
c
==
'\n'
)
{
warn
(
m_fileName
,
line
,
"unexpected new line inside {#...#} block"
);
m_engine
->
printIncludeContext
(
m_fileName
,
line
);
}
else
if
(
c
==
'#'
)
// #} or something else
{
...
...
@@ -3101,6 +3134,7 @@ void TemplateLexer::tokenize(QList<TemplateToken> &tokens)
if
(
c
==
'\n'
)
{
warn
(
m_fileName
,
line
,
"unexpected new line inside {#...#} block"
);
m_engine
->
printIncludeContext
(
m_fileName
,
line
);
}
state
=
StateComment
;
}
...
...
@@ -3125,6 +3159,7 @@ void TemplateLexer::tokenize(QList<TemplateToken> &tokens)
if
(
c
==
'\n'
)
{
warn
(
m_fileName
,
line
,
"unexpected new line inside {{...}} block"
);
m_engine
->
printIncludeContext
(
m_fileName
,
line
);
}
else
if
(
c
==
'}'
)
// }} or something else
{
...
...
@@ -3148,6 +3183,7 @@ void TemplateLexer::tokenize(QList<TemplateToken> &tokens)
if
(
c
==
'\n'
)
{
warn
(
m_fileName
,
line
,
"unexpected new line inside {{...}} block"
);
m_engine
->
printIncludeContext
(
m_fileName
,
line
);
}
state
=
StateVariable
;
}
...
...
@@ -3192,9 +3228,10 @@ void TemplateLexer::addToken(QList<TemplateToken> &tokens,
//----------------------------------------------------------
TemplateParser
::
TemplateParser
(
const
QCString
&
templateName
,
TemplateParser
::
TemplateParser
(
const
TemplateEngine
*
engine
,
const
QCString
&
templateName
,
QList
<
TemplateToken
>
&
tokens
)
:
m_templateName
(
templateName
),
m_tokens
(
tokens
)
m_
engine
(
engine
),
m_
templateName
(
templateName
),
m_tokens
(
tokens
)
{
}
...
...
@@ -3214,10 +3251,10 @@ void TemplateParser::parse(
case
TemplateToken
:
:
Text
:
nodes
.
append
(
new
TemplateNodeText
(
this
,
parent
,
tok
->
line
,
tok
->
data
));
break
;
case
TemplateToken
:
:
Variable
:
case
TemplateToken
:
:
Variable
:
// {{ var }}
nodes
.
append
(
new
TemplateNodeVariable
(
this
,
parent
,
tok
->
line
,
tok
->
data
));
break
;
case
TemplateToken
:
:
Block
:
case
TemplateToken
:
:
Block
:
// {% tag %}
{
QCString
command
=
tok
->
data
;
int
sep
=
command
.
find
(
' '
);
...
...
@@ -3301,6 +3338,15 @@ void TemplateParser::prependToken(const TemplateToken *token)
m_tokens
.
prepend
(
token
);
}
void
TemplateParser
::
warn
(
const
char
*
fileName
,
int
line
,
const
char
*
fmt
,...)
const
{
va_list
args
;
va_start
(
args
,
fmt
);
::
warn
(
fileName
,
line
,
fmt
,
args
);
va_end
(
args
);
m_engine
->
printIncludeContext
(
fileName
,
line
);
}
//----------------------------------------------------------
...
...
@@ -3311,11 +3357,11 @@ TemplateImpl::TemplateImpl(TemplateEngine *engine,const QCString &name,const QCS
{
m_name
=
name
;
m_engine
=
engine
;
TemplateLexer
lexer
(
name
,
data
);
TemplateLexer
lexer
(
engine
,
name
,
data
);
QList
<
TemplateToken
>
tokens
;
tokens
.
setAutoDelete
(
TRUE
);
lexer
.
tokenize
(
tokens
);
TemplateParser
parser
(
name
,
tokens
);
TemplateParser
parser
(
engine
,
name
,
tokens
);
parser
.
parse
(
this
,
1
,
QStrList
(),
m_nodes
);
}
...
...
@@ -3348,11 +3394,35 @@ void TemplateImpl::render(FTextStream &ts, TemplateContext *c)
/** @brief Private data of the template engine */
class
TemplateEngine
::
Private
{
class
IncludeEntry
{
public
:
enum
Type
{
Template
,
Block
};
IncludeEntry
(
Type
type
,
const
QCString
&
fileName
,
const
QCString
&
blockName
,
int
line
)
:
m_type
(
type
),
m_fileName
(
fileName
),
m_blockName
(
blockName
),
m_line
(
line
)
{}
Type
type
()
const
{
return
m_type
;
}
QCString
fileName
()
const
{
return
m_fileName
;
}
QCString
blockName
()
const
{
return
m_blockName
;
}
int
line
()
const
{
return
m_line
;
}
private
:
Type
m_type
;
QCString
m_fileName
;
QCString
m_blockName
;
int
m_line
;
};
public
:
Private
(
TemplateEngine
*
engine
)
:
m_templateCache
(
17
),
m_engine
(
engine
)
{
m_templateCache
.
setAutoDelete
(
TRUE
);
}
Template
*
loadByName
(
const
QCString
&
fileName
)
const
Private
(
TemplateEngine
*
engine
)
:
m_templateCache
(
17
)
/*, m_indent(0)*/
,
m_engine
(
engine
)
{
m_templateCache
.
setAutoDelete
(
TRUE
);
m_includeStack
.
setAutoDelete
(
TRUE
);
}
Template
*
loadByName
(
const
QCString
&
fileName
,
int
line
)
{
//for (int i=0;i<m_indent;i++) printf(" ");
//m_indent++;
//printf("loadByName(%s,%d) {\n",fileName.data(),line);
m_includeStack
.
append
(
new
IncludeEntry
(
IncludeEntry
::
Template
,
fileName
,
QCString
(),
line
));
Template
*
templ
=
m_templateCache
.
find
(
fileName
);
if
(
templ
==
0
)
{
...
...
@@ -3379,10 +3449,60 @@ class TemplateEngine::Private
}
return
templ
;
}
void
unload
(
Template
*
/*t*/
)
{
//(void)t;
//m_indent--;
//for (int i=0;i<m_indent;i++) printf(" ");
//printf("}\n");
m_includeStack
.
removeLast
();
}
void
enterBlock
(
const
QCString
&
fileName
,
const
QCString
&
blockName
,
int
line
)
{
//for (int i=0;i<m_indent;i++) printf(" ");
//m_indent++;
//printf("enterBlock(%s,%s,%d) {\n",fileName.data(),blockName.data(),line);
m_includeStack
.
append
(
new
IncludeEntry
(
IncludeEntry
::
Block
,
fileName
,
blockName
,
line
));
}
void
leaveBlock
()
{
//m_indent--;
//for (int i=0;i<m_indent;i++) printf(" ");
//printf("}\n");
m_includeStack
.
removeLast
();
}
void
printIncludeContext
(
const
char
*
fileName
,
int
line
)
const
{
QListIterator
<
IncludeEntry
>
li
(
m_includeStack
);
li
.
toLast
();
IncludeEntry
*
ie
=
li
.
current
();
while
((
ie
=
li
.
current
()))
{
--
li
;
IncludeEntry
*
next
=
li
.
current
();
if
(
ie
->
type
()
==
IncludeEntry
::
Template
)
{
if
(
next
)
{
warn
(
fileName
,
line
,
" inside template '%s' included from template '%s' at line %d"
,
ie
->
fileName
().
data
(),
next
->
fileName
().
data
(),
ie
->
line
());
}
}
else
// ie->type()==IncludeEntry::Block
{
warn
(
fileName
,
line
,
" included by block '%s' inside template '%s' at line %d"
,
ie
->
blockName
().
data
(),
ie
->
fileName
().
data
(),
ie
->
line
());
}
}
}
private
:
mutable
QDict
<
Template
>
m_templateCache
;
QDict
<
Template
>
m_templateCache
;
//mutable int m_indent;
TemplateEngine
*
m_engine
;
QList
<
IncludeEntry
>
m_includeStack
;
};
TemplateEngine
::
TemplateEngine
()
...
...
@@ -3397,11 +3517,31 @@ TemplateEngine::~TemplateEngine()
TemplateContext
*
TemplateEngine
::
createContext
()
const
{
return
new
TemplateContextImpl
;
return
new
TemplateContextImpl
(
this
);
}
Template
*
TemplateEngine
::
loadByName
(
const
QCString
&
fileName
,
int
line
)
{
return
p
->
loadByName
(
fileName
,
line
);
}
void
TemplateEngine
::
unload
(
Template
*
t
)
{
p
->
unload
(
t
);
}
void
TemplateEngine
::
enterBlock
(
const
QCString
&
fileName
,
const
QCString
&
blockName
,
int
line
)
{
p
->
enterBlock
(
fileName
,
blockName
,
line
);
}
void
TemplateEngine
::
leaveBlock
()
{
p
->
leaveBlock
();
}
Template
*
TemplateEngine
::
loadByName
(
const
QCString
&
fileName
)
void
TemplateEngine
::
printIncludeContext
(
const
char
*
fileName
,
int
line
)
const
{
return
p
->
loadByName
(
fileNam
e
);
p
->
printIncludeContext
(
fileName
,
lin
e
);
}
src/template.h
View file @
744d1ca5
...
...
@@ -10,32 +10,32 @@ class TemplateListIntf;
class
TemplateStructIntf
;
class
TemplateEngine
;
/** @defgroup template_api Template API
/** @defgroup template_api Template API
*
* This is the API for a
* <a href="https://docs.djangoproject.com/en/1.6/topics/templates/">Django</a>
* This is the API for a
* <a href="https://docs.djangoproject.com/en/1.6/topics/templates/">Django</a>
* compatible template system written in C++.
* It is somewhat inspired by Stephen Kelly's
* It is somewhat inspired by Stephen Kelly's
* <a href="http://www.gitorious.org/grantlee/pages/Home">Grantlee</a>.
*
* A template is simply a text file.
* A template contains \b variables, which get replaced with values when the
* A template is simply a text file.
* A template contains \b variables, which get replaced with values when the
* template is evaluated, and \b tags, which control the logic of the template.
*
* Variables look like this: `{{ variable }}`
* When the template engine encounters a variable, it evaluates that variable and
* replaces it with the result. Variable names consist of any combination of
* When the template engine encounters a variable, it evaluates that variable and
* replaces it with the result. Variable names consist of any combination of
* alphanumeric characters and the underscore ("_").
* Use a dot (.) to access attributes of a structured variable.
*
*
* One can modify variables for display by using \b filters, for example:
* `{{ value|default:"nothing" }}`
*
* Tags look like this: `{% tag %}`. Tags are more complex than variables:
* Some create text in the output, some control flow by performing loops or logic,
* Tags look like this: `{% tag %}`. Tags are more complex than variables:
* Some create text in the output, some control flow by performing loops or logic,
* and some load external information into the template to be used by later variables.
*
* To comment-out part of a line in a template, use the comment syntax:
* To comment-out part of a line in a template, use the comment syntax:
* `{# comment text #}`.
*
* Supported Django tags:
...
...
@@ -144,13 +144,13 @@ class TemplateVariant
/** Constructs a new variant with a string value \a s. */
TemplateVariant
(
const
QCString
&
s
,
bool
raw
=
FALSE
);
/** Constructs a new variant with a struct value \a s.
/** Constructs a new variant with a struct value \a s.
* @note. Only a pointer to the struct is stored. The caller
* is responsible to manage the memory for the struct object.
*/
TemplateVariant
(
const
TemplateStructIntf
*
s
);
/** Constructs a new variant with a list value \a l.
/** Constructs a new variant with a list value \a l.
* @note. Only a pointer to the struct is stored. The caller
* is responsible to manage the memory for the list object.
*/
...
...
@@ -168,7 +168,7 @@ class TemplateVariant
/** Destroys the Variant object */
~
TemplateVariant
();
/** Constructs a copy of the variant, \a v,
/** Constructs a copy of the variant, \a v,
* passed as the argument to this constructor.
*/
TemplateVariant
(
const
TemplateVariant
&
v
);
...
...
@@ -176,7 +176,7 @@ class TemplateVariant
/** Assigns the value of the variant \a v to this variant. */
TemplateVariant
&
operator
=
(
const
TemplateVariant
&
v
);
/** Compares this QVariant with v and returns true if they are equal;
/** Compares this QVariant with v and returns true if they are equal;
* otherwise returns false.
*/
bool
operator
==
(
TemplateVariant
&
other
);
...
...
@@ -190,13 +190,13 @@ class TemplateVariant
/** Returns the variant as an integer. */
int
toInt
()
const
;
/** Returns the pointer to list referenced by this variant
* or 0 if this variant does not have list type.
/** Returns the pointer to list referenced by this variant
* or 0 if this variant does not have list type.
*/
const
TemplateListIntf
*
toList
()
const
;
/** Returns the pointer to struct referenced by this variant
* or 0 if this variant does not have struct type.
/** Returns the pointer to struct referenced by this variant
* or 0 if this variant does not have struct type.
*/
const
TemplateStructIntf
*
toStruct
()
const
;
...
...
@@ -205,7 +205,7 @@ class TemplateVariant
*/
TemplateVariant
call
(
const
QValueList
<
TemplateVariant
>
&
args
);
/** Sets whether or not the value of the Variant should be
/** Sets whether or not the value of the Variant should be
* escaped or written as-is (raw).
* @param[in] b TRUE means write as-is, FALSE means apply escaping.
*/
...
...
@@ -223,7 +223,7 @@ class TemplateVariant
//------------------------------------------------------------------------
/** @brief Abstract read-only interface for a context value of type list.
/** @brief Abstract read-only interface for a context value of type list.
* @note The values of the list are TemplateVariants.
*/
class
TemplateListIntf
...
...
@@ -245,7 +245,7 @@ class TemplateListIntf
virtual
void
toPrev
()
=
0
;
/* Returns TRUE if the iterator points to a valid element
* in the list, or FALSE otherwise.
* If TRUE is returned, the value pointed to be the
* If TRUE is returned, the value pointed to be the
* iterator is assigned to \a v.
*/
virtual
bool
current
(
TemplateVariant
&
v
)
const
=
0
;
...
...
@@ -260,7 +260,7 @@ class TemplateListIntf
/** Returns the element at index position \a index. */
virtual
TemplateVariant
at
(
int
index
)
const
=
0
;
/** Creates a new iterator for this list.
/** Creates a new iterator for this list.
* @note the user should call delete on the returned pointer.
*/
virtual
TemplateListIntf
::
ConstIterator
*
createIterator
()
const
=
0
;
...
...
@@ -279,7 +279,7 @@ class TemplateList : public TemplateListIntf
virtual
int
count
()
const
;
virtual
TemplateVariant
at
(
int
index
)
const
;
virtual
TemplateListIntf
::
ConstIterator
*
createIterator
()
const
;
/** Appends element \a v to the end of the list */
virtual
void
append
(
const
TemplateVariant
&
v
);
...
...
@@ -350,8 +350,8 @@ class TemplateSpacelessIntf
//------------------------------------------------------------------------
/** @brief Abstract interface for a template context.
*
/** @brief Abstract interface for a template context.
*
* A Context consists of a stack of dictionaries.
* A dictionary consists of a mapping of string keys onto TemplateVariant values.
* A key is searched starting with the dictionary at the top of the stack
...
...
@@ -370,10 +370,10 @@ class TemplateContext
/** Pop the current scope from the stack. */
virtual
void
pop
()
=
0
;
/** Sets a value in the current scope.
/** Sets a value in the current scope.
* @param[in] name The name of the value; the key in the dictionary.
* @param[in] v The value associated with the key.
* @note When a given key is already present,
* @note When a given key is already present,
* its value will be replaced by \a v
*/
virtual
void
set
(
const
char
*
name
,
const
TemplateVariant
&
v
)
=
0
;
...
...
@@ -409,8 +409,8 @@ class TemplateContext
//------------------------------------------------------------------------
/** @brief Abstract interface for a template.
* @note Must be created
by
TemplateEngine
/** @brief Abstract interface for a template.
* @note Must be created
and is deleted by the
TemplateEngine
*/
class
Template
{
...
...
@@ -418,7 +418,7 @@ class Template
/** Destructor */
virtual
~
Template
()
{}
/** Renders a template instance to a stream.
/** Renders a template instance to a stream.
* @param[in] ts The text stream to write the results to.
* @param[in] c The context containing data that can be used
* when instantiating the template.
...
...
@@ -444,13 +444,25 @@ class TemplateEngine
TemplateContext
*
createContext
()
const
;
/** Creates a new template whole contents are in a file.
* @param[in] fileName The name of the file containing the
* @param[in] fileName The name of the file containing the
* template data
* @param[in] fromLine The line number of the statement that triggered the load
* @return the new template, the caller will be the owner.
*/
Template
*
loadByName
(
const
QCString
&
fileName
);
Template
*
loadByName
(
const
QCString
&
fileName
,
int
fromLine
);
/** Indicates that template \a t is no longer needed. The engine
* may decide to delete it.
*/
void
unload
(
Template
*
t
);
void
printIncludeContext
(
const
char
*
fileName
,
int
line
)
const
;
private
:
friend
class
TemplateNodeBlock
;
void
enterBlock
(
const
QCString
&
fileName
,
const
QCString
&
blockName
,
int
line
);
void
leaveBlock
();
class
Private
;
Private
*
p
;
};
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment