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
782f7c46
Unverified
Commit
782f7c46
authored
Nov 03, 2022
by
Maarten L. Hekkelman
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Support for cifv1.0 (empty category names)
parent
c45d02cb
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
157 additions
and
30 deletions
+157
-30
changelog
+1
-0
include/cif++/category.hpp
+3
-1
src/category.cpp
+51
-20
src/condition.cpp
+1
-1
src/parser.cpp
+8
-4
src/pdb/pdb2cif_remark_3.cpp
+1
-1
src/text.cpp
+4
-3
test/unit-v2-test.cpp
+88
-0
No files found.
changelog
View file @
782f7c46
Version
5.0.1
Version
5.0.1
-
Fix
loading
dictionaries
-
Fix
loading
dictionaries
-
Support
for
cifv1
.0
files
Version
5.0.0
Version
5.0.0
-
Total
rewrite
of
cif
part
-
Total
rewrite
of
cif
part
...
...
include/cif++/category.hpp
View file @
782f7c46
...
@@ -86,7 +86,7 @@ class category
...
@@ -86,7 +86,7 @@ class category
const
std
::
string
&
name
()
const
{
return
m_name
;
}
const
std
::
string
&
name
()
const
{
return
m_name
;
}
iset
fields
()
const
;
iset
key_
fields
()
const
;
std
::
set
<
uint16_t
>
key_field_indices
()
const
;
std
::
set
<
uint16_t
>
key_field_indices
()
const
;
...
@@ -482,6 +482,8 @@ class category
...
@@ -482,6 +482,8 @@ class category
return
get_column_ix
(
name
)
<
m_columns
.
size
();
return
get_column_ix
(
name
)
<
m_columns
.
size
();
}
}
iset
get_columns
()
const
;
// --------------------------------------------------------------------
// --------------------------------------------------------------------
void
sort
(
std
::
function
<
int
(
row_handle
,
row_handle
)
>
f
);
void
sort
(
std
::
function
<
int
(
row_handle
,
row_handle
)
>
f
);
...
...
src/category.cpp
View file @
782f7c46
...
@@ -410,7 +410,7 @@ category_index::entry *category_index::insert(entry *h, row *v)
...
@@ -410,7 +410,7 @@ category_index::entry *category_index::insert(entry *h, row *v)
row_handle
rh
(
m_category
,
*
v
);
row_handle
rh
(
m_category
,
*
v
);
std
::
ostringstream
os
;
std
::
ostringstream
os
;
for
(
auto
col
:
m_category
.
fields
())
for
(
auto
col
:
m_category
.
key_
fields
())
{
{
if
(
rh
[
col
])
if
(
rh
[
col
])
os
<<
col
<<
": "
<<
std
::
quoted
(
rh
[
col
].
text
())
<<
"; "
;
os
<<
col
<<
": "
<<
std
::
quoted
(
rh
[
col
].
text
())
<<
"; "
;
...
@@ -686,7 +686,17 @@ category::~category()
...
@@ -686,7 +686,17 @@ category::~category()
// --------------------------------------------------------------------
// --------------------------------------------------------------------
iset
category
::
fields
()
const
iset
category
::
get_columns
()
const
{
iset
result
;
for
(
auto
&
col
:
m_columns
)
result
.
insert
(
col
.
m_name
);
return
result
;
}
iset
category
::
key_fields
()
const
{
{
if
(
m_validator
==
nullptr
)
if
(
m_validator
==
nullptr
)
throw
std
::
runtime_error
(
"No Validator specified"
);
throw
std
::
runtime_error
(
"No Validator specified"
);
...
@@ -1853,7 +1863,10 @@ void category::write(std::ostream &os, const std::vector<uint16_t> &order, bool
...
@@ -1853,7 +1863,10 @@ void category::write(std::ostream &os, const std::vector<uint16_t> &order, bool
for
(
auto
cix
:
order
)
for
(
auto
cix
:
order
)
{
{
auto
&
col
=
m_columns
[
cix
];
auto
&
col
=
m_columns
[
cix
];
os
<<
'_'
<<
m_name
<<
'.'
<<
col
.
m_name
<<
' '
<<
'\n'
;
os
<<
'_'
;
if
(
not
m_name
.
empty
())
os
<<
m_name
<<
'.'
;
os
<<
col
.
m_name
<<
' '
<<
'\n'
;
columnWidths
[
cix
]
=
2
;
columnWidths
[
cix
]
=
2
;
}
}
...
@@ -1941,7 +1954,10 @@ void category::write(std::ostream &os, const std::vector<uint16_t> &order, bool
...
@@ -1941,7 +1954,10 @@ void category::write(std::ostream &os, const std::vector<uint16_t> &order, bool
{
{
auto
&
col
=
m_columns
[
cix
];
auto
&
col
=
m_columns
[
cix
];
os
<<
'_'
<<
m_name
<<
'.'
<<
col
.
m_name
<<
std
::
string
(
l
-
col
.
m_name
.
length
()
-
m_name
.
length
()
-
2
,
' '
);
os
<<
'_'
;
if
(
not
m_name
.
empty
())
os
<<
m_name
<<
'.'
;
os
<<
col
.
m_name
<<
std
::
string
(
l
-
col
.
m_name
.
length
()
-
m_name
.
length
()
-
2
,
' '
);
std
::
string_view
s
;
std
::
string_view
s
;
auto
iv
=
m_head
->
get
(
cix
);
auto
iv
=
m_head
->
get
(
cix
);
...
@@ -1978,29 +1994,44 @@ bool category::operator==(const category &rhs) const
...
@@ -1978,29 +1994,44 @@ bool category::operator==(const category &rhs) const
// if (tagsA != tagsB)
// if (tagsA != tagsB)
// std::cout << "Unequal number of fields" << std::endl;
// std::cout << "Unequal number of fields" << std::endl;
const
category_validator
*
catValidator
=
nullptr
;
auto
validator
=
a
.
get_validator
();
auto
validator
=
a
.
get_validator
();
auto
catValidator
=
validator
->
get_validator_for_category
(
a
.
name
());
if
(
validator
!=
nullptr
)
if
(
catValidator
==
nullptr
)
catValidator
=
validator
->
get_validator_for_category
(
a
.
name
());
throw
std
::
runtime_error
(
"missing cat validator"
);
typedef
std
::
function
<
int
(
std
::
string_view
,
std
::
string_view
)
>
compType
;
typedef
std
::
function
<
int
(
std
::
string_view
,
std
::
string_view
)
>
compType
;
std
::
vector
<
std
::
tuple
<
std
::
string
,
compType
>>
tags
;
std
::
vector
<
std
::
tuple
<
std
::
string
,
compType
>>
tags
;
auto
keys
=
catValidator
->
m_
keys
;
std
::
vector
<
std
::
string
>
keys
;
std
::
vector
<
size_t
>
keyIx
;
std
::
vector
<
size_t
>
keyIx
;
for
(
auto
&
tag
:
a
.
fields
()
)
if
(
catValidator
==
nullptr
)
{
{
auto
iv
=
catValidator
->
get_validator_for_item
(
tag
);
for
(
auto
&
tag
:
a
.
get_columns
())
if
(
iv
==
nullptr
)
{
throw
std
::
runtime_error
(
"missing item validator"
);
tags
.
push_back
(
std
::
make_tuple
(
tag
,
[](
std
::
string_view
va
,
std
::
string_view
vb
)
{
return
va
.
compare
(
vb
);
}));
auto
tv
=
iv
->
m_type
;
keyIx
.
push_back
(
keys
.
size
());
if
(
tv
==
nullptr
)
keys
.
push_back
(
tag
);
throw
std
::
runtime_error
(
"missing type validator"
);
}
tags
.
push_back
(
std
::
make_tuple
(
tag
,
std
::
bind
(
&
cif
::
type_validator
::
compare
,
tv
,
std
::
placeholders
::
_1
,
std
::
placeholders
::
_2
)));
}
else
auto
pred
=
[
tag
](
const
std
::
string
&
s
)
->
bool
{
return
cif
::
iequals
(
tag
,
s
)
==
0
;
};
{
if
(
find_if
(
keys
.
begin
(),
keys
.
end
(),
pred
)
==
keys
.
end
())
keys
=
catValidator
->
m_keys
;
keyIx
.
push_back
(
tags
.
size
()
-
1
);
for
(
auto
&
tag
:
a
.
key_fields
())
{
auto
iv
=
catValidator
->
get_validator_for_item
(
tag
);
if
(
iv
==
nullptr
)
throw
std
::
runtime_error
(
"missing item validator"
);
auto
tv
=
iv
->
m_type
;
if
(
tv
==
nullptr
)
throw
std
::
runtime_error
(
"missing type validator"
);
tags
.
push_back
(
std
::
make_tuple
(
tag
,
std
::
bind
(
&
cif
::
type_validator
::
compare
,
tv
,
std
::
placeholders
::
_1
,
std
::
placeholders
::
_2
)));
auto
pred
=
[
tag
](
const
std
::
string
&
s
)
->
bool
{
return
cif
::
iequals
(
tag
,
s
)
==
0
;
};
if
(
find_if
(
keys
.
begin
(),
keys
.
end
(),
pred
)
==
keys
.
end
())
keyIx
.
push_back
(
tags
.
size
()
-
1
);
}
}
}
// a.reorderByIndex();
// a.reorderByIndex();
...
...
src/condition.cpp
View file @
782f7c46
...
@@ -32,7 +32,7 @@ namespace cif
...
@@ -32,7 +32,7 @@ namespace cif
iset
get_category_fields
(
const
category
&
cat
)
iset
get_category_fields
(
const
category
&
cat
)
{
{
return
cat
.
fields
();
return
cat
.
key_
fields
();
}
}
uint16_t
get_column_ix
(
const
category
&
cat
,
std
::
string_view
col
)
uint16_t
get_column_ix
(
const
category
&
cat
,
std
::
string_view
col
)
...
...
src/parser.cpp
View file @
782f7c46
...
@@ -695,7 +695,8 @@ void sac_parser::parse_global()
...
@@ -695,7 +695,8 @@ void sac_parser::parse_global()
void
sac_parser
::
parse_datablock
()
void
sac_parser
::
parse_datablock
()
{
{
std
::
string
cat
;
static
const
std
::
string
kUnitializedCategory
(
"<invalid>"
);
std
::
string
cat
=
kUnitializedCategory
;
// intial value acts as a guard for empty category names
while
(
m_lookahead
==
CIFToken
::
LOOP
or
m_lookahead
==
CIFToken
::
Tag
or
m_lookahead
==
CIFToken
::
SAVE
)
while
(
m_lookahead
==
CIFToken
::
LOOP
or
m_lookahead
==
CIFToken
::
Tag
or
m_lookahead
==
CIFToken
::
SAVE
)
{
{
...
@@ -703,7 +704,7 @@ void sac_parser::parse_datablock()
...
@@ -703,7 +704,7 @@ void sac_parser::parse_datablock()
{
{
case
CIFToken
:
:
LOOP
:
case
CIFToken
:
:
LOOP
:
{
{
cat
.
clear
()
;
// should start a new category
cat
=
kUnitializedCategory
;
// should start a new category
match
(
CIFToken
::
LOOP
);
match
(
CIFToken
::
LOOP
);
...
@@ -714,7 +715,7 @@ void sac_parser::parse_datablock()
...
@@ -714,7 +715,7 @@ void sac_parser::parse_datablock()
std
::
string
catName
,
itemName
;
std
::
string
catName
,
itemName
;
std
::
tie
(
catName
,
itemName
)
=
split_tag_name
(
m_token_value
);
std
::
tie
(
catName
,
itemName
)
=
split_tag_name
(
m_token_value
);
if
(
cat
.
empty
()
)
if
(
cat
==
kUnitializedCategory
)
{
{
produce_category
(
catName
);
produce_category
(
catName
);
cat
=
catName
;
cat
=
catName
;
...
@@ -800,6 +801,9 @@ void parser::produce_row()
...
@@ -800,6 +801,9 @@ void parser::produce_row()
if
(
VERBOSE
>=
4
)
if
(
VERBOSE
>=
4
)
std
::
cerr
<<
"producing row for category "
<<
m_category
->
name
()
<<
std
::
endl
;
std
::
cerr
<<
"producing row for category "
<<
m_category
->
name
()
<<
std
::
endl
;
if
(
m_category
==
nullptr
)
error
(
"inconsistent categories in loop_"
);
m_category
->
emplace
({});
m_category
->
emplace
({});
m_row
=
m_category
->
back
();
m_row
=
m_category
->
back
();
// m_row.lineNr(m_line_nr);
// m_row.lineNr(m_line_nr);
...
@@ -810,7 +814,7 @@ void parser::produce_item(const std::string &category, const std::string &item,
...
@@ -810,7 +814,7 @@ void parser::produce_item(const std::string &category, const std::string &item,
if
(
VERBOSE
>=
4
)
if
(
VERBOSE
>=
4
)
std
::
cerr
<<
"producing _"
<<
category
<<
'.'
<<
item
<<
" -> "
<<
value
<<
std
::
endl
;
std
::
cerr
<<
"producing _"
<<
category
<<
'.'
<<
item
<<
" -> "
<<
value
<<
std
::
endl
;
if
(
not
iequals
(
category
,
m_category
->
name
()))
if
(
m_category
==
nullptr
or
not
iequals
(
category
,
m_category
->
name
()))
error
(
"inconsistent categories in loop_"
);
error
(
"inconsistent categories in loop_"
);
m_row
[
item
]
=
m_token_value
;
m_row
[
item
]
=
m_token_value
;
...
...
src/pdb/pdb2cif_remark_3.cpp
View file @
782f7c46
...
@@ -1483,7 +1483,7 @@ bool Remark3Parser::parse(const std::string &expMethod, PDBRecord *r, cif::datab
...
@@ -1483,7 +1483,7 @@ bool Remark3Parser::parse(const std::string &expMethod, PDBRecord *r, cif::datab
auto
r1
=
cat1
.
front
();
auto
r1
=
cat1
.
front
();
auto
r2
=
cat2
.
front
();
auto
r2
=
cat2
.
front
();
for
(
auto
column
:
cat1
.
fields
())
for
(
auto
column
:
cat1
.
key_
fields
())
r2
[
column
]
=
r1
[
column
].
text
();
r2
[
column
]
=
r1
[
column
].
text
();
}
}
}
}
...
...
src/text.cpp
View file @
782f7c46
...
@@ -224,9 +224,10 @@ std::tuple<std::string, std::string> split_tag_name(std::string_view tag)
...
@@ -224,9 +224,10 @@ std::tuple<std::string, std::string> split_tag_name(std::string_view tag)
auto
s
=
tag
.
find
(
'.'
);
auto
s
=
tag
.
find
(
'.'
);
if
(
s
==
std
::
string
::
npos
)
if
(
s
==
std
::
string
::
npos
)
throw
std
::
runtime_error
(
"tag does not contain dot ("
+
std
::
string
{
tag
}
+
')'
);
// throw std::runtime_error("tag does not contain dot (" + std::string{ tag } + ')');
return
std
::
tuple
<
std
::
string
,
std
::
string
>
{
return
std
::
tuple
<
std
::
string
,
std
::
string
>
{
""
,
tag
.
substr
(
1
)
};
tag
.
substr
(
1
,
s
-
1
),
tag
.
substr
(
s
+
1
)};
else
return
std
::
tuple
<
std
::
string
,
std
::
string
>
{
tag
.
substr
(
1
,
s
-
1
),
tag
.
substr
(
s
+
1
)};
}
}
// --------------------------------------------------------------------
// --------------------------------------------------------------------
...
...
test/unit-v2-test.cpp
View file @
782f7c46
...
@@ -2970,3 +2970,91 @@ _cat_1.id_2
...
@@ -2970,3 +2970,91 @@ _cat_1.id_2
for
(
const
auto
&
[
key
,
test
]
:
TESTS
)
for
(
const
auto
&
[
key
,
test
]
:
TESTS
)
BOOST_CHECK_EQUAL
((
bool
)
cat1
[
key
],
test
);
BOOST_CHECK_EQUAL
((
bool
)
cat1
[
key
],
test
);
}
}
// --------------------------------------------------------------------
BOOST_AUTO_TEST_CASE
(
cifv1_0_1
)
{
auto
f
=
R"(data_TEST
#
loop_
_id
_name
1 aap
2 noot
3 mies
4 ?
5 .
)"
_cf
;
auto
&
db
=
f
.
front
();
auto
&
cat
=
db
[
""
];
for
(
auto
r
:
cat
)
{
int
id
;
std
::
optional
<
std
::
string
>
name
;
cif
::
tie
(
id
,
name
)
=
r
.
get
(
"id"
,
"name"
);
switch
(
id
)
{
case
1
:
BOOST_CHECK_EQUAL
(
*
name
,
"aap"
);
break
;
case
2
:
BOOST_CHECK_EQUAL
(
*
name
,
"noot"
);
break
;
case
3
:
BOOST_CHECK_EQUAL
(
*
name
,
"mies"
);
break
;
default
:
BOOST_CHECK
(
name
.
has_value
()
==
false
);
}
}
std
::
stringstream
ss
;
ss
<<
db
;
auto
f2
=
cif
::
file
(
ss
);
auto
&
db2
=
f2
.
front
();
BOOST_TEST
(
db
==
db2
);
}
// BOOST_AUTO_TEST_CASE(cifv1_0_2)
// {
// BOOST_CHECK_THROW(R"(data_TEST
// #
// _version 1.0
// loop_
// _id
// _name
// 1 aap
// 2 noot
// 3 mies
// 4 ?
// 5 .
// )"_cf, cif::parse_error);
// }
BOOST_AUTO_TEST_CASE
(
cifv1_0_3
)
{
auto
f
=
R"(data_TEST
#
_version 1.0
_date today
)"
_cf
;
auto
&
db
=
f
.
front
();
auto
&
cat
=
db
[
""
];
BOOST_CHECK
(
not
cat
.
empty
());
auto
r
=
cat
.
front
();
BOOST_CHECK_EQUAL
(
r
[
"version"
].
as
<
std
::
string
>
(),
"1.0"
);
BOOST_CHECK_EQUAL
(
r
[
"date"
].
as
<
std
::
string
>
(),
"today"
);
std
::
stringstream
ss
;
ss
<<
db
;
auto
f2
=
cif
::
file
(
ss
);
auto
&
db2
=
f2
.
front
();
BOOST_TEST
(
db
==
db2
);
}
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