Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
O
ogs
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Requirements
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Locked files
Build
Pipelines
Jobs
Pipeline schedules
Test cases
Artifacts
Deploy
Releases
Package registry
Container Registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Service Desk
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Code review analytics
Issue analytics
Insights
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Dmitri Naumov
ogs
Commits
244fa211
Commit
244fa211
authored
9 years ago
by
Christoph Lehmann
Browse files
Options
Downloads
Patches
Plain Diff
[BL] config tree: more complete support for XML attributes
parent
de1d1463
No related branches found
No related tags found
No related merge requests found
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
BaseLib/ConfigTreeNew-impl.h
+14
-5
14 additions, 5 deletions
BaseLib/ConfigTreeNew-impl.h
BaseLib/ConfigTreeNew.cpp
+53
-12
53 additions, 12 deletions
BaseLib/ConfigTreeNew.cpp
BaseLib/ConfigTreeNew.h
+63
-12
63 additions, 12 deletions
BaseLib/ConfigTreeNew.h
with
130 additions
and
29 deletions
BaseLib/ConfigTreeNew-impl.h
+
14
−
5
View file @
244fa211
...
@@ -142,6 +142,17 @@ template<typename T>
...
@@ -142,6 +142,17 @@ template<typename T>
T
T
ConfigTreeNew
::
ConfigTreeNew
::
getConfAttribute
(
std
::
string
const
&
attr
)
const
getConfAttribute
(
std
::
string
const
&
attr
)
const
{
if
(
auto
a
=
getConfAttributeOptional
<
T
>
(
attr
))
return
*
a
;
error
(
"Did not find XML attribute with name
\"
"
+
attr
+
"
\"
."
);
}
template
<
typename
T
>
boost
::
optional
<
T
>
ConfigTreeNew
::
getConfAttributeOptional
(
std
::
string
const
&
attr
)
const
{
{
checkUniqueAttr
(
attr
);
checkUniqueAttr
(
attr
);
auto
&
ct
=
markVisited
<
T
>
(
attr
,
true
,
true
);
auto
&
ct
=
markVisited
<
T
>
(
attr
,
true
,
true
);
...
@@ -150,18 +161,16 @@ getConfAttribute(std::string const& attr) const
...
@@ -150,18 +161,16 @@ getConfAttribute(std::string const& attr) const
if
(
auto
a
=
attrs
->
get_child_optional
(
attr
))
{
if
(
auto
a
=
attrs
->
get_child_optional
(
attr
))
{
++
ct
.
count
;
// count only if attribute has been found
++
ct
.
count
;
// count only if attribute has been found
if
(
auto
v
=
a
->
get_value_optional
<
T
>
())
{
if
(
auto
v
=
a
->
get_value_optional
<
T
>
())
{
return
*
v
;
return
v
;
}
else
{
}
else
{
error
(
"Value for XML attribute
\"
"
+
attr
+
"
\"
`"
error
(
"Value for XML attribute
\"
"
+
attr
+
"
\"
`"
+
shortString
(
a
->
data
())
+
shortString
(
a
->
data
())
+
"' not convertible to the desired type."
);
+
"' not convertible to the desired type."
);
}
}
}
else
{
error
(
"Did not find XML attribute with name
\"
"
+
attr
+
"
\"
"
);
}
}
}
else
{
error
(
"This parameter has no XML attributes"
);
}
}
return
boost
::
none
;
}
}
template
<
typename
T
>
template
<
typename
T
>
...
...
This diff is collapsed.
Click to expand it.
BaseLib/ConfigTreeNew.cpp
+
53
−
12
View file @
244fa211
...
@@ -84,7 +84,7 @@ ConfigTreeNew::
...
@@ -84,7 +84,7 @@ ConfigTreeNew::
getConfParam
(
std
::
string
const
&
root
)
const
getConfParam
(
std
::
string
const
&
root
)
const
{
{
auto
ct
=
getConfSubtree
(
root
);
auto
ct
=
getConfSubtree
(
root
);
if
(
hasChildren
(
ct
))
if
(
ct
.
hasChildren
())
error
(
"Requested parameter <"
+
root
+
"> actually is a subtree."
);
error
(
"Requested parameter <"
+
root
+
"> actually is a subtree."
);
return
ct
;
return
ct
;
}
}
...
@@ -94,11 +94,25 @@ ConfigTreeNew::
...
@@ -94,11 +94,25 @@ ConfigTreeNew::
getConfParamOptional
(
std
::
string
const
&
root
)
const
getConfParamOptional
(
std
::
string
const
&
root
)
const
{
{
auto
ct
=
getConfSubtreeOptional
(
root
);
auto
ct
=
getConfSubtreeOptional
(
root
);
if
(
ct
&&
hasChildren
(
*
ct
))
if
(
ct
&&
ct
->
hasChildren
())
error
(
"Requested parameter <"
+
root
+
"> actually is a subtree."
);
error
(
"Requested parameter <"
+
root
+
"> actually is a subtree."
);
return
ct
;
return
ct
;
}
}
Range
<
ConfigTreeNew
::
ParameterIterator
>
ConfigTreeNew
::
getConfParamList
(
const
std
::
string
&
param
)
const
{
checkUnique
(
param
);
markVisited
(
param
,
false
,
true
);
auto
p
=
_tree
->
equal_range
(
param
);
return
Range
<
ParameterIterator
>
(
ParameterIterator
(
p
.
first
,
param
,
*
this
),
ParameterIterator
(
p
.
second
,
param
,
*
this
));
}
ConfigTreeNew
ConfigTreeNew
ConfigTreeNew
::
ConfigTreeNew
::
getConfSubtree
(
std
::
string
const
&
root
)
const
getConfSubtree
(
std
::
string
const
&
root
)
const
...
@@ -117,10 +131,10 @@ getConfSubtreeOptional(std::string const& root) const
...
@@ -117,10 +131,10 @@ getConfSubtreeOptional(std::string const& root) const
checkUnique
(
root
);
checkUnique
(
root
);
if
(
auto
subtree
=
_tree
->
get_child_optional
(
root
))
{
if
(
auto
subtree
=
_tree
->
get_child_optional
(
root
))
{
markVisited
(
root
,
false
);
markVisited
(
root
,
false
,
false
);
return
ConfigTreeNew
(
*
subtree
,
*
this
,
root
);
return
ConfigTreeNew
(
*
subtree
,
*
this
,
root
);
}
else
{
}
else
{
markVisited
(
root
,
true
);
markVisited
(
root
,
false
,
true
);
return
boost
::
none
;
return
boost
::
none
;
}
}
}
}
...
@@ -130,7 +144,7 @@ ConfigTreeNew::
...
@@ -130,7 +144,7 @@ ConfigTreeNew::
getConfSubtreeList
(
std
::
string
const
&
root
)
const
getConfSubtreeList
(
std
::
string
const
&
root
)
const
{
{
checkUnique
(
root
);
checkUnique
(
root
);
markVisited
(
root
,
true
);
markVisited
(
root
,
false
,
true
);
auto
p
=
_tree
->
equal_range
(
root
);
auto
p
=
_tree
->
equal_range
(
root
);
...
@@ -144,13 +158,24 @@ void ConfigTreeNew::ignoreConfParam(const std::string ¶m) const
...
@@ -144,13 +158,24 @@ void ConfigTreeNew::ignoreConfParam(const std::string ¶m) const
checkUnique
(
param
);
checkUnique
(
param
);
// if not found, peek only
// if not found, peek only
bool
peek_only
=
_tree
->
find
(
param
)
==
_tree
->
not_found
();
bool
peek_only
=
_tree
->
find
(
param
)
==
_tree
->
not_found
();
markVisited
(
param
,
peek_only
);
markVisited
(
param
,
false
,
peek_only
);
}
void
ConfigTreeNew
::
ignoreConfAttribute
(
const
std
::
string
&
attr
)
const
{
checkUniqueAttr
(
attr
);
// Exercise: Guess what not! (hint: if not found, peek only)
// Btw. (not a hint) _tree->find() does not seem to work here.
bool
peek_only
=
!
_tree
->
get_child_optional
(
"<xmlattr>."
+
attr
);
markVisited
(
attr
,
true
,
peek_only
);
}
}
void
ConfigTreeNew
::
ignoreConfParamAll
(
const
std
::
string
&
param
)
const
void
ConfigTreeNew
::
ignoreConfParamAll
(
const
std
::
string
&
param
)
const
{
{
checkUnique
(
param
);
checkUnique
(
param
);
auto
&
ct
=
markVisited
(
param
,
true
);
auto
&
ct
=
markVisited
(
param
,
false
,
true
);
auto
p
=
_tree
->
equal_range
(
param
);
auto
p
=
_tree
->
equal_range
(
param
);
for
(
auto
it
=
p
.
first
;
it
!=
p
.
second
;
++
it
)
{
for
(
auto
it
=
p
.
first
;
it
!=
p
.
second
;
++
it
)
{
...
@@ -236,7 +261,23 @@ void ConfigTreeNew::checkUnique(const std::string &key) const
...
@@ -236,7 +261,23 @@ void ConfigTreeNew::checkUnique(const std::string &key) const
void
ConfigTreeNew
::
checkUniqueAttr
(
const
std
::
string
&
attr
)
const
void
ConfigTreeNew
::
checkUniqueAttr
(
const
std
::
string
&
attr
)
const
{
{
checkKeyname
(
attr
);
// Workaround for handling attributes with xml namespaces and uppercase letters.
if
(
attr
.
find
(
':'
)
!=
attr
.
npos
)
{
auto
pos
=
decltype
(
attr
.
npos
){
0
};
// Replace colon and uppercase letters with an allowed character 'a'.
// That means, attributes containing a colon are also allowed to contain
// uppercase letters.
auto
attr2
=
attr
;
do
{
pos
=
attr2
.
find_first_of
(
":ABCDEFGHIJKLMNOPQRSTUVWXYZ"
,
pos
);
if
(
pos
!=
attr
.
npos
)
attr2
[
pos
]
=
'a'
;
}
while
(
pos
!=
attr
.
npos
);
checkKeyname
(
attr2
);
}
else
{
checkKeyname
(
attr
);
}
if
(
_visited_params
.
find
({
true
,
attr
})
!=
_visited_params
.
end
())
{
if
(
_visited_params
.
find
({
true
,
attr
})
!=
_visited_params
.
end
())
{
error
(
"Attribute
\"
"
+
attr
+
"
\"
has already been processed."
);
error
(
"Attribute
\"
"
+
attr
+
"
\"
has already been processed."
);
...
@@ -245,9 +286,9 @@ void ConfigTreeNew::checkUniqueAttr(const std::string &attr) const
...
@@ -245,9 +286,9 @@ void ConfigTreeNew::checkUniqueAttr(const std::string &attr) const
ConfigTreeNew
::
CountType
&
ConfigTreeNew
::
CountType
&
ConfigTreeNew
::
ConfigTreeNew
::
markVisited
(
std
::
string
const
&
key
,
bool
const
peek_only
)
const
markVisited
(
std
::
string
const
&
key
,
bool
const
is_attr
,
bool
const
peek_only
)
const
{
{
return
markVisited
<
ConfigTreeNew
>
(
key
,
false
,
peek_only
);
return
markVisited
<
ConfigTreeNew
>
(
key
,
is_attr
,
peek_only
);
}
}
void
void
...
@@ -266,9 +307,9 @@ markVisitedDecrement(bool const is_attr, std::string const& key) const
...
@@ -266,9 +307,9 @@ markVisitedDecrement(bool const is_attr, std::string const& key) const
}
}
bool
bool
ConfigTreeNew
::
hasChildren
(
ConfigTreeNew
const
&
ct
)
const
ConfigTreeNew
::
hasChildren
()
const
{
{
auto
const
&
tree
=
*
ct
.
_tree
;
auto
const
&
tree
=
*
_tree
;
if
(
tree
.
begin
()
==
tree
.
end
())
if
(
tree
.
begin
()
==
tree
.
end
())
return
false
;
// no children
return
false
;
// no children
if
(
tree
.
front
().
first
==
"<xmlattr>"
if
(
tree
.
front
().
first
==
"<xmlattr>"
...
...
This diff is collapsed.
Click to expand it.
BaseLib/ConfigTreeNew.h
+
63
−
12
View file @
244fa211
...
@@ -89,8 +89,7 @@ template<typename Iterator> class Range;
...
@@ -89,8 +89,7 @@ template<typename Iterator> class Range;
class
ConfigTreeNew
final
class
ConfigTreeNew
final
{
{
public:
public:
/*!
/*! A wrapper around a Boost Iterator for iterating over ranges of subtrees.
* A wrapper around a Boost Iterator for iterating over ranges of subtrees.
*
*
* The methods of this class tell the associated (parent) \c ConfigTree object when
* The methods of this class tell the associated (parent) \c ConfigTree object when
* a setting has been parsed.
* a setting has been parsed.
...
@@ -117,7 +116,7 @@ public:
...
@@ -117,7 +116,7 @@ public:
// tell the _parent instance that a subtree now has been parsed.
// tell the _parent instance that a subtree now has been parsed.
if
(
_has_incremented
)
{
if
(
_has_incremented
)
{
_has_incremented
=
false
;
_has_incremented
=
false
;
_parent
.
markVisited
(
_tagname
,
false
);
_parent
.
markVisited
(
_tagname
,
false
,
false
);
}
}
return
ConfigTreeNew
(
_it
->
second
,
_parent
,
_tagname
);
return
ConfigTreeNew
(
_it
->
second
,
_parent
,
_tagname
);
}
}
...
@@ -133,10 +132,32 @@ public:
...
@@ -133,10 +132,32 @@ public:
private
:
private
:
bool
_has_incremented
=
true
;
bool
_has_incremented
=
true
;
Iterator
_it
;
Iterator
_it
;
protected
:
std
::
string
const
_tagname
;
std
::
string
const
_tagname
;
ConfigTreeNew
const
&
_parent
;
ConfigTreeNew
const
&
_parent
;
};
};
/*! A wrapper around a Boost Iterator for iterating over ranges of parameters.
*
* The methods of this class tell the associated (parent) \c ConfigTree object when
* a setting has been parsed.
*/
class
ParameterIterator
:
public
SubtreeIterator
{
public:
// Inherit the constructor
using
SubtreeIterator
::
SubtreeIterator
;
ConfigTreeNew
operator
*
()
{
auto
st
=
SubtreeIterator
::
operator
*
();
if
(
st
.
hasChildren
())
_parent
.
error
(
"The requested parameter <"
+
_tagname
+
">"
" has child elements."
);
return
st
;
}
};
/*!
/*!
* A wrapper around a Boost Iterator for iterating over ranges of values.
* A wrapper around a Boost Iterator for iterating over ranges of values.
...
@@ -265,7 +286,7 @@ public:
...
@@ -265,7 +286,7 @@ public:
template
<
typename
T
>
boost
::
optional
<
T
>
template
<
typename
T
>
boost
::
optional
<
T
>
getConfParamOptional
(
std
::
string
const
&
param
)
const
;
getConfParamOptional
(
std
::
string
const
&
param
)
const
;
/*!
R
et
urn
s all parameters with
the
name \c param from the current level of the tree.
/*!
F
et
che
s all parameters with name \c param from the current level of the tree.
*
*
* The return value is suitable to be used with range-base for-loops.
* The return value is suitable to be used with range-base for-loops.
*
*
...
@@ -282,9 +303,8 @@ public:
...
@@ -282,9 +303,8 @@ public:
* parameters---check that the queried parameters do not have any children (apart from XML
* parameters---check that the queried parameters do not have any children (apart from XML
* attributes); if they do, error() is called.
* attributes); if they do, error() is called.
*
*
* The support for parameters with attributes is limited in the sense that there are no
* The support for parameters with attributes is limited in the sense that it is not
* <tt>get...List()</tt> methods in this group and that it is not possible to explicitly
* possible to peek/check them. However, such functionality can easily be added on demand.
* ignore attibutes. However, such functionality can easily be added on demand.
*/
*/
//!\{
//!\{
...
@@ -306,6 +326,17 @@ public:
...
@@ -306,6 +326,17 @@ public:
boost
::
optional
<
ConfigTreeNew
>
boost
::
optional
<
ConfigTreeNew
>
getConfParamOptional
(
std
::
string
const
&
param
)
const
;
getConfParamOptional
(
std
::
string
const
&
param
)
const
;
/*! Fetches all parameters with name \c param from the current level of the tree.
*
* The return value is suitable to be used with range-base for-loops.
*
* \pre \c param must not have been read before from this ConfigTree.
*
* \todo write tests
*/
Range
<
ParameterIterator
>
getConfParamList
(
std
::
string
const
&
param
)
const
;
/*! Get the plain data contained in the current level of the tree.
/*! Get the plain data contained in the current level of the tree.
*
*
* \return the data converted to the type \c T
* \return the data converted to the type \c T
...
@@ -324,6 +355,17 @@ public:
...
@@ -324,6 +355,17 @@ public:
template
<
typename
T
>
T
template
<
typename
T
>
T
getConfAttribute
(
std
::
string
const
&
attr
)
const
;
getConfAttribute
(
std
::
string
const
&
attr
)
const
;
/*! Get XML attribute \c attr of type \c T for the current parameter if present.
*
* \return the requested attribute
*
* \pre \c param must not have been read before from this ConfigTree.
*
* \todo write tests
*/
template
<
typename
T
>
boost
::
optional
<
T
>
getConfAttributeOptional
(
std
::
string
const
&
attr
)
const
;
//!\}
//!\}
/*! \name Methods for peeking and checking parameters
/*! \name Methods for peeking and checking parameters
...
@@ -401,7 +443,7 @@ public:
...
@@ -401,7 +443,7 @@ public:
*
*
* This method is used to avoid warning messages.
* This method is used to avoid warning messages.
*
*
* \pre \c
root
must not have been read before from this ConfigTree.
* \pre \c
param
must not have been read before from this ConfigTree.
*/
*/
void
ignoreConfParam
(
std
::
string
const
&
param
)
const
;
void
ignoreConfParam
(
std
::
string
const
&
param
)
const
;
...
@@ -409,10 +451,18 @@ public:
...
@@ -409,10 +451,18 @@ public:
*
*
* This method is used to avoid warning messages.
* This method is used to avoid warning messages.
*
*
* \pre \c
root
must not have been read before from this ConfigTree.
* \pre \c
param
must not have been read before from this ConfigTree.
*/
*/
void
ignoreConfParamAll
(
std
::
string
const
&
param
)
const
;
void
ignoreConfParamAll
(
std
::
string
const
&
param
)
const
;
/*! Tell this instance to ignore the XML attribute \c attr.
*
* This method is used to avoid warning messages.
*
* \pre \c attr must not have been read before from this ConfigTree.
*/
void
ignoreConfAttribute
(
std
::
string
const
&
attr
)
const
;
//!\}
//!\}
//! The destructor performs the check if all nodes at the current level of the tree
//! The destructor performs the check if all nodes at the current level of the tree
...
@@ -481,14 +531,15 @@ private:
...
@@ -481,14 +531,15 @@ private:
*
*
* \c param peek_only if true, do not change the read-count of the given key.
* \c param peek_only if true, do not change the read-count of the given key.
*/
*/
CountType
&
markVisited
(
std
::
string
const
&
key
,
bool
const
peek_only
)
const
;
CountType
&
markVisited
(
std
::
string
const
&
key
,
bool
const
is_attr
,
bool
const
peek_only
)
const
;
//! Used in the destructor to compute the difference between number of reads of a parameter
//! Used in the destructor to compute the difference between number of reads of a parameter
//! and the number of times it exists in the ConfigTree
//! and the number of times it exists in the ConfigTree
void
markVisitedDecrement
(
bool
const
is_attr
,
std
::
string
const
&
key
)
const
;
void
markVisitedDecrement
(
bool
const
is_attr
,
std
::
string
const
&
key
)
const
;
//! Checks if th
e
tree
\c ct
has any children.
//! Checks if th
is
tree has any children.
bool
hasChildren
(
ConfigTreeNew
const
&
ct
)
const
;
bool
hasChildren
()
const
;
/*! Checks if the top level of this tree has been read entirely (and not too often).
/*! Checks if the top level of this tree has been read entirely (and not too often).
*
*
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment