Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
L
libcifpp
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
open
libcifpp
Commits
c3963bc4
Commit
c3963bc4
authored
Oct 06, 2020
by
Maarten L. Hekkelman
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fixed linked update (regression)
parent
23bd51ac
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
189 additions
and
82 deletions
+189
-82
include/cif++/Cif++.hpp
+90
-10
src/Cif++.cpp
+10
-7
src/CifParser.cpp
+89
-65
test/unit-test.cpp
+0
-0
No files found.
include/cif++/Cif++.hpp
View file @
c3963bc4
...
@@ -718,11 +718,13 @@ struct ConditionImpl
...
@@ -718,11 +718,13 @@ struct ConditionImpl
virtual
void
prepare
(
const
Category
&
c
)
{}
virtual
void
prepare
(
const
Category
&
c
)
{}
virtual
bool
test
(
const
Category
&
c
,
const
Row
&
r
)
const
=
0
;
virtual
bool
test
(
const
Category
&
c
,
const
Row
&
r
)
const
=
0
;
virtual
void
str
(
std
::
ostream
&
os
)
const
=
0
;
};
};
struct
AllConditionImpl
:
public
ConditionImpl
struct
AllConditionImpl
:
public
ConditionImpl
{
{
virtual
bool
test
(
const
Category
&
c
,
const
Row
&
r
)
const
{
return
true
;
}
virtual
bool
test
(
const
Category
&
c
,
const
Row
&
r
)
const
{
return
true
;
}
virtual
void
str
(
std
::
ostream
&
os
)
const
{
os
<<
"*"
;
}
};
};
struct
orConditionImpl
;
struct
orConditionImpl
;
...
@@ -789,11 +791,20 @@ class Condition
...
@@ -789,11 +791,20 @@ class Condition
std
::
swap
(
mPrepared
,
rhs
.
mPrepared
);
std
::
swap
(
mPrepared
,
rhs
.
mPrepared
);
}
}
friend
std
::
ostream
&
operator
<<
(
std
::
ostream
&
os
,
const
Condition
&
cond
);
private
:
private
:
detail
::
ConditionImpl
*
mImpl
;
detail
::
ConditionImpl
*
mImpl
;
bool
mPrepared
=
false
;
bool
mPrepared
=
false
;
};
};
inline
std
::
ostream
&
operator
<<
(
std
::
ostream
&
os
,
const
Condition
&
cond
)
{
if
(
cond
.
mImpl
)
cond
.
mImpl
->
str
(
os
);
return
os
;
}
namespace
detail
namespace
detail
{
{
...
@@ -808,7 +819,12 @@ struct KeyIsEmptyConditionImpl : public ConditionImpl
...
@@ -808,7 +819,12 @@ struct KeyIsEmptyConditionImpl : public ConditionImpl
{
{
return
r
[
mItemIx
].
empty
();
return
r
[
mItemIx
].
empty
();
}
}
virtual
void
str
(
std
::
ostream
&
os
)
const
{
os
<<
mItemTag
<<
" IS NULL"
;
}
std
::
string
mItemTag
;
std
::
string
mItemTag
;
size_t
mItemIx
;
size_t
mItemIx
;
};
};
...
@@ -816,8 +832,8 @@ struct KeyIsEmptyConditionImpl : public ConditionImpl
...
@@ -816,8 +832,8 @@ struct KeyIsEmptyConditionImpl : public ConditionImpl
struct
KeyCompareConditionImpl
:
public
ConditionImpl
struct
KeyCompareConditionImpl
:
public
ConditionImpl
{
{
template
<
typename
COMP
>
template
<
typename
COMP
>
KeyCompareConditionImpl
(
const
std
::
string
&
ItemTag
,
COMP
&&
comp
)
KeyCompareConditionImpl
(
const
std
::
string
&
ItemTag
,
COMP
&&
comp
,
const
std
::
string
&
s
)
:
mItemTag
(
ItemTag
),
mComp
(
std
::
move
(
comp
))
{}
:
mItemTag
(
ItemTag
),
mComp
(
std
::
move
(
comp
))
,
mStr
(
s
)
{}
virtual
void
prepare
(
const
Category
&
c
);
virtual
void
prepare
(
const
Category
&
c
);
...
@@ -826,10 +842,16 @@ struct KeyCompareConditionImpl : public ConditionImpl
...
@@ -826,10 +842,16 @@ struct KeyCompareConditionImpl : public ConditionImpl
return
mComp
(
c
,
r
,
mCaseInsensitive
);
return
mComp
(
c
,
r
,
mCaseInsensitive
);
}
}
virtual
void
str
(
std
::
ostream
&
os
)
const
{
os
<<
mItemTag
<<
(
mCaseInsensitive
?
"^ "
:
" "
)
<<
mStr
;
}
std
::
string
mItemTag
;
std
::
string
mItemTag
;
size_t
mItemIx
;
size_t
mItemIx
;
bool
mCaseInsensitive
=
false
;
bool
mCaseInsensitive
=
false
;
std
::
function
<
bool
(
const
Category
&
,
const
Row
&
,
bool
)
>
mComp
;
std
::
function
<
bool
(
const
Category
&
,
const
Row
&
,
bool
)
>
mComp
;
std
::
string
mStr
;
};
};
struct
KeyMatchesConditionImpl
:
public
ConditionImpl
struct
KeyMatchesConditionImpl
:
public
ConditionImpl
...
@@ -843,6 +865,11 @@ struct KeyMatchesConditionImpl : public ConditionImpl
...
@@ -843,6 +865,11 @@ struct KeyMatchesConditionImpl : public ConditionImpl
{
{
return
std
::
regex_match
(
r
[
mItemIx
].
as
<
std
::
string
>
(),
mRx
);
return
std
::
regex_match
(
r
[
mItemIx
].
as
<
std
::
string
>
(),
mRx
);
}
}
virtual
void
str
(
std
::
ostream
&
os
)
const
{
os
<<
mItemTag
<<
" =~ expression"
;
}
std
::
string
mItemTag
;
std
::
string
mItemTag
;
size_t
mItemIx
;
size_t
mItemIx
;
...
@@ -858,6 +885,10 @@ struct anyIsConditionImpl : public ConditionImpl
...
@@ -858,6 +885,10 @@ struct anyIsConditionImpl : public ConditionImpl
:
mValue
(
value
)
{}
:
mValue
(
value
)
{}
virtual
bool
test
(
const
Category
&
c
,
const
Row
&
r
)
const
;
virtual
bool
test
(
const
Category
&
c
,
const
Row
&
r
)
const
;
virtual
void
str
(
std
::
ostream
&
os
)
const
{
os
<<
"<any> == "
<<
mValue
;
}
valueType
mValue
;
valueType
mValue
;
};
};
...
@@ -868,6 +899,10 @@ struct anyMatchesConditionImpl : public ConditionImpl
...
@@ -868,6 +899,10 @@ struct anyMatchesConditionImpl : public ConditionImpl
:
mRx
(
rx
)
{}
:
mRx
(
rx
)
{}
virtual
bool
test
(
const
Category
&
c
,
const
Row
&
r
)
const
;
virtual
bool
test
(
const
Category
&
c
,
const
Row
&
r
)
const
;
virtual
void
str
(
std
::
ostream
&
os
)
const
{
os
<<
"<any> =~ expression"
;
}
std
::
regex
mRx
;
std
::
regex
mRx
;
};
};
...
@@ -880,6 +915,11 @@ struct allConditionImpl : public ConditionImpl
...
@@ -880,6 +915,11 @@ struct allConditionImpl : public ConditionImpl
{
{
return
true
;
return
true
;
}
}
virtual
void
str
(
std
::
ostream
&
os
)
const
{
os
<<
"*"
;
}
};
};
struct
andConditionImpl
:
public
ConditionImpl
struct
andConditionImpl
:
public
ConditionImpl
...
@@ -908,6 +948,15 @@ struct andConditionImpl : public ConditionImpl
...
@@ -908,6 +948,15 @@ struct andConditionImpl : public ConditionImpl
return
mA
->
test
(
c
,
r
)
and
mB
->
test
(
c
,
r
);
return
mA
->
test
(
c
,
r
)
and
mB
->
test
(
c
,
r
);
}
}
virtual
void
str
(
std
::
ostream
&
os
)
const
{
os
<<
'('
;
mA
->
str
(
os
);
os
<<
") AND ("
;
mB
->
str
(
os
);
os
<<
')'
;
}
ConditionImpl
*
mA
;
ConditionImpl
*
mA
;
ConditionImpl
*
mB
;
ConditionImpl
*
mB
;
};
};
...
@@ -937,7 +986,16 @@ struct orConditionImpl : public ConditionImpl
...
@@ -937,7 +986,16 @@ struct orConditionImpl : public ConditionImpl
{
{
return
mA
->
test
(
c
,
r
)
or
mB
->
test
(
c
,
r
);
return
mA
->
test
(
c
,
r
)
or
mB
->
test
(
c
,
r
);
}
}
virtual
void
str
(
std
::
ostream
&
os
)
const
{
os
<<
'('
;
mA
->
str
(
os
);
os
<<
") OR ("
;
mB
->
str
(
os
);
os
<<
')'
;
}
ConditionImpl
*
mA
;
ConditionImpl
*
mA
;
ConditionImpl
*
mB
;
ConditionImpl
*
mB
;
};
};
...
@@ -964,7 +1022,14 @@ struct notConditionImpl : public ConditionImpl
...
@@ -964,7 +1022,14 @@ struct notConditionImpl : public ConditionImpl
{
{
return
not
mA
->
test
(
c
,
r
);
return
not
mA
->
test
(
c
,
r
);
}
}
virtual
void
str
(
std
::
ostream
&
os
)
const
{
os
<<
"NOT ("
;
mA
->
str
(
os
);
os
<<
')'
;
}
ConditionImpl
*
mA
;
ConditionImpl
*
mA
;
};
};
...
@@ -1004,8 +1069,11 @@ struct Key
...
@@ -1004,8 +1069,11 @@ struct Key
template
<
typename
T
>
template
<
typename
T
>
Condition
operator
==
(
const
Key
&
key
,
const
T
&
v
)
Condition
operator
==
(
const
Key
&
key
,
const
T
&
v
)
{
{
std
::
ostringstream
s
;
s
<<
"== "
<<
v
;
return
Condition
(
new
detail
::
KeyCompareConditionImpl
(
key
.
mItemTag
,
[
tag
=
key
.
mItemTag
,
v
](
const
Category
&
c
,
const
Row
&
r
,
bool
icase
)
return
Condition
(
new
detail
::
KeyCompareConditionImpl
(
key
.
mItemTag
,
[
tag
=
key
.
mItemTag
,
v
](
const
Category
&
c
,
const
Row
&
r
,
bool
icase
)
{
return
r
[
tag
].
template
compare
<
T
>
(
v
,
icase
)
==
0
;
}));
{
return
r
[
tag
].
template
compare
<
T
>
(
v
,
icase
)
==
0
;
}
,
s
.
str
()
));
}
}
// inline Condition operator==(const Key& key, const detail::ItemReference& v)
// inline Condition operator==(const Key& key, const detail::ItemReference& v)
...
@@ -1037,29 +1105,41 @@ inline Condition operator!=(const Key& key, const char* v)
...
@@ -1037,29 +1105,41 @@ inline Condition operator!=(const Key& key, const char* v)
template
<
typename
T
>
template
<
typename
T
>
Condition
operator
>
(
const
Key
&
key
,
const
T
&
v
)
Condition
operator
>
(
const
Key
&
key
,
const
T
&
v
)
{
{
std
::
ostringstream
s
;
s
<<
">"
<<
v
;
return
Condition
(
new
detail
::
KeyCompareConditionImpl
(
key
.
mItemTag
,
[
tag
=
key
.
mItemTag
,
v
](
const
Category
&
c
,
const
Row
&
r
,
bool
icase
)
return
Condition
(
new
detail
::
KeyCompareConditionImpl
(
key
.
mItemTag
,
[
tag
=
key
.
mItemTag
,
v
](
const
Category
&
c
,
const
Row
&
r
,
bool
icase
)
{
return
r
[
tag
].
template
compare
<
T
>
(
v
,
icase
)
>
0
;
}));
{
return
r
[
tag
].
template
compare
<
T
>
(
v
,
icase
)
>
0
;
}
,
s
.
str
()
));
}
}
template
<
typename
T
>
template
<
typename
T
>
Condition
operator
>=
(
const
Key
&
key
,
const
T
&
v
)
Condition
operator
>=
(
const
Key
&
key
,
const
T
&
v
)
{
{
std
::
ostringstream
s
;
s
<<
">="
<<
v
;
return
Condition
(
new
detail
::
KeyCompareConditionImpl
(
key
.
mItemTag
,
[
tag
=
key
.
mItemTag
,
v
](
const
Category
&
c
,
const
Row
&
r
,
bool
icase
)
return
Condition
(
new
detail
::
KeyCompareConditionImpl
(
key
.
mItemTag
,
[
tag
=
key
.
mItemTag
,
v
](
const
Category
&
c
,
const
Row
&
r
,
bool
icase
)
{
return
r
[
tag
].
template
compare
<
T
>
(
v
,
icase
)
>=
0
;
}));
{
return
r
[
tag
].
template
compare
<
T
>
(
v
,
icase
)
>=
0
;
}
,
s
.
str
()
));
}
}
template
<
typename
T
>
template
<
typename
T
>
Condition
operator
<
(
const
Key
&
key
,
const
T
&
v
)
Condition
operator
<
(
const
Key
&
key
,
const
T
&
v
)
{
{
std
::
ostringstream
s
;
s
<<
"<"
<<
v
;
return
Condition
(
new
detail
::
KeyCompareConditionImpl
(
key
.
mItemTag
,
[
tag
=
key
.
mItemTag
,
v
](
const
Category
&
c
,
const
Row
&
r
,
bool
icase
)
return
Condition
(
new
detail
::
KeyCompareConditionImpl
(
key
.
mItemTag
,
[
tag
=
key
.
mItemTag
,
v
](
const
Category
&
c
,
const
Row
&
r
,
bool
icase
)
{
return
r
[
tag
].
template
compare
<
T
>
(
v
,
icase
)
<
0
;
}));
{
return
r
[
tag
].
template
compare
<
T
>
(
v
,
icase
)
<
0
;
}
,
s
.
str
()
));
}
}
template
<
typename
T
>
template
<
typename
T
>
Condition
operator
<=
(
const
Key
&
key
,
const
T
&
v
)
Condition
operator
<=
(
const
Key
&
key
,
const
T
&
v
)
{
{
std
::
ostringstream
s
;
s
<<
"<="
<<
v
;
return
Condition
(
new
detail
::
KeyCompareConditionImpl
(
key
.
mItemTag
,
[
tag
=
key
.
mItemTag
,
v
](
const
Category
&
c
,
const
Row
&
r
,
bool
icase
)
return
Condition
(
new
detail
::
KeyCompareConditionImpl
(
key
.
mItemTag
,
[
tag
=
key
.
mItemTag
,
v
](
const
Category
&
c
,
const
Row
&
r
,
bool
icase
)
{
return
r
[
tag
].
template
compare
<
T
>
(
v
,
icase
)
<=
0
;
}));
{
return
r
[
tag
].
template
compare
<
T
>
(
v
,
icase
)
<=
0
;
}
,
s
.
str
()
));
}
}
template
<>
template
<>
...
...
src/Cif++.cpp
View file @
c3963bc4
...
@@ -2519,7 +2519,7 @@ void Row::assign(size_t column, const std::string& value, bool skipUpdateLinked)
...
@@ -2519,7 +2519,7 @@ void Row::assign(size_t column, const std::string& value, bool skipUpdateLinked)
std
::
string
pk
=
linked
->
mParentKeys
[
ix
];
std
::
string
pk
=
linked
->
mParentKeys
[
ix
];
std
::
string
ck
=
linked
->
mChildKeys
[
ix
];
std
::
string
ck
=
linked
->
mChildKeys
[
ix
];
// TODO add code to *NOT* test mandatory fiels for Empty
// TODO add code to *NOT* test mandatory fiel
d
s for Empty
if
(
pk
==
iv
->
mTag
)
if
(
pk
==
iv
->
mTag
)
{
{
...
@@ -2529,16 +2529,19 @@ void Row::assign(size_t column, const std::string& value, bool skipUpdateLinked)
...
@@ -2529,16 +2529,19 @@ void Row::assign(size_t column, const std::string& value, bool skipUpdateLinked)
else
else
{
{
const
char
*
value
=
(
*
this
)[
pk
].
c_str
();
const
char
*
value
=
(
*
this
)[
pk
].
c_str
();
cond
=
std
::
move
(
cond
)
&&
((
Key
(
ck
)
==
value
)
or
Key
(
ck
)
==
Empty
());
if
(
*
value
==
0
)
cond
=
std
::
move
(
cond
)
&&
Key
(
ck
)
==
Empty
();
else
cond
=
std
::
move
(
cond
)
&&
((
Key
(
ck
)
==
value
)
or
Key
(
ck
)
==
Empty
());
}
}
}
}
// if (cif::VERBOSE >
2)
if
(
cif
::
VERBOSE
>=
2
)
//
{
{
// std::std::cerr << "Parent: " << linked->mParentCategory << " Child: " << linked->mChildCategory << std::
std::endl
std
::
cerr
<<
"Parent: "
<<
linked
->
mParentCategory
<<
" Child: "
<<
linked
->
mChildCategory
<<
std
::
endl
// << cond << std::
std::endl;
<<
cond
<<
std
::
endl
;
//
}
}
auto
rows
=
childCat
->
find
(
std
::
move
(
cond
));
auto
rows
=
childCat
->
find
(
std
::
move
(
cond
));
for
(
auto
&
cr
:
rows
)
for
(
auto
&
cr
:
rows
)
...
...
src/CifParser.cpp
View file @
c3963bc4
...
@@ -894,86 +894,110 @@ void DictParser::linkItems()
...
@@ -894,86 +894,110 @@ void DictParser::linkItems()
std
::
map
<
std
::
tuple
<
std
::
string
,
std
::
string
>
,
size_t
>
linkIndex
;
std
::
map
<
std
::
tuple
<
std
::
string
,
std
::
string
>
,
size_t
>
linkIndex
;
std
::
map
<
std
::
tuple
<
std
::
string
,
std
::
string
>
,
int
>
linkGroupIds
;
std
::
map
<
std
::
tuple
<
std
::
string
,
std
::
string
>
,
int
>
linkGroupIds
;
std
::
vector
<
std
::
tuple
<
std
::
vector
<
std
::
string
>
,
std
::
vector
<
std
::
string
>>>
linkKeys
;
std
::
vector
<
std
::
tuple
<
std
::
vector
<
std
::
string
>
,
std
::
vector
<
std
::
string
>>>
linkKeys
;
for
(
auto
gl
:
dict
[
"pdbx_item_linked_group_list"
]
)
auto
addLink
=
[
&
](
size_t
ix
,
const
std
::
string
&
pk
,
const
std
::
string
&
ck
)
{
{
std
::
string
child
,
parent
;
auto
&&
[
pkeys
,
ckeys
]
=
linkKeys
.
at
(
ix
);
int
link_group_id
;
cif
::
tie
(
child
,
parent
,
link_group_id
)
=
gl
.
get
(
"child_name"
,
"parent_name"
,
"link_group_id"
);
bool
found
=
false
;
for
(
size_t
i
=
0
;
i
<
pkeys
.
size
();
++
i
)
auto
civ
=
mValidator
.
getValidatorForItem
(
child
);
if
(
civ
==
nullptr
)
error
(
"in pdbx_item_linked_group_list, item '"
+
child
+
"' is not specified"
);
auto
piv
=
mValidator
.
getValidatorForItem
(
parent
);
if
(
piv
==
nullptr
)
error
(
"in pdbx_item_linked_group_list, item '"
+
parent
+
"' is not specified"
);
auto
key
=
std
::
make_tuple
(
piv
->
mCategory
->
mName
,
civ
->
mCategory
->
mName
);
if
(
not
linkIndex
.
count
(
key
))
{
{
linkIndex
[
key
]
=
linkKeys
.
size
();
if
(
pkeys
[
i
]
==
pk
and
ckeys
[
i
]
==
ck
)
linkKeys
.
push_back
({});
{
found
=
true
;
break
;
}
}
linkGroupIds
[
key
]
=
link_group_id
;
if
(
not
found
)
{
pkeys
.
push_back
(
pk
);
ckeys
.
push_back
(
ck
);
}
}
};
size_t
ix
=
linkIndex
.
at
(
key
);
std
::
get
<
0
>
(
linkKeys
.
at
(
ix
)).
push_back
(
piv
->
mTag
);
std
::
get
<
1
>
(
linkKeys
.
at
(
ix
)).
push_back
(
civ
->
mTag
);
}
// for links recorded in categories but not in pdbx_item_linked_group_list
auto
&
linkedGroupList
=
dict
[
"pdbx_item_linked_group_list"
];
for
(
auto
li
:
mImpl
->
mLinkedItems
)
{
std
::
string
child
,
parent
;
std
::
tie
(
child
,
parent
)
=
li
;
auto
civ
=
mValidator
.
getValidatorForItem
(
child
);
if
(
civ
==
nullptr
)
error
(
"in pdbx_item_linked_group_list, item '"
+
child
+
"' is not specified"
);
auto
piv
=
mValidator
.
getValidatorForItem
(
parent
);
if
(
piv
==
nullptr
)
error
(
"in pdbx_item_linked_group_list, item '"
+
parent
+
"' is not specified"
);
auto
key
=
std
::
make_tuple
(
piv
->
mCategory
->
mName
,
civ
->
mCategory
->
mName
);
if
(
linkedGroupList
.
empty
())
if
(
not
linkIndex
.
count
(
key
))
{
// for links recorded in categories but not in pdbx_item_linked_group_list
for
(
auto
li
:
mImpl
->
mLinkedItems
)
{
{
linkIndex
[
key
]
=
linkKeys
.
size
();
std
::
string
child
,
parent
;
linkKeys
.
push_back
({});
std
::
tie
(
child
,
parent
)
=
li
;
auto
civ
=
mValidator
.
getValidatorForItem
(
child
);
if
(
civ
==
nullptr
)
error
(
"in pdbx_item_linked_group_list, item '"
+
child
+
"' is not specified"
);
auto
piv
=
mValidator
.
getValidatorForItem
(
parent
);
if
(
piv
==
nullptr
)
error
(
"in pdbx_item_linked_group_list, item '"
+
parent
+
"' is not specified"
);
auto
key
=
std
::
make_tuple
(
piv
->
mCategory
->
mName
,
civ
->
mCategory
->
mName
);
if
(
linkIndex
.
count
(
key
))
{
linkIndex
[
key
]
=
linkKeys
.
size
();
linkKeys
.
push_back
({});
}
size_t
ix
=
linkIndex
.
at
(
key
);
addLink
(
ix
,
piv
->
mTag
,
civ
->
mTag
);
}
}
size_t
ix
=
linkIndex
.
at
(
key
);
std
::
get
<
0
>
(
linkKeys
.
at
(
ix
)).
push_back
(
piv
->
mTag
);
std
::
get
<
1
>
(
linkKeys
.
at
(
ix
)).
push_back
(
civ
->
mTag
);
}
}
else
auto
&
linkedGroup
=
dict
[
"pdbx_item_linked_group"
];
// now store the links in the validator
for
(
auto
&
kv
:
linkIndex
)
{
{
ValidateLink
link
=
{};
for
(
auto
gl
:
linkedGroupList
)
std
::
tie
(
link
.
mParentCategory
,
link
.
mChildCategory
)
=
kv
.
first
;
{
std
::
string
child
,
parent
;
int
link_group_id
;
cif
::
tie
(
child
,
parent
,
link_group_id
)
=
gl
.
get
(
"child_name"
,
"parent_name"
,
"link_group_id"
);
auto
civ
=
mValidator
.
getValidatorForItem
(
child
);
if
(
civ
==
nullptr
)
error
(
"in pdbx_item_linked_group_list, item '"
+
child
+
"' is not specified"
);
auto
piv
=
mValidator
.
getValidatorForItem
(
parent
);
if
(
piv
==
nullptr
)
error
(
"in pdbx_item_linked_group_list, item '"
+
parent
+
"' is not specified"
);
auto
key
=
std
::
make_tuple
(
piv
->
mCategory
->
mName
,
civ
->
mCategory
->
mName
);
if
(
not
linkIndex
.
count
(
key
))
{
linkIndex
[
key
]
=
linkKeys
.
size
();
linkKeys
.
push_back
({});
if
(
linkGroupIds
.
count
(
kv
.
first
))
linkGroupIds
[
key
]
=
link_group_id
;
link
.
mLinkGroupID
=
linkGroupIds
[
kv
.
first
];
}
std
::
tie
(
link
.
mParentKeys
,
link
.
mChildKeys
)
=
linkKeys
[
kv
.
second
];
size_t
ix
=
linkIndex
.
at
(
key
);
addLink
(
ix
,
piv
->
mTag
,
civ
->
mTag
);
}
// look up the label
auto
&
linkedGroup
=
dict
[
"pdbx_item_linked_group"
];
for
(
auto
r
:
linkedGroup
.
find
(
cif
::
Key
(
"category_id"
)
==
link
.
mChildCategory
and
cif
::
Key
(
"link_group_id"
)
==
link
.
mLinkGroupID
))
// now store the links in the validator
for
(
auto
&
kv
:
linkIndex
)
{
{
link
.
mLinkGroupLabel
=
r
[
"label"
].
as
<
std
::
string
>
();
ValidateLink
link
=
{};
break
;
std
::
tie
(
link
.
mParentCategory
,
link
.
mChildCategory
)
=
kv
.
first
;
}
if
(
linkGroupIds
.
count
(
kv
.
first
))
link
.
mLinkGroupID
=
linkGroupIds
[
kv
.
first
];
std
::
tie
(
link
.
mParentKeys
,
link
.
mChildKeys
)
=
linkKeys
[
kv
.
second
];
// look up the label
for
(
auto
r
:
linkedGroup
.
find
(
cif
::
Key
(
"category_id"
)
==
link
.
mChildCategory
and
cif
::
Key
(
"link_group_id"
)
==
link
.
mLinkGroupID
))
{
link
.
mLinkGroupLabel
=
r
[
"label"
].
as
<
std
::
string
>
();
break
;
}
mValidator
.
addLinkValidator
(
std
::
move
(
link
));
mValidator
.
addLinkValidator
(
std
::
move
(
link
));
}
}
}
// now make sure the itemType is specified for all itemValidators
// now make sure the itemType is specified for all itemValidators
for
(
auto
&
cv
:
mValidator
.
mCategoryValidators
)
for
(
auto
&
cv
:
mValidator
.
mCategoryValidators
)
...
...
test/unit-test.cpp
View file @
c3963bc4
This diff is collapsed.
Click to expand it.
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