Commit 4666ee31 by Maarten L. Hekkelman

Merge branch 'trunk' of github.com:PDB-REDO/libcifpp into trunk

parents 98db98f9 2958c56a
...@@ -608,7 +608,13 @@ class sugar : public residue ...@@ -608,7 +608,13 @@ class sugar : public residue
sugar(sugar &&rhs); sugar(sugar &&rhs);
sugar &operator=(sugar &&rhs); sugar &operator=(sugar &&rhs);
int num() const { return std::stoi(m_auth_seq_id); } int num() const {
int result;
auto r = std::from_chars(m_auth_seq_id.data(), m_auth_seq_id.data() + m_auth_seq_id.length(), result);
if (r.ec != std::errc())
throw std::runtime_error("The auth_seq_id should be a number for a sugar");
return result;
}
std::string name() const; std::string name() const;
/// \brief Return the atom the C1 is linked to /// \brief Return the atom the C1 is linked to
......
...@@ -248,7 +248,7 @@ class sac_parser ...@@ -248,7 +248,7 @@ class sac_parser
SAVE SAVE
}; };
std::istream &m_source; std::streambuf &m_source;
// Parser state // Parser state
bool m_validate; bool m_validate;
...@@ -257,7 +257,7 @@ class sac_parser ...@@ -257,7 +257,7 @@ class sac_parser
CIFToken m_lookahead; CIFToken m_lookahead;
std::string m_token_value; std::string m_token_value;
CIFValue mTokenType; CIFValue mTokenType;
std::stack<int> m_buffer; std::string m_buffer; // retract buffer, used to be a stack<char>
}; };
// -------------------------------------------------------------------- // --------------------------------------------------------------------
......
...@@ -115,8 +115,8 @@ void file::load_dictionary() ...@@ -115,8 +115,8 @@ void file::load_dictionary()
} }
} }
if (not m_validator) // if (not m_validator)
load_dictionary("mmcif_pdbx.dic"); // TODO: maybe incorrect? Perhaps improve? // load_dictionary("mmcif_pdbx.dic"); // TODO: maybe incorrect? Perhaps improve?
} }
void file::load_dictionary(std::string_view name) void file::load_dictionary(std::string_view name)
......
...@@ -47,7 +47,7 @@ namespace cif ...@@ -47,7 +47,7 @@ namespace cif
// -------------------------------------------------------------------- // --------------------------------------------------------------------
sac_parser::sac_parser(std::istream &is, bool init) sac_parser::sac_parser(std::istream &is, bool init)
: m_source(is) : m_source(*is.rdbuf())
{ {
m_validate = true; m_validate = true;
m_line_nr = 1; m_line_nr = 1;
...@@ -62,26 +62,26 @@ sac_parser::sac_parser(std::istream &is, bool init) ...@@ -62,26 +62,26 @@ sac_parser::sac_parser(std::istream &is, bool init)
// translation. // translation.
int sac_parser::get_next_char() int sac_parser::get_next_char()
{ {
int result; int result = std::char_traits<char>::eof();
if (m_buffer.empty()) if (not m_buffer.empty())
result = m_source.get();
else
{ {
result = m_buffer.top(); result = m_buffer.back();
m_buffer.pop(); m_buffer.pop_back();
} }
else
result = m_source.sbumpc();
// very simple CR/LF translation into LF // very simple CR/LF translation into LF
if (result == '\r') if (result == '\r')
{ {
int lookahead = m_source.get(); int lookahead = m_source.sbumpc();
if (lookahead != '\n') if (lookahead != '\n')
m_buffer.push(lookahead); m_buffer.push_back(lookahead);
result = '\n'; result = '\n';
} }
m_token_value += static_cast<char>(result); m_token_value.push_back(static_cast<char>(result));
if (result == '\n') if (result == '\n')
++m_line_nr; ++m_line_nr;
...@@ -106,7 +106,7 @@ void sac_parser::retract() ...@@ -106,7 +106,7 @@ void sac_parser::retract()
if (ch == '\n') if (ch == '\n')
--m_line_nr; --m_line_nr;
m_buffer.push(ch); m_buffer.push_back(ch);
m_token_value.pop_back(); m_token_value.pop_back();
} }
...@@ -453,8 +453,6 @@ void sac_parser::match(CIFToken token) ...@@ -453,8 +453,6 @@ void sac_parser::match(CIFToken token)
bool sac_parser::parse_single_datablock(const std::string &datablock) bool sac_parser::parse_single_datablock(const std::string &datablock)
{ {
// first locate the start, as fast as we can // first locate the start, as fast as we can
auto &sb = *m_source.rdbuf();
enum enum
{ {
start, start,
...@@ -471,7 +469,7 @@ bool sac_parser::parse_single_datablock(const std::string &datablock) ...@@ -471,7 +469,7 @@ bool sac_parser::parse_single_datablock(const std::string &datablock)
std::string::size_type si = 0; std::string::size_type si = 0;
bool found = false; bool found = false;
for (auto ch = sb.sbumpc(); not found and ch != std::streambuf::traits_type::eof(); ch = sb.sbumpc()) for (auto ch = m_source.sbumpc(); not found and ch != std::streambuf::traits_type::eof(); ch = m_source.sbumpc())
{ {
switch (state) switch (state)
{ {
...@@ -544,8 +542,6 @@ sac_parser::datablock_index sac_parser::index_datablocks() ...@@ -544,8 +542,6 @@ sac_parser::datablock_index sac_parser::index_datablocks()
datablock_index index; datablock_index index;
// first locate the start, as fast as we can // first locate the start, as fast as we can
auto &sb = *m_source.rdbuf();
enum enum
{ {
start, start,
...@@ -563,7 +559,7 @@ sac_parser::datablock_index sac_parser::index_datablocks() ...@@ -563,7 +559,7 @@ sac_parser::datablock_index sac_parser::index_datablocks()
std::string::size_type si = 0; std::string::size_type si = 0;
std::string datablock; std::string datablock;
for (auto ch = sb.sbumpc(); ch != std::streambuf::traits_type::eof(); ch = sb.sbumpc()) for (auto ch = m_source.sbumpc(); ch != std::streambuf::traits_type::eof(); ch = m_source.sbumpc())
{ {
switch (state) switch (state)
{ {
...@@ -626,7 +622,7 @@ sac_parser::datablock_index sac_parser::index_datablocks() ...@@ -626,7 +622,7 @@ sac_parser::datablock_index sac_parser::index_datablocks()
else if (isspace(ch)) else if (isspace(ch))
{ {
if (not datablock.empty()) if (not datablock.empty())
index[datablock] = m_source.tellg(); index[datablock] = m_source.pubseekoff(0, std::ios_base::cur, std::ios_base::in);
state = start; state = start;
} }
...@@ -648,7 +644,7 @@ bool sac_parser::parse_single_datablock(const std::string &datablock, const data ...@@ -648,7 +644,7 @@ bool sac_parser::parse_single_datablock(const std::string &datablock, const data
auto i = index.find(datablock); auto i = index.find(datablock);
if (i != index.end()) if (i != index.end())
{ {
m_source.seekg(i->second); m_source.pubseekpos(i->second, std::ios_base::in);
produce_datablock(datablock); produce_datablock(datablock);
m_lookahead = get_next_token(); m_lookahead = get_next_token();
......
...@@ -704,16 +704,17 @@ class Ff : public FBase ...@@ -704,16 +704,17 @@ class Ff : public FBase
else else
{ {
std::string s{ text() }; std::string s{ text() };
try
{ double d = 0;
os << std::stod(s); auto r = cif::from_chars(s.data(), s.data() + s.length(), d);
} if (r.ec != std::errc())
catch (const std::exception &ex)
{ {
if (VERBOSE >= 0) if (VERBOSE > 0)
std::cerr << "Failed to write '" << s << "' as a double, this indicates an error in the code for writing PDB files" << std::endl; std::cerr << "Failed to write '" << s << "' as a double, this indicates an error in the code for writing PDB files" << std::endl;
os << s; os << s;
} }
else
os << d;
} }
} }
}; };
......
...@@ -1136,16 +1136,15 @@ void PDBFileParser::PreParseInput(std::istream &is) ...@@ -1136,16 +1136,15 @@ void PDBFileParser::PreParseInput(std::istream &is)
{ {
std::string cs = lookahead.substr(offset, len); std::string cs = lookahead.substr(offset, len);
cif::trim(cs); cif::trim(cs);
int result; int result = 0;
try if (not cs.empty())
{
result = cs.empty() ? 0 : stoi(cs);
}
catch (...)
{ {
auto r = std::from_chars(cs.data(), cs.data() + cs.length(), result);
if (r.ec != std::errc())
throw std::runtime_error("Continuation std::string '" + cs + "' is not valid"); throw std::runtime_error("Continuation std::string '" + cs + "' is not valid");
} }
return result; return result;
}; };
...@@ -1402,7 +1401,12 @@ void PDBFileParser::PreParseInput(std::istream &is) ...@@ -1402,7 +1401,12 @@ void PDBFileParser::PreParseInput(std::istream &is)
link.symOpB = cur->vS(67, 72); // 67 - 72 SymOP sym2 Symmetry operator atom 2. link.symOpB = cur->vS(67, 72); // 67 - 72 SymOP sym2 Symmetry operator atom 2.
if (type == "LINK") // 1 - 6 Record name "LINK " if (type == "LINK") // 1 - 6 Record name "LINK "
link.distance = std::stof(cur->vF(74, 78)); {
auto f = cur->vF(74, 78);
auto r = cif::from_chars(f.data(), f.data() + f.length(), link.distance);
if (r.ec != std::errc() and cif::VERBOSE > 0)
std::cerr << "Error parsing link distance at line " << cur->mLineNr << std::endl;
}
// 74 – 78 Real(5.2) Length Link distance // 74 – 78 Real(5.2) Length Link distance
mLinks.push_back(link); mLinks.push_back(link);
...@@ -5107,11 +5111,10 @@ void PDBFileParser::ParseConnectivtyAnnotation() ...@@ -5107,11 +5111,10 @@ void PDBFileParser::ParseConnectivtyAnnotation()
if (mRec->is("LINK ")) if (mRec->is("LINK "))
{ {
distance = vS(74, 78); distance = vS(74, 78);
try
{ double d;
stod(distance); auto r = cif::from_chars(distance.data(), distance.data() + distance.length(), d);
} if (r.ec != std::errc())
catch (const std::invalid_argument &)
{ {
if (cif::VERBOSE > 0) if (cif::VERBOSE > 0)
std::cerr << "Distance value '" << distance << "' is not a valid float in LINK record" << std::endl; std::cerr << "Distance value '" << distance << "' is not a valid float in LINK record" << std::endl;
...@@ -6211,6 +6214,10 @@ file read(std::istream &is) ...@@ -6211,6 +6214,10 @@ file read(std::istream &is)
result.load(is); result.load(is);
} }
// Must be a PDB like file, right?
if (result.get_validator() == nullptr)
result.load_dictionary("mmcif_pdbx.dic");
return result; return result;
} }
......
...@@ -1207,13 +1207,15 @@ void Remark3Parser::storeCapture(const char *category, std::initializer_list<con ...@@ -1207,13 +1207,15 @@ void Remark3Parser::storeCapture(const char *category, std::initializer_list<con
} }
else if (iequals(category, "pdbx_refine_tls_group")) else if (iequals(category, "pdbx_refine_tls_group"))
{ {
std::string tlsGroupID; std::string tlsID;
if (not mDb["pdbx_refine_tls"].empty()) if (not mDb["pdbx_refine_tls"].empty())
tlsGroupID = mDb["pdbx_refine_tls"].back()["id"].as<std::string>(); tlsID = mDb["pdbx_refine_tls"].back()["id"].as<std::string>();
std::string tlsGroupID = cat.get_unique_id("");
cat.emplace({ { "pdbx_refine_id", mExpMethod }, cat.emplace({
{ "pdbx_refine_id", mExpMethod },
{ "id", tlsGroupID }, { "id", tlsGroupID },
{ "refine_tls_id", tlsGroupID } }); { "refine_tls_id", tlsID } });
} }
else if (iequals(category, "pdbx_refine_tls")) else if (iequals(category, "pdbx_refine_tls"))
{ {
...@@ -1425,10 +1427,9 @@ bool Remark3Parser::parse(const std::string &expMethod, PDBRecord *r, cif::datab ...@@ -1425,10 +1427,9 @@ bool Remark3Parser::parse(const std::string &expMethod, PDBRecord *r, cif::datab
sort(scores.begin(), scores.end()); sort(scores.begin(), scores.end());
bool guessProgram = scores.empty() or scores.front().score < 0.9f; bool guessProgram = scores.empty() or scores.front().score < 0.9f;
;
if (guessProgram) if (guessProgram)
{ {
if (cif::VERBOSE >= 0) if (cif::VERBOSE > 0)
std::cerr << "Unknown or untrusted program in REMARK 3, trying all parsers to see if there is a match" << std::endl; std::cerr << "Unknown or untrusted program in REMARK 3, trying all parsers to see if there is a match" << std::endl;
tryParser(new BUSTER_TNT_Remark3Parser("BUSTER-TNT", expMethod, r, db)); tryParser(new BUSTER_TNT_Remark3Parser("BUSTER-TNT", expMethod, r, db));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment