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
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
136 additions
and
29 deletions
+136
-29
include/cif++/Cif++.hpp
+87
-7
src/Cif++.cpp
+9
-6
src/CifParser.cpp
+40
-16
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
{
{
...
@@ -809,6 +820,11 @@ struct KeyIsEmptyConditionImpl : public ConditionImpl
...
@@ -809,6 +820,11 @@ 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
...
@@ -844,6 +866,11 @@ struct KeyMatchesConditionImpl : public ConditionImpl
...
@@ -844,6 +866,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
;
std
::
regex
mRx
;
std
::
regex
mRx
;
...
@@ -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
;
};
};
...
@@ -938,6 +987,15 @@ struct orConditionImpl : public ConditionImpl
...
@@ -938,6 +987,15 @@ 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
;
};
};
...
@@ -965,6 +1023,13 @@ struct notConditionImpl : public ConditionImpl
...
@@ -965,6 +1023,13 @@ 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
();
if
(
*
value
==
0
)
cond
=
std
::
move
(
cond
)
&&
Key
(
ck
)
==
Empty
();
else
cond
=
std
::
move
(
cond
)
&&
((
Key
(
ck
)
==
value
)
or
Key
(
ck
)
==
Empty
());
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
...
@@ -895,11 +895,36 @@ void DictParser::linkItems()
...
@@ -895,11 +895,36 @@ void DictParser::linkItems()
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
)
{
auto
&&
[
pkeys
,
ckeys
]
=
linkKeys
.
at
(
ix
);
bool
found
=
false
;
for
(
size_t
i
=
0
;
i
<
pkeys
.
size
();
++
i
)
{
if
(
pkeys
[
i
]
==
pk
and
ckeys
[
i
]
==
ck
)
{
found
=
true
;
break
;
}
}
if
(
not
found
)
{
pkeys
.
push_back
(
pk
);
ckeys
.
push_back
(
ck
);
}
};
auto
&
linkedGroupList
=
dict
[
"pdbx_item_linked_group_list"
];
if
(
linkedGroupList
.
empty
())
{
// for links recorded in categories but not in pdbx_item_linked_group_list
for
(
auto
li
:
mImpl
->
mLinkedItems
)
{
{
std
::
string
child
,
parent
;
std
::
string
child
,
parent
;
int
link_group_id
;
std
::
tie
(
child
,
parent
)
=
li
;
cif
::
tie
(
child
,
parent
,
link_group_id
)
=
gl
.
get
(
"child_name"
,
"parent_name"
,
"link_group_id"
);
auto
civ
=
mValidator
.
getValidatorForItem
(
child
);
auto
civ
=
mValidator
.
getValidatorForItem
(
child
);
if
(
civ
==
nullptr
)
if
(
civ
==
nullptr
)
...
@@ -910,25 +935,23 @@ void DictParser::linkItems()
...
@@ -910,25 +935,23 @@ void DictParser::linkItems()
error
(
"in pdbx_item_linked_group_list, item '"
+
parent
+
"' is not specified"
);
error
(
"in pdbx_item_linked_group_list, item '"
+
parent
+
"' is not specified"
);
auto
key
=
std
::
make_tuple
(
piv
->
mCategory
->
mName
,
civ
->
mCategory
->
mName
);
auto
key
=
std
::
make_tuple
(
piv
->
mCategory
->
mName
,
civ
->
mCategory
->
mName
);
if
(
not
linkIndex
.
count
(
key
))
if
(
linkIndex
.
count
(
key
))
{
{
linkIndex
[
key
]
=
linkKeys
.
size
();
linkIndex
[
key
]
=
linkKeys
.
size
();
linkKeys
.
push_back
({});
linkKeys
.
push_back
({});
linkGroupIds
[
key
]
=
link_group_id
;
}
}
size_t
ix
=
linkIndex
.
at
(
key
);
size_t
ix
=
linkIndex
.
at
(
key
);
addLink
(
ix
,
piv
->
mTag
,
civ
->
mTag
);
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
else
for
(
auto
li
:
mImpl
->
mLinkedItems
)
{
for
(
auto
gl
:
linkedGroupList
)
{
{
std
::
string
child
,
parent
;
std
::
string
child
,
parent
;
std
::
tie
(
child
,
parent
)
=
li
;
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
);
auto
civ
=
mValidator
.
getValidatorForItem
(
child
);
if
(
civ
==
nullptr
)
if
(
civ
==
nullptr
)
...
@@ -943,12 +966,12 @@ void DictParser::linkItems()
...
@@ -943,12 +966,12 @@ void DictParser::linkItems()
{
{
linkIndex
[
key
]
=
linkKeys
.
size
();
linkIndex
[
key
]
=
linkKeys
.
size
();
linkKeys
.
push_back
({});
linkKeys
.
push_back
({});
linkGroupIds
[
key
]
=
link_group_id
;
}
}
size_t
ix
=
linkIndex
.
at
(
key
);
size_t
ix
=
linkIndex
.
at
(
key
);
addLink
(
ix
,
piv
->
mTag
,
civ
->
mTag
);
std
::
get
<
0
>
(
linkKeys
.
at
(
ix
)).
push_back
(
piv
->
mTag
);
std
::
get
<
1
>
(
linkKeys
.
at
(
ix
)).
push_back
(
civ
->
mTag
);
}
}
auto
&
linkedGroup
=
dict
[
"pdbx_item_linked_group"
];
auto
&
linkedGroup
=
dict
[
"pdbx_item_linked_group"
];
...
@@ -973,6 +996,7 @@ void DictParser::linkItems()
...
@@ -973,6 +996,7 @@ void DictParser::linkItems()
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
...
...
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