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
sugar(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;
/// \brief Return the atom the C1 is linked to
......
......@@ -248,7 +248,7 @@ class sac_parser
SAVE
};
std::istream &m_source;
std::streambuf &m_source;
// Parser state
bool m_validate;
......@@ -257,7 +257,7 @@ class sac_parser
CIFToken m_lookahead;
std::string m_token_value;
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()
}
}
if (not m_validator)
load_dictionary("mmcif_pdbx.dic"); // TODO: maybe incorrect? Perhaps improve?
// if (not m_validator)
// load_dictionary("mmcif_pdbx.dic"); // TODO: maybe incorrect? Perhaps improve?
}
void file::load_dictionary(std::string_view name)
......
......@@ -47,7 +47,7 @@ namespace cif
// --------------------------------------------------------------------
sac_parser::sac_parser(std::istream &is, bool init)
: m_source(is)
: m_source(*is.rdbuf())
{
m_validate = true;
m_line_nr = 1;
......@@ -62,26 +62,26 @@ sac_parser::sac_parser(std::istream &is, bool init)
// translation.
int sac_parser::get_next_char()
{
int result;
int result = std::char_traits<char>::eof();
if (m_buffer.empty())
result = m_source.get();
else
if (not m_buffer.empty())
{
result = m_buffer.top();
m_buffer.pop();
result = m_buffer.back();
m_buffer.pop_back();
}
else
result = m_source.sbumpc();
// very simple CR/LF translation into LF
if (result == '\r')
{
int lookahead = m_source.get();
int lookahead = m_source.sbumpc();
if (lookahead != '\n')
m_buffer.push(lookahead);
m_buffer.push_back(lookahead);
result = '\n';
}
m_token_value += static_cast<char>(result);
m_token_value.push_back(static_cast<char>(result));
if (result == '\n')
++m_line_nr;
......@@ -106,7 +106,7 @@ void sac_parser::retract()
if (ch == '\n')
--m_line_nr;
m_buffer.push(ch);
m_buffer.push_back(ch);
m_token_value.pop_back();
}
......@@ -453,8 +453,6 @@ void sac_parser::match(CIFToken token)
bool sac_parser::parse_single_datablock(const std::string &datablock)
{
// first locate the start, as fast as we can
auto &sb = *m_source.rdbuf();
enum
{
start,
......@@ -471,7 +469,7 @@ bool sac_parser::parse_single_datablock(const std::string &datablock)
std::string::size_type si = 0;
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)
{
......@@ -544,8 +542,6 @@ sac_parser::datablock_index sac_parser::index_datablocks()
datablock_index index;
// first locate the start, as fast as we can
auto &sb = *m_source.rdbuf();
enum
{
start,
......@@ -563,7 +559,7 @@ sac_parser::datablock_index sac_parser::index_datablocks()
std::string::size_type si = 0;
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)
{
......@@ -626,7 +622,7 @@ sac_parser::datablock_index sac_parser::index_datablocks()
else if (isspace(ch))
{
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;
}
......@@ -648,7 +644,7 @@ bool sac_parser::parse_single_datablock(const std::string &datablock, const data
auto i = index.find(datablock);
if (i != index.end())
{
m_source.seekg(i->second);
m_source.pubseekpos(i->second, std::ios_base::in);
produce_datablock(datablock);
m_lookahead = get_next_token();
......
......@@ -704,16 +704,17 @@ class Ff : public FBase
else
{
std::string s{ text() };
try
{
os << std::stod(s);
}
catch (const std::exception &ex)
double d = 0;
auto r = cif::from_chars(s.data(), s.data() + s.length(), d);
if (r.ec != std::errc())
{
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;
os << s;
}
else
os << d;
}
}
};
......
......@@ -1136,16 +1136,15 @@ void PDBFileParser::PreParseInput(std::istream &is)
{
std::string cs = lookahead.substr(offset, len);
cif::trim(cs);
int result;
int result = 0;
try
{
result = cs.empty() ? 0 : stoi(cs);
}
catch (...)
if (not cs.empty())
{
throw std::runtime_error("Continuation std::string '" + cs + "' is not valid");
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");
}
return result;
};
......@@ -1402,7 +1401,12 @@ void PDBFileParser::PreParseInput(std::istream &is)
link.symOpB = cur->vS(67, 72); // 67 - 72 SymOP sym2 Symmetry operator atom 2.
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
mLinks.push_back(link);
......@@ -5107,11 +5111,10 @@ void PDBFileParser::ParseConnectivtyAnnotation()
if (mRec->is("LINK "))
{
distance = vS(74, 78);
try
{
stod(distance);
}
catch (const std::invalid_argument &)
double d;
auto r = cif::from_chars(distance.data(), distance.data() + distance.length(), d);
if (r.ec != std::errc())
{
if (cif::VERBOSE > 0)
std::cerr << "Distance value '" << distance << "' is not a valid float in LINK record" << std::endl;
......@@ -6211,6 +6214,10 @@ file read(std::istream &is)
result.load(is);
}
// Must be a PDB like file, right?
if (result.get_validator() == nullptr)
result.load_dictionary("mmcif_pdbx.dic");
return result;
}
......
......@@ -1207,13 +1207,15 @@ void Remark3Parser::storeCapture(const char *category, std::initializer_list<con
}
else if (iequals(category, "pdbx_refine_tls_group"))
{
std::string tlsGroupID;
std::string tlsID;
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 },
{ "refine_tls_id", tlsGroupID } });
{ "refine_tls_id", tlsID } });
}
else if (iequals(category, "pdbx_refine_tls"))
{
......@@ -1425,10 +1427,9 @@ bool Remark3Parser::parse(const std::string &expMethod, PDBRecord *r, cif::datab
sort(scores.begin(), scores.end());
bool guessProgram = scores.empty() or scores.front().score < 0.9f;
;
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;
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