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
2bd3c0ef
Commit
2bd3c0ef
authored
Mar 23, 2014
by
Dimitri van Heesch
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'template'
parents
bfc2c287
12cd22f4
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
272 additions
and
16 deletions
+272
-16
template.cpp
src/template.cpp
+269
-13
template.h
src/template.h
+3
-3
No files found.
src/template.cpp
View file @
2bd3c0ef
...
...
@@ -305,12 +305,12 @@ int TemplateVariant::toInt() const
return
result
;
}
const
TemplateStructIntf
*
TemplateVariant
::
toStruct
()
const
TemplateStructIntf
*
TemplateVariant
::
toStruct
()
const
{
return
p
->
type
==
Struct
?
p
->
strukt
:
0
;
}
const
TemplateListIntf
*
TemplateVariant
::
toList
()
const
TemplateListIntf
*
TemplateVariant
::
toList
()
const
{
return
p
->
type
==
List
?
p
->
list
:
0
;
}
...
...
@@ -624,6 +624,14 @@ class TemplateBlockContext
QDict
<
QList
<
TemplateNodeBlock
>
>
m_blocks
;
};
/** @brief A container to store a key-value pair */
struct
TemplateKeyValue
{
TemplateKeyValue
()
{}
TemplateKeyValue
(
const
QCString
&
k
,
const
TemplateVariant
&
v
)
:
key
(
k
),
value
(
v
)
{}
QCString
key
;
TemplateVariant
value
;
};
/** @brief Internal class representing the implementation of a template
* context */
...
...
@@ -650,25 +658,28 @@ class TemplateContextImpl : public TemplateContext
{
TemplateEscapeIntf
**
ppIntf
=
m_escapeIntfDict
.
find
(
ext
);
m_activeEscapeIntf
=
ppIntf
?
*
ppIntf
:
0
;
}
void
setActiveEscapeIntf
(
TemplateEscapeIntf
*
intf
)
{
m_activeEscapeIntf
=
intf
;
}
void
setSpacelessIntf
(
TemplateSpacelessIntf
*
intf
)
{
m_spacelessIntf
=
intf
;
}
void
setActiveEscapeIntf
(
TemplateEscapeIntf
*
intf
)
{
m_activeEscapeIntf
=
intf
;
}
void
setSpacelessIntf
(
TemplateSpacelessIntf
*
intf
)
{
m_spacelessIntf
=
intf
;
}
// internal methods
TemplateBlockContext
*
blockContext
();
TemplateVariant
getPrimary
(
const
QCString
&
name
)
const
;
void
setLocation
(
const
QCString
&
templateName
,
int
line
)
{
m_templateName
=
templateName
;
m_line
=
line
;
}
QCString
templateName
()
const
{
return
m_templateName
;
}
int
line
()
const
{
return
m_line
;
}
QCString
outputDirectory
()
const
{
return
m_outputDir
;
}
TemplateEscapeIntf
*
escapeIntf
()
const
{
return
m_activeEscapeIntf
;
}
QCString
templateName
()
const
{
return
m_templateName
;
}
int
line
()
const
{
return
m_line
;
}
QCString
outputDirectory
()
const
{
return
m_outputDir
;
}
TemplateEscapeIntf
*
escapeIntf
()
const
{
return
m_activeEscapeIntf
;
}
TemplateSpacelessIntf
*
spacelessIntf
()
const
{
return
m_spacelessIntf
;
}
void
enableSpaceless
(
bool
b
)
{
m_spacelessEnabled
=
b
;
}
bool
spacelessEnabled
()
const
{
return
m_spacelessEnabled
&&
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
;
// index related functions
void
openSubIndex
(
const
QCString
&
indexName
);
void
closeSubIndex
(
const
QCString
&
indexName
);
void
addIndexEntry
(
const
QCString
&
indexName
,
const
QValueList
<
TemplateKeyValue
>
&
arguments
);
private
:
const
TemplateEngine
*
m_engine
;
QCString
m_templateName
;
...
...
@@ -680,6 +691,8 @@ class TemplateContextImpl : public TemplateContext
TemplateEscapeIntf
*
m_activeEscapeIntf
;
TemplateSpacelessIntf
*
m_spacelessIntf
;
bool
m_spacelessEnabled
;
TemplateAutoRef
<
TemplateStruct
>
m_indices
;
QDict
<
QStack
<
TemplateVariant
>
>
m_indexStacks
;
};
//-----------------------------------------------------------------------------
...
...
@@ -1831,11 +1844,13 @@ class TemplateImpl : public TemplateNode, public Template
TemplateContextImpl
::
TemplateContextImpl
(
const
TemplateEngine
*
e
)
:
m_engine
(
e
),
m_templateName
(
"<unknown>"
),
m_line
(
1
),
m_activeEscapeIntf
(
0
),
m_spacelessIntf
(
0
),
m_spacelessEnabled
(
FALSE
)
m_spacelessIntf
(
0
),
m_spacelessEnabled
(
FALSE
)
,
m_indices
(
TemplateStruct
::
alloc
())
{
m_indexStacks
.
setAutoDelete
(
TRUE
);
m_contextStack
.
setAutoDelete
(
TRUE
);
m_escapeIntfDict
.
setAutoDelete
(
TRUE
);
push
();
set
(
"index"
,
m_indices
.
get
());
}
TemplateContextImpl
::~
TemplateContextImpl
()
...
...
@@ -1969,6 +1984,102 @@ void TemplateContextImpl::warn(const char *fileName,int line,const char *fmt,...
m_engine
->
printIncludeContext
(
fileName
,
line
);
}
void
TemplateContextImpl
::
openSubIndex
(
const
QCString
&
indexName
)
{
//printf("TemplateContextImpl::openSubIndex(%s)\n",indexName.data());
QStack
<
TemplateVariant
>
*
stack
=
m_indexStacks
.
find
(
indexName
);
if
(
!
stack
||
stack
->
isEmpty
()
||
stack
->
top
()
->
type
()
==
TemplateVariant
::
List
)
// error: no stack yet or no entry
{
warn
(
m_templateName
,
m_line
,
"opensubindex for index %s without preceding indexentry"
,
indexName
.
data
());
return
;
}
// get the parent entry to add the list to
TemplateStruct
*
entry
=
dynamic_cast
<
TemplateStruct
*>
(
stack
->
top
()
->
toStruct
());
if
(
entry
)
{
// add new list to the stack
TemplateList
*
list
=
TemplateList
::
alloc
();
stack
->
push
(
new
TemplateVariant
(
list
));
entry
->
set
(
"children"
,
list
);
entry
->
set
(
"is_leaf_node"
,
false
);
}
}
void
TemplateContextImpl
::
closeSubIndex
(
const
QCString
&
indexName
)
{
//printf("TemplateContextImpl::closeSubIndex(%s)\n",indexName.data());
QStack
<
TemplateVariant
>
*
stack
=
m_indexStacks
.
find
(
indexName
);
if
(
!
stack
||
stack
->
count
()
<
3
)
{
warn
(
m_templateName
,
m_line
,
"closesubindex for index %s without matching open"
,
indexName
.
data
());
}
else
// stack->count()>=2
{
if
(
stack
->
top
()
->
type
()
==
TemplateVariant
::
Struct
)
{
delete
stack
->
pop
();
// pop struct
delete
stack
->
pop
();
// pop list
}
else
// empty list! correct "is_left_node" attribute of the parent entry
{
delete
stack
->
pop
();
// pop list
TemplateStruct
*
entry
=
dynamic_cast
<
TemplateStruct
*>
(
stack
->
top
()
->
toStruct
());
if
(
entry
)
{
entry
->
set
(
"is_leaf_node"
,
true
);
}
}
}
}
void
TemplateContextImpl
::
addIndexEntry
(
const
QCString
&
indexName
,
const
QValueList
<
TemplateKeyValue
>
&
arguments
)
{
QValueListConstIterator
<
TemplateKeyValue
>
it
=
arguments
.
begin
();
//printf("TemplateContextImpl::addIndexEntry(%s)\n",indexName.data());
//while (it!=arguments.end())
//{
// printf(" key=%s value=%s\n",(*it).key.data(),(*it).value.toString().data());
// ++it;
//}
QStack
<
TemplateVariant
>
*
stack
=
m_indexStacks
.
find
(
indexName
);
if
(
!
stack
)
// no stack yet, create it!
{
stack
=
new
QStack
<
TemplateVariant
>
;
stack
->
setAutoDelete
(
TRUE
);
m_indexStacks
.
insert
(
indexName
,
stack
);
}
TemplateList
*
list
=
0
;
if
(
stack
->
isEmpty
())
// first item, create empty list and add it to the index
{
list
=
TemplateList
::
alloc
();
stack
->
push
(
new
TemplateVariant
(
list
));
m_indices
->
set
(
indexName
,
list
);
// make list available under index
}
else
// stack not empty
{
if
(
stack
->
top
()
->
type
()
==
TemplateVariant
::
Struct
)
// already an entry in the list
{
// remove current entry from the stack
delete
stack
->
pop
();
}
else
// first entry after opensubindex
{
ASSERT
(
stack
->
top
()
->
type
()
==
TemplateVariant
::
List
);
}
// get list to add new item
list
=
dynamic_cast
<
TemplateList
*>
(
stack
->
top
()
->
toList
());
}
TemplateStruct
*
entry
=
TemplateStruct
::
alloc
();
// add user specified fields to the entry
for
(
it
=
arguments
.
begin
();
it
!=
arguments
.
end
();
++
it
)
{
entry
->
set
((
*
it
).
key
,(
*
it
).
value
);
}
entry
->
set
(
"is_leaf_node"
,
true
);
stack
->
push
(
new
TemplateVariant
(
entry
));
list
->
append
(
entry
);
}
//----------------------------------------------------------
/** @brief Class representing a piece of plain text in a template */
...
...
@@ -3020,6 +3131,148 @@ class TemplateNodeTree : public TemplateNodeCreator<TemplateNodeTree>
TemplateNodeList
m_treeNodes
;
};
//----------------------------------------------------------
/** @brief Class representing an 'indexentry' tag in a template */
class
TemplateNodeIndexEntry
:
public
TemplateNodeCreator
<
TemplateNodeIndexEntry
>
{
struct
Mapping
{
Mapping
(
const
QCString
&
n
,
ExprAst
*
e
)
:
name
(
n
),
value
(
e
)
{}
~
Mapping
()
{
delete
value
;
}
QCString
name
;
ExprAst
*
value
;
};
public
:
TemplateNodeIndexEntry
(
TemplateParser
*
parser
,
TemplateNode
*
parent
,
int
line
,
const
QCString
&
data
)
:
TemplateNodeCreator
<
TemplateNodeIndexEntry
>
(
parser
,
parent
,
line
)
{
TRACE
((
"{TemplateNodeIndexEntry(%s)
\n
"
,
data
.
data
()));
m_args
.
setAutoDelete
(
TRUE
);
ExpressionParser
expParser
(
parser
,
line
);
QValueList
<
QCString
>
args
=
split
(
data
,
" "
);
QValueListIterator
<
QCString
>
it
=
args
.
begin
();
if
(
it
==
args
.
end
()
||
(
*
it
).
find
(
'='
)
!=-
1
)
{
parser
->
warn
(
parser
->
templateName
(),
line
,
"Missing name for indexentry tag"
);
}
else
{
m_name
=
*
it
;
++
it
;
while
(
it
!=
args
.
end
())
{
QCString
arg
=
*
it
;
int
j
=
arg
.
find
(
'='
);
if
(
j
>
0
)
{
ExprAst
*
expr
=
expParser
.
parse
(
arg
.
mid
(
j
+
1
));
if
(
expr
)
{
m_args
.
append
(
new
Mapping
(
arg
.
left
(
j
),
expr
));
}
}
else
{
parser
->
warn
(
parser
->
templateName
(),
line
,
"invalid argument '%s' for indexentry tag"
,
arg
.
data
());
}
++
it
;
}
}
TRACE
((
"}TemplateNodeIndexEntry(%s)
\n
"
,
data
.
data
()));
}
void
render
(
FTextStream
&
,
TemplateContext
*
c
)
{
if
(
!
m_name
.
isEmpty
())
{
TemplateContextImpl
*
ci
=
dynamic_cast
<
TemplateContextImpl
*>
(
c
);
ci
->
setLocation
(
m_templateName
,
m_line
);
QListIterator
<
Mapping
>
it
(
m_args
);
Mapping
*
mapping
;
QValueList
<
TemplateKeyValue
>
list
;
for
(
it
.
toFirst
();(
mapping
=
it
.
current
());
++
it
)
{
list
.
append
(
TemplateKeyValue
(
mapping
->
name
,
mapping
->
value
->
resolve
(
c
)));
}
ci
->
addIndexEntry
(
m_name
,
list
);
}
}
private
:
QCString
m_name
;
QList
<
Mapping
>
m_args
;
};
//----------------------------------------------------------
/** @brief Class representing an 'opensubindex' tag in a template */
class
TemplateNodeOpenSubIndex
:
public
TemplateNodeCreator
<
TemplateNodeOpenSubIndex
>
{
public
:
TemplateNodeOpenSubIndex
(
TemplateParser
*
parser
,
TemplateNode
*
parent
,
int
line
,
const
QCString
&
data
)
:
TemplateNodeCreator
<
TemplateNodeOpenSubIndex
>
(
parser
,
parent
,
line
)
{
TRACE
((
"{TemplateNodeOpenSubIndex(%s)
\n
"
,
data
.
data
()));
m_name
=
data
.
stripWhiteSpace
();
if
(
m_name
.
isEmpty
())
{
parser
->
warn
(
parser
->
templateName
(),
line
,
"Missing argument for opensubindex tag"
);
}
else
if
(
m_name
.
find
(
' '
)
!=-
1
)
{
parser
->
warn
(
parser
->
templateName
(),
line
,
"Expected single argument for opensubindex tag got '%s'"
,
data
.
data
());
m_name
=
""
;
}
TRACE
((
"}TemplateNodeOpenSubIndex(%s)
\n
"
,
data
.
data
()));
}
void
render
(
FTextStream
&
,
TemplateContext
*
c
)
{
if
(
!
m_name
.
isEmpty
())
{
TemplateContextImpl
*
ci
=
dynamic_cast
<
TemplateContextImpl
*>
(
c
);
ci
->
setLocation
(
m_templateName
,
m_line
);
ci
->
openSubIndex
(
m_name
);
}
}
private
:
QCString
m_name
;
};
//----------------------------------------------------------
/** @brief Class representing an 'closesubindex' tag in a template */
class
TemplateNodeCloseSubIndex
:
public
TemplateNodeCreator
<
TemplateNodeCloseSubIndex
>
{
public
:
TemplateNodeCloseSubIndex
(
TemplateParser
*
parser
,
TemplateNode
*
parent
,
int
line
,
const
QCString
&
data
)
:
TemplateNodeCreator
<
TemplateNodeCloseSubIndex
>
(
parser
,
parent
,
line
)
{
TRACE
((
"{TemplateNodeCloseSubIndex(%s)
\n
"
,
data
.
data
()));
m_name
=
data
.
stripWhiteSpace
();
if
(
m_name
.
isEmpty
())
{
parser
->
warn
(
parser
->
templateName
(),
line
,
"Missing argument for closesubindex tag"
);
}
else
if
(
m_name
.
find
(
' '
)
!=-
1
||
m_name
.
isEmpty
())
{
parser
->
warn
(
parser
->
templateName
(),
line
,
"Expected single argument for closesubindex tag got '%s'"
,
data
.
data
());
m_name
=
""
;
}
TRACE
((
"}TemplateNodeCloseSubIndex(%s)
\n
"
,
data
.
data
()));
}
void
render
(
FTextStream
&
,
TemplateContext
*
c
)
{
if
(
!
m_name
.
isEmpty
())
{
TemplateContextImpl
*
ci
=
dynamic_cast
<
TemplateContextImpl
*>
(
c
);
ci
->
setLocation
(
m_templateName
,
m_line
);
ci
->
closeSubIndex
(
m_name
);
}
}
private
:
QCString
m_name
;
};
//----------------------------------------------------------
/** @brief Class representing an 'with' tag in a template */
...
...
@@ -3395,6 +3648,9 @@ static TemplateNodeFactory::AutoRegister<TemplateNodeRepeat> autoRefRepeat("r
static
TemplateNodeFactory
::
AutoRegister
<
TemplateNodeInclude
>
autoRefInclude
(
"include"
);
static
TemplateNodeFactory
::
AutoRegister
<
TemplateNodeMarkers
>
autoRefMarkers
(
"markers"
);
static
TemplateNodeFactory
::
AutoRegister
<
TemplateNodeSpaceless
>
autoRefSpaceless
(
"spaceless"
);
static
TemplateNodeFactory
::
AutoRegister
<
TemplateNodeIndexEntry
>
autoRefIndexEntry
(
"indexentry"
);
static
TemplateNodeFactory
::
AutoRegister
<
TemplateNodeOpenSubIndex
>
autoRefOpenSubIndex
(
"opensubindex"
);
static
TemplateNodeFactory
::
AutoRegister
<
TemplateNodeCloseSubIndex
>
autoRefCloseSubIndex
(
"closesubindex"
);
//----------------------------------------------------------
...
...
src/template.h
View file @
2bd3c0ef
...
...
@@ -191,12 +191,12 @@ class TemplateVariant
/** Returns the pointer to list referenced by this variant
* or 0 if this variant does not have list type.
*/
const
TemplateListIntf
*
toList
()
const
;
TemplateListIntf
*
toList
()
const
;
/** Returns the pointer to struct referenced by this variant
* or 0 if this variant does not have struct type.
*/
const
TemplateStructIntf
*
toStruct
()
const
;
TemplateStructIntf
*
toStruct
()
const
;
/** Return the result of apply this function with \a args.
* Returns an empty string if the variant type is not a function.
...
...
@@ -399,7 +399,7 @@ class TemplateSpacelessIntf
* A key is searched starting with the dictionary at the top of the stack
* and searching downwards until it is found. The stack is used to create
* local scopes.
* @note This object must be created by TemplateEngine
* @note This object must be created by TemplateEngine
::createContext()
*/
class
TemplateContext
{
...
...
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