Commit 24078771 by Maarten L. Hekkelman

Reordering all files

parent 5fde0507
...@@ -193,50 +193,63 @@ endif() ...@@ -193,50 +193,63 @@ endif()
# Sources # Sources
set(project_sources set(project_sources
${PROJECT_SOURCE_DIR}/src/AtomType.cpp ${PROJECT_SOURCE_DIR}/src/cif/category.cpp
${PROJECT_SOURCE_DIR}/src/BondMap.cpp ${PROJECT_SOURCE_DIR}/src/cif/condition.cpp
${PROJECT_SOURCE_DIR}/src/Cif++.cpp ${PROJECT_SOURCE_DIR}/src/cif/datablock.cpp
${PROJECT_SOURCE_DIR}/src/Cif2PDB.cpp ${PROJECT_SOURCE_DIR}/src/cif/dictionary_parser.cpp
${PROJECT_SOURCE_DIR}/src/CifParser.cpp ${PROJECT_SOURCE_DIR}/src/cif/item.cpp
${PROJECT_SOURCE_DIR}/src/CifUtils.cpp ${PROJECT_SOURCE_DIR}/src/cif/parser.cpp
${PROJECT_SOURCE_DIR}/src/CifValidator.cpp ${PROJECT_SOURCE_DIR}/src/cif/row.cpp
${PROJECT_SOURCE_DIR}/src/Compound.cpp ${PROJECT_SOURCE_DIR}/src/cif/validate.cpp
${PROJECT_SOURCE_DIR}/src/PDB2Cif.cpp
${PROJECT_SOURCE_DIR}/src/PDB2CifRemark3.cpp # ${PROJECT_SOURCE_DIR}/src/pdb/Cif2PDB.cpp
${PROJECT_SOURCE_DIR}/src/Point.cpp # ${PROJECT_SOURCE_DIR}/src/pdb/PDB2Cif.cpp
${PROJECT_SOURCE_DIR}/src/Secondary.cpp # ${PROJECT_SOURCE_DIR}/src/pdb/PDB2CifRemark3.cpp
${PROJECT_SOURCE_DIR}/src/Structure.cpp
${PROJECT_SOURCE_DIR}/src/Symmetry.cpp # ${PROJECT_SOURCE_DIR}/src/structure/AtomType.cpp
${PROJECT_SOURCE_DIR}/src/TlsParser.cpp # ${PROJECT_SOURCE_DIR}/src/structure/BondMap.cpp
# ${PROJECT_SOURCE_DIR}/src/structure/Compound.cpp
${PROJECT_SOURCE_DIR}/src/v2/category.cpp # ${PROJECT_SOURCE_DIR}/src/structure/Secondary.cpp
${PROJECT_SOURCE_DIR}/src/v2/condition.cpp # ${PROJECT_SOURCE_DIR}/src/structure/Structure.cpp
${PROJECT_SOURCE_DIR}/src/v2/dictionary_parser.cpp # ${PROJECT_SOURCE_DIR}/src/structure/Symmetry.cpp
${PROJECT_SOURCE_DIR}/src/v2/item.cpp # ${PROJECT_SOURCE_DIR}/src/structure/TlsParser.cpp
${PROJECT_SOURCE_DIR}/src/v2/parser.cpp
${PROJECT_SOURCE_DIR}/src/v2/row.cpp ${PROJECT_SOURCE_DIR}/src/utilities.cpp
${PROJECT_SOURCE_DIR}/src/v2/validate.cpp ${PROJECT_SOURCE_DIR}/src/point.cpp
) )
set(project_headers set(project_headers
${PROJECT_SOURCE_DIR}/include/cif++/AtomType.hpp
${PROJECT_SOURCE_DIR}/include/cif++/BondMap.hpp ${PROJECT_SOURCE_DIR}/include/cif++/cif.hpp
${PROJECT_SOURCE_DIR}/include/cif++/utilities.hpp
${PROJECT_SOURCE_DIR}/include/cif++/cif/item.hpp
${PROJECT_SOURCE_DIR}/include/cif++/cif/datablock.hpp
${PROJECT_SOURCE_DIR}/include/cif++/cif/file.hpp
${PROJECT_SOURCE_DIR}/include/cif++/cif/writer.hpp
${PROJECT_SOURCE_DIR}/include/cif++/cif/validate.hpp
${PROJECT_SOURCE_DIR}/include/cif++/cif/list.hpp
${PROJECT_SOURCE_DIR}/include/cif++/cif/iterator.hpp
${PROJECT_SOURCE_DIR}/include/cif++/cif/parser.hpp
${PROJECT_SOURCE_DIR}/include/cif++/cif/forward_decl.hpp
${PROJECT_SOURCE_DIR}/include/cif++/cif/dictionary_parser.hpp
${PROJECT_SOURCE_DIR}/include/cif++/cif/condition.hpp
${PROJECT_SOURCE_DIR}/include/cif++/cif/category.hpp
${PROJECT_SOURCE_DIR}/include/cif++/cif/row.hpp
${PROJECT_SOURCE_DIR}/include/cif++/structure/AtomType.hpp
${PROJECT_SOURCE_DIR}/include/cif++/structure/BondMap.hpp
${PROJECT_SOURCE_DIR}/include/cif++/structure/TlsParser.hpp
${PROJECT_SOURCE_DIR}/include/cif++/structure/Symmetry.hpp
${PROJECT_SOURCE_DIR}/include/cif++/structure/Structure.hpp
${PROJECT_SOURCE_DIR}/include/cif++/structure/Secondary.hpp
${PROJECT_SOURCE_DIR}/include/cif++/structure/Compound.hpp
${PROJECT_SOURCE_DIR}/include/cif++/pdb/PDB2Cif.hpp
${PROJECT_SOURCE_DIR}/include/cif++/pdb/PDB2CifRemark3.hpp
${PROJECT_SOURCE_DIR}/include/cif++/pdb/Cif2PDB.hpp
${PROJECT_SOURCE_DIR}/include/cif++/Cif++.hpp ${PROJECT_SOURCE_DIR}/include/cif++/Cif++.hpp
${PROJECT_SOURCE_DIR}/include/cif++/Cif2PDB.hpp ${PROJECT_SOURCE_DIR}/include/cif++/point.hpp
${PROJECT_SOURCE_DIR}/include/cif++/CifParser.hpp
${PROJECT_SOURCE_DIR}/include/cif++/CifUtils.hpp
${PROJECT_SOURCE_DIR}/include/cif++/CifValidator.hpp
${PROJECT_SOURCE_DIR}/include/cif++/Compound.hpp
${PROJECT_SOURCE_DIR}/include/cif++/PDB2Cif.hpp
${PROJECT_SOURCE_DIR}/include/cif++/PDB2CifRemark3.hpp
${PROJECT_SOURCE_DIR}/include/cif++/Point.hpp
${PROJECT_SOURCE_DIR}/include/cif++/Secondary.hpp
${PROJECT_SOURCE_DIR}/include/cif++/Structure.hpp
${PROJECT_SOURCE_DIR}/include/cif++/Symmetry.hpp
${PROJECT_SOURCE_DIR}/include/cif++/TlsParser.hpp
) )
add_library(cifpp ${project_sources} ${project_headers} ${CMAKE_SOURCE_DIR}/src/SymOpTable_data.hpp) add_library(cifpp ${project_sources} ${project_headers} ${CMAKE_SOURCE_DIR}/src/structure/SymOpTable_data.hpp)
set_target_properties(cifpp PROPERTIES POSITION_INDEPENDENT_CODE ON) set_target_properties(cifpp PROPERTIES POSITION_INDEPENDENT_CODE ON)
target_include_directories(cifpp target_include_directories(cifpp
...@@ -391,10 +404,10 @@ if(CIFPP_BUILD_TESTS) ...@@ -391,10 +404,10 @@ if(CIFPP_BUILD_TESTS)
list(APPEND CIFPP_tests list(APPEND CIFPP_tests
# pdb2cif # pdb2cif
rename-compound # rename-compound
structure # structure
sugar # sugar
unit # unit
unit-v2) unit-v2)
foreach(CIFPP_TEST IN LISTS CIFPP_tests) foreach(CIFPP_TEST IN LISTS CIFPP_tests)
......
This source diff could not be displayed because it is too large. You can view the blob instead.
/*-
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2020 NKI/AVL, Netherlands Cancer Institute
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
#include <cif++/Cif++.hpp>
#include <map>
#include <stack>
namespace cif
{
// --------------------------------------------------------------------
class CifParserError : public std::runtime_error
{
public:
CifParserError(uint32_t lineNr, const std::string &message);
};
// --------------------------------------------------------------------
extern const uint32_t kMaxLineLength;
extern const uint8_t kCharTraitsTable[128];
enum CharTraitsMask : uint8_t
{
kOrdinaryMask = 1 << 0,
kNonBlankMask = 1 << 1,
kTextLeadMask = 1 << 2,
kAnyPrintMask = 1 << 3
};
inline bool isWhite(int ch)
{
return std::isspace(ch) or ch == '#';
}
inline bool isOrdinary(int ch)
{
return ch >= 0x20 and ch <= 0x7f and (kCharTraitsTable[ch - 0x20] & kOrdinaryMask) != 0;
}
inline bool isNonBlank(int ch)
{
return ch > 0x20 and ch <= 0x7f and (kCharTraitsTable[ch - 0x20] & kNonBlankMask) != 0;
}
inline bool isTextLead(int ch)
{
return ch >= 0x20 and ch <= 0x7f and (kCharTraitsTable[ch - 0x20] & kTextLeadMask) != 0;
}
inline bool isAnyPrint(int ch)
{
return ch == '\t' or
(ch >= 0x20 and ch <= 0x7f and (kCharTraitsTable[ch - 0x20] & kAnyPrintMask) != 0);
}
bool isUnquotedString(const char *s);
// --------------------------------------------------------------------
using DatablockIndex = std::map<std::string, std::size_t>;
// --------------------------------------------------------------------
// sac Parser, analogous to SAX Parser (simple api for xml)
class SacParser
{
public:
SacParser(std::istream &is, bool init = true);
virtual ~SacParser() {}
enum CIFToken
{
eCIFTokenUnknown,
eCIFTokenEOF,
eCIFTokenDATA,
eCIFTokenLOOP,
eCIFTokenGLOBAL,
eCIFTokenSAVE,
eCIFTokenSTOP,
eCIFTokenTag,
eCIFTokenValue,
};
static const char *kTokenName[];
enum CIFValueType
{
eCIFValueInt,
eCIFValueFloat,
eCIFValueNumeric,
eCIFValueString,
eCIFValueTextField,
eCIFValueInapplicable,
eCIFValueUnknown
};
static const char *kValueName[];
int getNextChar();
void retract();
int restart(int start);
CIFToken getNextToken();
void match(CIFToken token);
bool parseSingleDatablock(const std::string &datablock);
DatablockIndex indexDatablocks();
bool parseSingleDatablock(const std::string &datablock, const DatablockIndex &index);
void parseFile();
void parseGlobal();
void parseDataBlock();
virtual void parseSaveFrame();
void parseDictionary();
void error(const std::string &msg);
// production methods, these are pure virtual here
virtual void produceDatablock(const std::string &name) = 0;
virtual void produceCategory(const std::string &name) = 0;
virtual void produceRow() = 0;
virtual void produceItem(const std::string &category, const std::string &item, const std::string &value) = 0;
protected:
enum State
{
eStateStart,
eStateWhite,
eStateComment,
eStateQuestionMark,
eStateDot,
eStateQuotedString,
eStateQuotedStringQuote,
eStateUnquotedString,
eStateTag,
eStateTextField,
eStateFloat = 100,
eStateInt = 110,
eStateValue = 300,
eStateDATA,
eStateSAVE
};
std::istream &mData;
// Parser state
bool mValidate;
uint32_t mLineNr;
bool mBol;
CIFToken mLookahead;
std::string mTokenValue;
CIFValueType mTokenType;
std::stack<int> mBuffer;
};
// --------------------------------------------------------------------
class Parser : public SacParser
{
public:
Parser(std::istream &is, File &f, bool init = true);
virtual void produceDatablock(const std::string &name);
virtual void produceCategory(const std::string &name);
virtual void produceRow();
virtual void produceItem(const std::string &category, const std::string &item, const std::string &value);
protected:
File &mFile;
Datablock *mDataBlock;
Datablock::iterator mCat;
Row mRow;
};
// --------------------------------------------------------------------
class DictParser : public Parser
{
public:
DictParser(Validator &validator, std::istream &is);
~DictParser();
void loadDictionary();
private:
virtual void parseSaveFrame();
bool collectItemTypes();
void linkItems();
Validator &mValidator;
File mFile;
struct DictParserDataImpl *mImpl;
bool mCollectedItemTypes = false;
};
} // namespace cif
/*-
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2020 NKI/AVL, Netherlands Cancer Institute
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
#include <cif++/Cif++.hpp>
// duh.. https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86164
// #include <regex>
#include <boost/regex.hpp>
#include <set>
namespace cif
{
struct ValidateCategory;
class ValidatorFactory;
// --------------------------------------------------------------------
class ValidationError : public std::exception
{
public:
ValidationError(const std::string &msg);
ValidationError(const std::string &cat, const std::string &item,
const std::string &msg);
const char *what() const noexcept { return mMsg.c_str(); }
std::string mMsg;
};
// --------------------------------------------------------------------
enum class DDL_PrimitiveType
{
Char,
UChar,
Numb
};
DDL_PrimitiveType mapToPrimitiveType(std::string_view s);
struct ValidateType
{
std::string mName;
DDL_PrimitiveType mPrimitiveType;
// std::regex mRx;
boost::regex mRx;
bool operator<(const ValidateType &rhs) const
{
return icompare(mName, rhs.mName) < 0;
}
// compare values based on type
// int compare(const std::string& a, const std::string& b) const
// {
// return compare(a.c_str(), b.c_str());
// }
int compare(const char *a, const char *b) const;
};
struct ValidateItem
{
std::string mTag;
bool mMandatory;
const ValidateType *mType;
cif::iset mEnums;
std::string mDefault;
bool mDefaultIsNull;
ValidateCategory *mCategory = nullptr;
// ItemLinked is used for non-key links
struct ItemLinked
{
ValidateItem *mParent;
std::string mParentItem;
std::string mChildItem;
};
std::vector<ItemLinked> mLinked;
bool operator<(const ValidateItem &rhs) const
{
return icompare(mTag, rhs.mTag) < 0;
}
bool operator==(const ValidateItem &rhs) const
{
return iequals(mTag, rhs.mTag);
}
void operator()(std::string value) const;
};
struct ValidateCategory
{
std::string mName;
std::vector<std::string> mKeys;
cif::iset mGroups;
cif::iset mMandatoryFields;
std::set<ValidateItem> mItemValidators;
bool operator<(const ValidateCategory &rhs) const
{
return icompare(mName, rhs.mName) < 0;
}
void addItemValidator(ValidateItem &&v);
const ValidateItem *getValidatorForItem(std::string_view tag) const;
const std::set<ValidateItem> &itemValidators() const
{
return mItemValidators;
}
};
struct ValidateLink
{
int mLinkGroupID;
std::string mParentCategory;
std::vector<std::string> mParentKeys;
std::string mChildCategory;
std::vector<std::string> mChildKeys;
std::string mLinkGroupLabel;
};
// --------------------------------------------------------------------
class Validator
{
public:
Validator(std::string_view name, std::istream &is);
~Validator();
Validator(const Validator &rhs) = delete;
Validator &operator=(const Validator &rhs) = delete;
Validator(Validator &&rhs);
Validator &operator=(Validator &&rhs);
friend class DictParser;
friend class ValidatorFactory;
void addTypeValidator(ValidateType &&v);
const ValidateType *getValidatorForType(std::string_view typeCode) const;
void addCategoryValidator(ValidateCategory &&v);
const ValidateCategory *getValidatorForCategory(std::string_view category) const;
void addLinkValidator(ValidateLink &&v);
std::vector<const ValidateLink *> getLinksForParent(std::string_view category) const;
std::vector<const ValidateLink *> getLinksForChild(std::string_view category) const;
void reportError(const std::string &msg, bool fatal) const;
std::string dictName() const { return mName; }
void dictName(const std::string &name) { mName = name; }
std::string dictVersion() const { return mVersion; }
void dictVersion(const std::string &version) { mVersion = version; }
private:
// name is fully qualified here:
ValidateItem *getValidatorForItem(std::string_view name) const;
std::string mName;
std::string mVersion;
bool mStrict = false;
// std::set<uint32_t> mSubCategories;
std::set<ValidateType> mTypeValidators;
std::set<ValidateCategory> mCategoryValidators;
std::vector<ValidateLink> mLinkValidators;
};
// --------------------------------------------------------------------
class ValidatorFactory
{
public:
static ValidatorFactory &instance()
{
return sInstance;
}
const Validator &operator[](std::string_view dictionary);
private:
static ValidatorFactory sInstance;
ValidatorFactory();
std::mutex mMutex;
std::list<Validator> mValidators;
};
} // namespace cif
...@@ -26,18 +26,6 @@ ...@@ -26,18 +26,6 @@
#pragma once #pragma once
#include <filesystem> #include <cif++/utilities.hpp>
#include <forward_list> #include <cif++/cif/file.hpp>
#include <list> #include <cif++/cif/parser.hpp>
#include <map>
#include <scoped_allocator>
#include <string>
#include <cif++/CifUtils.hpp>
#include <cif++/v2/file.hpp>
namespace cif::v2
{
} // namespace cif::v2
...@@ -26,19 +26,18 @@ ...@@ -26,19 +26,18 @@
#pragma once #pragma once
#include <cif++/v2/forward_decl.hpp> #include <cif++/cif/forward_decl.hpp>
#include <cif++/v2/condition.hpp> #include <cif++/cif/condition.hpp>
#include <cif++/v2/iterator.hpp> #include <cif++/cif/iterator.hpp>
#include <cif++/v2/row.hpp> #include <cif++/cif/row.hpp>
#include <cif++/v2/validate.hpp> #include <cif++/cif/validate.hpp>
// TODO: implement all of: // TODO: implement all of:
// https://en.cppreference.com/w/cpp/named_req/Container // https://en.cppreference.com/w/cpp/named_req/Container
// https://en.cppreference.com/w/cpp/named_req/SequenceContainer // https://en.cppreference.com/w/cpp/named_req/SequenceContainer
// and more? // and more?
namespace cif::v2 namespace cif::v2
{ {
...@@ -323,7 +322,7 @@ class category ...@@ -323,7 +322,7 @@ class category
} }
// -------------------------------------------------------------------- // --------------------------------------------------------------------
bool has_children(row_handle r) const; bool has_children(row_handle r) const;
bool has_parents(row_handle r) const; bool has_parents(row_handle r) const;
...@@ -448,7 +447,7 @@ class category ...@@ -448,7 +447,7 @@ class category
{ {
if (ix >= m_columns.size()) if (ix >= m_columns.size())
throw std::out_of_range("column index is out of range"); throw std::out_of_range("column index is out of range");
return m_columns[ix].m_name; return m_columns[ix].m_name;
} }
...@@ -475,6 +474,23 @@ class category ...@@ -475,6 +474,23 @@ class category
return result; return result;
} }
// --------------------------------------------------------------------
std::vector<std::string> get_tag_order() const;
void write(std::ostream &os) const;
void write(std::ostream &os, const std::vector<std::string> &order);
private:
void write(std::ostream &os, const std::vector<uint16_t> &order, bool includeEmptyColumns) const;
public:
friend std::ostream &operator<<(std::ostream &os, const category &cat)
{
cat.write(os);
return os;
}
private: private:
void update_value(row *row, size_t column, std::string_view value, bool updateLinked, bool validate = true); void update_value(row *row, size_t column, std::string_view value, bool updateLinked, bool validate = true);
...@@ -631,6 +647,8 @@ class category ...@@ -631,6 +647,8 @@ class category
iterator insert_impl(const_iterator pos, row *n); iterator insert_impl(const_iterator pos, row *n);
iterator erase_impl(const_iterator pos); iterator erase_impl(const_iterator pos);
// --------------------------------------------------------------------
std::string m_name; std::string m_name;
std::vector<item_column> m_columns; std::vector<item_column> m_columns;
const validator *m_validator = nullptr; const validator *m_validator = nullptr;
...@@ -638,7 +656,7 @@ class category ...@@ -638,7 +656,7 @@ class category
std::vector<link> m_parent_links, m_child_links; std::vector<link> m_parent_links, m_child_links;
bool m_cascade = true; bool m_cascade = true;
uint32_t m_last_unique_num = 0; uint32_t m_last_unique_num = 0;
class category_index* m_index = nullptr; class category_index *m_index = nullptr;
row *m_head = nullptr, *m_tail = nullptr; row *m_head = nullptr, *m_tail = nullptr;
}; };
......
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
#include <iostream> #include <iostream>
#include <regex> #include <regex>
#include <cif++/v2/row.hpp> #include <cif++/cif/row.hpp>
namespace cif::v2 namespace cif::v2
{ {
......
/*-
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2022 NKI/AVL, Netherlands Cancer Institute
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
#include <cif++/cif/forward_decl.hpp>
#include <cif++/cif/category.hpp>
namespace cif::v2
{
// --------------------------------------------------------------------
class datablock : public std::list<category>
{
public:
datablock() = default;
datablock(std::string_view name)
: m_name(name)
{
}
datablock(const datablock &) = default;
datablock(datablock &&) = default;
datablock &operator=(const datablock &) = default;
datablock &operator=(datablock &&) = default;
// --------------------------------------------------------------------
const std::string &name() const { return m_name; }
void set_validator(const validator *v);
const validator *get_validator() const;
bool is_valid() const;
// --------------------------------------------------------------------
category &operator[](std::string_view name);
const category &operator[](std::string_view name) const;
category *get(std::string_view name);
const category *get(std::string_view name) const;
std::tuple<iterator, bool> emplace(std::string_view name);
std::vector<std::string> get_tag_order() const;
void write(std::ostream &os) const;
friend std::ostream &operator<<(std::ostream &os, const datablock &db)
{
db.write(os);
return os;
}
private:
std::string m_name;
const validator *m_validator = nullptr;
};
} // namespace cif::v2
\ No newline at end of file
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
#pragma once #pragma once
#include <cif++/v2/validate.hpp> #include <cif++/cif/validate.hpp>
namespace cif::v2 namespace cif::v2
{ {
......
...@@ -26,10 +26,10 @@ ...@@ -26,10 +26,10 @@
#pragma once #pragma once
#include <cif++/v2/forward_decl.hpp> #include <cif++/cif/forward_decl.hpp>
#include <cif++/v2/datablock.hpp> #include <cif++/cif/datablock.hpp>
#include <cif++/v2/parser.hpp> #include <cif++/cif/parser.hpp>
namespace cif::v2 namespace cif::v2
{ {
......
...@@ -34,14 +34,9 @@ ...@@ -34,14 +34,9 @@
#include <memory> #include <memory>
#include <optional> #include <optional>
#include <cif++/CifUtils.hpp> #include <cif++/utilities.hpp>
#include <cif++/v2/forward_decl.hpp> #include <cif++/cif/forward_decl.hpp>
namespace cif
{
extern int VERBOSE;
}
namespace cif::v2 namespace cif::v2
{ {
......
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
#pragma once #pragma once
#include <cif++/v2/row.hpp> #include <cif++/cif/row.hpp>
namespace cif::v2 namespace cif::v2
{ {
......
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
#pragma once #pragma once
#include <cif++/v2/row.hpp> #include <cif++/cif/row.hpp>
namespace cif::v2 namespace cif::v2
{ {
...@@ -87,12 +87,12 @@ class sac_parser ...@@ -87,12 +87,12 @@ class sac_parser
(ch >= 0x20 and ch <= 0x7f and (kCharTraitsTable[ch - 0x20] & kAnyPrintMask) != 0); (ch >= 0x20 and ch <= 0x7f and (kCharTraitsTable[ch - 0x20] & kAnyPrintMask) != 0);
} }
static bool is_unquoted_string(const char *s) static bool is_unquoted_string(std::string_view text)
{ {
auto ss = s; auto s = text.begin();
bool result = is_ordinary(*s++); bool result = is_ordinary(*s++);
while (result and *s != 0) while (result and s != text.end())
{ {
result = is_non_blank(*s); result = is_non_blank(*s);
++s; ++s;
...@@ -102,7 +102,7 @@ class sac_parser ...@@ -102,7 +102,7 @@ class sac_parser
if (result) if (result)
{ {
static const std::regex reservedRx(R"((^(?:data|save)|.*(?:loop|stop|global))_.+)", std::regex_constants::icase); static const std::regex reservedRx(R"((^(?:data|save)|.*(?:loop|stop|global))_.+)", std::regex_constants::icase);
result = not std::regex_match(ss, reservedRx); result = not std::regex_match(text.begin(), text.end(), reservedRx);
} }
return result; return result;
......
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
#pragma once #pragma once
#include <cif++/v2/item.hpp> #include <cif++/cif/item.hpp>
namespace cif::v2 namespace cif::v2
{ {
......
...@@ -33,7 +33,7 @@ ...@@ -33,7 +33,7 @@
// #include <regex> // #include <regex>
#include <boost/regex.hpp> #include <boost/regex.hpp>
#include <cif++/CifUtils.hpp> #include <cif++/utilities.hpp>
namespace cif::v2 namespace cif::v2
{ {
......
...@@ -34,8 +34,8 @@ ...@@ -34,8 +34,8 @@
#include <tuple> #include <tuple>
#include <vector> #include <vector>
#include <cif++/AtomType.hpp> #include <cif++/cif.hpp>
#include <cif++/Cif++.hpp> #include <cif++/structure/AtomType.hpp>
namespace mmcif namespace mmcif
{ {
...@@ -130,8 +130,8 @@ class Compound ...@@ -130,8 +130,8 @@ class Compound
friend class CCDCompoundFactoryImpl; friend class CCDCompoundFactoryImpl;
friend class CCP4CompoundFactoryImpl; friend class CCP4CompoundFactoryImpl;
Compound(cif::Datablock &db); Compound(cif::v2::datablock &db);
Compound(cif::Datablock &db, const std::string &id, const std::string &name, const std::string &type, const std::string &group); Compound(cif::v2::datablock &db, const std::string &id, const std::string &name, const std::string &type, const std::string &group);
std::string mID; std::string mID;
std::string mName; std::string mName;
......
...@@ -28,10 +28,10 @@ ...@@ -28,10 +28,10 @@
#include <numeric> #include <numeric>
#include <cif++/AtomType.hpp> #include <cif++/cif.hpp>
#include <cif++/Cif++.hpp> #include <cif++/structure/AtomType.hpp>
#include <cif++/Compound.hpp> #include <cif++/structure/Compound.hpp>
#include <cif++/Point.hpp> #include <cif++/point.hpp>
/* /*
To modify a structure, you will have to use actions. To modify a structure, you will have to use actions.
...@@ -63,7 +63,7 @@ class Atom ...@@ -63,7 +63,7 @@ class Atom
private: private:
struct AtomImpl : public std::enable_shared_from_this<AtomImpl> struct AtomImpl : public std::enable_shared_from_this<AtomImpl>
{ {
AtomImpl(cif::Datablock &db, const std::string &id, cif::Row row); AtomImpl(cif::v2::datablock &db, const std::string &id, cif::v2::row_handle row);
// constructor for a symmetry copy of an atom // constructor for a symmetry copy of an atom
AtomImpl(const AtomImpl &impl, const Point &loc, const std::string &sym_op); AtomImpl(const AtomImpl &impl, const Point &loc, const std::string &sym_op);
...@@ -85,7 +85,7 @@ class Atom ...@@ -85,7 +85,7 @@ class Atom
const std::string get_property(const std::string_view name) const; const std::string get_property(const std::string_view name) const;
void set_property(const std::string_view name, const std::string &value); void set_property(const std::string_view name, const std::string &value);
const cif::Datablock &mDb; const cif::v2::datablock &mDb;
std::string mID; std::string mID;
AtomType mType; AtomType mType;
...@@ -98,9 +98,9 @@ class Atom ...@@ -98,9 +98,9 @@ class Atom
Point mLocation; Point mLocation;
int mRefcount; int mRefcount;
cif::Row mRow; cif::v2::row_handle mRow;
mutable std::vector<std::tuple<std::string, cif::detail::ItemReference>> mCachedRefs; // mutable std::vector<std::tuple<std::string, cif::detail::ItemReference>> mCachedRefs;
mutable const Compound *mCompound = nullptr; mutable const Compound *mCompound = nullptr;
...@@ -123,7 +123,7 @@ class Atom ...@@ -123,7 +123,7 @@ class Atom
{ {
} }
Atom(cif::Datablock &db, cif::Row &row); Atom(cif::v2::datablock &db, cif::v2::row_handle &row);
// a special constructor to create symmetry copies // a special constructor to create symmetry copies
Atom(const Atom &rhs, const Point &symmmetry_location, const std::string &symmetry_operation); Atom(const Atom &rhs, const Point &symmmetry_location, const std::string &symmetry_operation);
...@@ -180,8 +180,8 @@ class Atom ...@@ -180,8 +180,8 @@ class Atom
void translateRotateAndTranslate(Point t1, Quaternion q, Point t2); void translateRotateAndTranslate(Point t1, Quaternion q, Point t2);
// for direct access to underlying data, be careful! // for direct access to underlying data, be careful!
const cif::Row getRow() const { return impl().mRow; } const cif::v2::row_handle getRow() const { return impl().mRow; }
const cif::Row getRowAniso() const; const cif::v2::row_handle getRowAniso() const;
bool isSymmetryCopy() const { return impl().mSymmetryCopy; } bool isSymmetryCopy() const { return impl().mSymmetryCopy; }
std::string symmetry() const { return impl().mSymmetryOperator; } std::string symmetry() const { return impl().mSymmetryOperator; }
...@@ -513,7 +513,7 @@ class Polymer : public std::vector<Monomer> ...@@ -513,7 +513,7 @@ class Polymer : public std::vector<Monomer>
Structure *mStructure; Structure *mStructure;
std::string mEntityID; std::string mEntityID;
std::string mAsymID; std::string mAsymID;
cif::RowSet mPolySeq; // cif::v2::row_handleSet mPolySeq;
}; };
// -------------------------------------------------------------------- // --------------------------------------------------------------------
...@@ -578,31 +578,31 @@ class Branch : public std::vector<Sugar> ...@@ -578,31 +578,31 @@ class Branch : public std::vector<Sugar>
// file is a reference to the data stored in e.g. the cif file. // file is a reference to the data stored in e.g. the cif file.
// This object is not copyable. // This object is not copyable.
class File : public cif::File class File : public cif::v2::file
{ {
public: public:
File() {} File() {}
File(const std::filesystem::path &path) // File(const std::filesystem::path &path)
{ // {
load(path); // load(path);
} // }
File(const char *data, size_t length) // File(const char *data, size_t length)
{ // {
load(data, length); // load(data, length);
} // }
File(const File &) = delete; File(const File &) = delete;
File &operator=(const File &) = delete; File &operator=(const File &) = delete;
void load(const std::filesystem::path &p) override; // void load(const std::filesystem::path &p) override;
void save(const std::filesystem::path &p) override; // void save(const std::filesystem::path &p) override;
using cif::File::load; // using cif::v2::file::load;
using cif::File::save; // using cif::v2::file::save;
cif::Datablock &data() { return front(); } cif::v2::datablock &data() { return front(); }
}; };
// -------------------------------------------------------------------- // --------------------------------------------------------------------
...@@ -622,12 +622,12 @@ inline bool operator&(StructureOpenOptions a, StructureOpenOptions b) ...@@ -622,12 +622,12 @@ inline bool operator&(StructureOpenOptions a, StructureOpenOptions b)
class Structure class Structure
{ {
public: public:
Structure(cif::File &p, size_t modelNr = 1, StructureOpenOptions options = {}) Structure(cif::v2::file &p, size_t modelNr = 1, StructureOpenOptions options = {})
: Structure(p.front(), modelNr, options) : Structure(p.front(), modelNr, options)
{ {
} }
Structure(cif::Datablock &db, size_t modelNr = 1, StructureOpenOptions options = {}); Structure(cif::v2::datablock &db, size_t modelNr = 1, StructureOpenOptions options = {});
Structure(Structure &&s) = default; Structure(Structure &&s) = default;
...@@ -756,12 +756,12 @@ class Structure ...@@ -756,12 +756,12 @@ class Structure
/// This method creates new atom records filled with info from the info. /// This method creates new atom records filled with info from the info.
/// ///
/// \param entity_id The entity ID of the new nonpoly /// \param entity_id The entity ID of the new nonpoly
/// \param atoms The array of sets of cif::item data containing the data for the atoms. /// \param atoms The array of sets of cif::v2::item data containing the data for the atoms.
/// \return The newly create asym ID /// \return The newly create asym ID
std::string createNonpoly(const std::string &entity_id, std::vector<std::vector<cif::Item>> &atom_info); std::string createNonpoly(const std::string &entity_id, std::vector<std::vector<cif::v2::item>> &atom_info);
/// \brief Create a new (sugar) branch with one first NAG containing atoms constructed from \a nag_atom_info /// \brief Create a new (sugar) branch with one first NAG containing atoms constructed from \a nag_atom_info
Branch &createBranch(std::vector<std::vector<cif::Item>> &nag_atom_info); Branch &createBranch(std::vector<std::vector<cif::v2::item>> &nag_atom_info);
/// \brief Extend an existing (sugar) branch identified by \a asymID with one sugar containing atoms constructed from \a atom_info /// \brief Extend an existing (sugar) branch identified by \a asymID with one sugar containing atoms constructed from \a atom_info
/// ///
...@@ -769,7 +769,7 @@ class Structure ...@@ -769,7 +769,7 @@ class Structure
/// \param atom_info Array containing the info for the atoms to construct for the new sugar /// \param atom_info Array containing the info for the atoms to construct for the new sugar
/// \param link_sugar The sugar to link to, note: this is the sugar number (1 based) /// \param link_sugar The sugar to link to, note: this is the sugar number (1 based)
/// \param link_atom The atom id of the atom linked in the sugar /// \param link_atom The atom id of the atom linked in the sugar
Branch &extendBranch(const std::string &asym_id, std::vector<std::vector<cif::Item>> &atom_info, Branch &extendBranch(const std::string &asym_id, std::vector<std::vector<cif::v2::item>> &atom_info,
int link_sugar, const std::string &link_atom); int link_sugar, const std::string &link_atom);
/// \brief Remove \a branch /// \brief Remove \a branch
...@@ -797,12 +797,12 @@ class Structure ...@@ -797,12 +797,12 @@ class Structure
void cleanupEmptyCategories(); void cleanupEmptyCategories();
/// \brief Direct access to underlying data /// \brief Direct access to underlying data
cif::Category &category(std::string_view name) const cif::v2::category &category(std::string_view name) const
{ {
return mDb[name]; return mDb[name];
} }
cif::Datablock &datablock() const cif::v2::datablock &datablock() const
{ {
return mDb; return mDb;
} }
...@@ -832,7 +832,7 @@ class Structure ...@@ -832,7 +832,7 @@ class Structure
void removeAtom(Atom &a, bool removeFromResidue); void removeAtom(Atom &a, bool removeFromResidue);
void removeSugar(Sugar &sugar); void removeSugar(Sugar &sugar);
cif::Datablock &mDb; cif::v2::datablock &mDb;
size_t mModelNr; size_t mModelNr;
AtomView mAtoms; AtomView mAtoms;
std::vector<size_t> mAtomIndex; std::vector<size_t> mAtomIndex;
......
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
#include <cstdint> #include <cstdint>
#include <array> #include <array>
#include <cif++/CifUtils.hpp> #include <cif++/utilities.hpp>
namespace mmcif namespace mmcif
{ {
......
...@@ -56,6 +56,8 @@ ...@@ -56,6 +56,8 @@
namespace cif namespace cif
{ {
extern int VERBOSE;
// the git 'build' number // the git 'build' number
std::string get_version_nr(); std::string get_version_nr();
// std::string get_version_date(); // std::string get_version_date();
......
...@@ -44,7 +44,7 @@ ...@@ -44,7 +44,7 @@
#include <cif++/Cif++.hpp> #include <cif++/Cif++.hpp>
#include <cif++/CifParser.hpp> #include <cif++/CifParser.hpp>
#include <cif++/CifUtils.hpp> #include <cif++/utilities.hpp>
#include <cif++/CifValidator.hpp> #include <cif++/CifValidator.hpp>
namespace fs = std::filesystem; namespace fs = std::filesystem;
......
/* Define to the name of this package. */
#cmakedefine PACKAGE_NAME "@PACKAGE_NAME@"
/* Define to the version of this package. */
#cmakedefine PACKAGE_VERSION "@PACKAGE_VERSION@"
/* Define the complete package string */
#cmakedefine PACKAGE_STRING "@PACKAGE_STRING@"
/* Using resources? */
#cmakedefine USE_RSRC @USE_RSRC@
/* src/Config.hpp.in. Generated from configure.ac by autoheader. */
/* define if the Boost library is available */
#undef HAVE_BOOST
/* define if the Boost::Date_Time library is available */
#undef HAVE_BOOST_DATE_TIME
/* define if the Boost::IOStreams library is available */
#undef HAVE_BOOST_IOSTREAMS
/* define if the Boost::Regex library is available */
#undef HAVE_BOOST_REGEX
/* define if the compiler supports basic C++17 syntax */
#undef HAVE_CXX17
/* Define to 1 if you have the <dlfcn.h> header file. */
#undef HAVE_DLFCN_H
/* Define to 1 if you have the `floor' function. */
#undef HAVE_FLOOR
/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H
/* Define to 1 if you have the `pow' function. */
#undef HAVE_POW
/* Define if you have POSIX threads libraries and header files. */
#undef HAVE_PTHREAD
/* Have PTHREAD_PRIO_INHERIT. */
#undef HAVE_PTHREAD_PRIO_INHERIT
/* Define to 1 if the system has the type `ptrdiff_t'. */
#undef HAVE_PTRDIFF_T
/* Define to 1 if you have the `rint' function. */
#undef HAVE_RINT
/* Define to 1 if you have the `sqrt' function. */
#undef HAVE_SQRT
/* Define to 1 if you have the <stdint.h> header file. */
#undef HAVE_STDINT_H
/* Define to 1 if you have the <stdlib.h> header file. */
#undef HAVE_STDLIB_H
/* Define to 1 if you have the `strchr' function. */
#undef HAVE_STRCHR
/* Define to 1 if you have the `strerror' function. */
#undef HAVE_STRERROR
/* Define to 1 if you have the <strings.h> header file. */
#undef HAVE_STRINGS_H
/* Define to 1 if you have the <string.h> header file. */
#undef HAVE_STRING_H
/* Define to 1 if you have the <sys/ioctl.h> header file. */
#undef HAVE_SYS_IOCTL_H
/* Define to 1 if you have the <sys/stat.h> header file. */
#undef HAVE_SYS_STAT_H
/* Define to 1 if you have the <sys/types.h> header file. */
#undef HAVE_SYS_TYPES_H
/* Define to 1 if you have the <termios.h> header file. */
#undef HAVE_TERMIOS_H
/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
/* Define to 1 if the system has the type `_Bool'. */
#undef HAVE__BOOL
/* Define to the sub-directory where libtool stores uninstalled libraries. */
#undef LT_OBJDIR
/* Define to the address where bug reports for this package should be sent. */
#undef PACKAGE_BUGREPORT
/* Define to the full name of this package. */
#undef PACKAGE_NAME
/* Define to the full name and version of this package. */
#undef PACKAGE_STRING
/* Define to the one symbol short name of this package. */
#undef PACKAGE_TARNAME
/* Define to the home page for this package. */
#undef PACKAGE_URL
/* Define to the version of this package. */
#undef PACKAGE_VERSION
/* Define to necessary symbol if this constant uses a non-standard name on
your system. */
#undef PTHREAD_CREATE_JOINABLE
/* Define to 1 if you have the ANSI C header files. */
#undef STDC_HEADERS
/* Use mrc to store resources */
#undef USE_RSRC
...@@ -24,8 +24,11 @@ ...@@ -24,8 +24,11 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#include <cif++/v2/category.hpp> #include <numeric>
#include <cif++/v2/datablock.hpp>
#include <cif++/cif/category.hpp>
#include <cif++/cif/datablock.hpp>
#include <cif++/cif/parser.hpp>
// TODO: Find out what the rules are exactly for linked items, the current implementation // TODO: Find out what the rules are exactly for linked items, the current implementation
// is inconsistent. It all depends whether a link is satified if a field taking part in the // is inconsistent. It all depends whether a link is satified if a field taking part in the
...@@ -34,6 +37,8 @@ ...@@ -34,6 +37,8 @@
namespace cif::v2 namespace cif::v2
{ {
const uint32_t kMaxLineLength = 132;
// -------------------------------------------------------------------- // --------------------------------------------------------------------
class row_comparator class row_comparator
...@@ -1526,7 +1531,7 @@ category::iterator category::insert_impl(const_iterator pos, row *n) ...@@ -1526,7 +1531,7 @@ category::iterator category::insert_impl(const_iterator pos, row *n)
// if (test != nullptr) // if (test != nullptr)
// { // {
// if (VERBOSE > 1) // if (VERBOSE > 1)
// std::cerr << "Not inserting new record in " << mName << " (duplicate Key)" << std::endl; // std::cerr << "Not inserting new record in " << m_name << " (duplicate Key)" << std::endl;
// result = test; // result = test;
// isNew = false; // isNew = false;
// } // }
...@@ -1612,4 +1617,262 @@ category::iterator category::erase_impl(const_iterator pos) ...@@ -1612,4 +1617,262 @@ category::iterator category::erase_impl(const_iterator pos)
// return iterator(*this, cur); // return iterator(*this, cur);
} }
namespace detail
{
size_t write_value(std::ostream &os, std::string_view value, size_t offset, size_t width)
{
if (value.find('\n') != std::string::npos or width == 0 or value.length() > 132) // write as text field
{
if (offset > 0)
os << std::endl;
os << ';';
char pc = 0;
for (auto ch : value)
{
if (pc == '\n' and ch == ';')
os << '\\';
os << ch;
pc = ch;
}
if (value.back() != '\n')
os << std::endl;
os << ';' << std::endl;
offset = 0;
}
else if (sac_parser::is_unquoted_string(value))
{
os << value;
if (value.length() < width)
{
os << std::string(width - value.length(), ' ');
offset += width;
}
else
{
os << ' ';
offset += value.length() + 1;
}
}
else
{
bool done = false;
for (char q : {'\'', '"'})
{
auto p = value.find(q); // see if we can use the quote character
while (p != std::string::npos and sac_parser::is_non_blank(value[p + 1]) and value[p + 1] != q)
p = value.find(q, p + 1);
if (p != std::string::npos)
continue;
os << q << value << q;
if (value.length() + 2 < width)
{
os << std::string(width - value.length() - 2, ' ');
offset += width;
}
else
{
os << ' ';
offset += value.length() + 1;
}
done = true;
break;
}
if (not done)
{
if (offset > 0)
os << std::endl;
os << ';' << value << std::endl
<< ';' << std::endl;
offset = 0;
}
}
return offset;
}
} // namespace detail
std::vector<std::string> category::get_tag_order() const
{
std::vector<std::string> result;
for (auto &c : m_columns)
result.push_back("_" + m_name + "." + c.m_name);
return result;
}
void category::write(std::ostream &os) const
{
std::vector<uint16_t> order(m_columns.size());
iota(order.begin(), order.end(), 0);
write(os, order, false);
}
void category::write(std::ostream &os, const std::vector<std::string> &columns)
{
// make sure all columns are present
for (auto &c : columns)
add_column(c);
std::vector<uint16_t> order;
order.reserve(m_columns.size());
for (auto &c : columns)
order.push_back(get_column_ix(c));
for (size_t i = 0; i < m_columns.size(); ++i)
{
if (std::find(order.begin(), order.end(), i) == order.end())
order.push_back(i);
}
write(os, order, true);
}
void category::write(std::ostream &os, const std::vector<uint16_t> &order, bool includeEmptyColumns) const
{
if (empty())
return;
// If the first Row has a next, we need a loop_
bool needLoop = (m_head->m_next != nullptr);
if (needLoop)
{
os << "loop_" << std::endl;
std::vector<size_t> columnWidths;
for (auto cix : order)
{
auto &col = m_columns[cix];
os << '_' << m_name << '.' << col.m_name << ' ' << std::endl;
columnWidths.push_back(2);
}
for (auto r = m_head; r != nullptr; r = r->m_next)
{
for (auto v = r->m_head; v != nullptr; v = v->m_next)
{
if (v->text().find('\n') == std::string_view::npos)
{
size_t l = v->text().length();
if (not sac_parser::is_unquoted_string(v->text()))
l += 2;
if (l > 132)
continue;
if (columnWidths[v->m_column_ix] < l + 1)
columnWidths[v->m_column_ix] = l + 1;
}
}
}
for (auto r = m_head; r != nullptr; r = r->m_next) // loop over rows
{
size_t offset = 0;
for (size_t cix : order)
{
size_t w = columnWidths[cix];
std::string_view s;
for (auto iv = r->m_head; iv != nullptr; iv = iv->m_next)
{
if (iv->m_column_ix == cix)
{
s = iv->text();
break;
}
}
if (s.empty())
s = "?";
size_t l = s.length();
if (not sac_parser::is_unquoted_string(s))
l += 2;
if (l < w)
l = w;
if (offset + l > 132 and offset > 0)
{
os << std::endl;
offset = 0;
}
offset = detail::write_value(os, s, offset, w);
if (offset > 132)
{
os << std::endl;
offset = 0;
}
}
if (offset > 0)
os << std::endl;
}
}
else
{
// first find the indent level
size_t l = 0;
for (auto &col : m_columns)
{
std::string tag = '_' + m_name + '.' + col.m_name;
if (l < tag.length())
l = tag.length();
}
l += 3;
for (size_t cix : order)
{
auto &col = m_columns[cix];
os << '_' << m_name << '.' << col.m_name << std::string(l - col.m_name.length() - m_name.length() - 2, ' ');
std::string_view s;
for (auto iv = m_head->m_head; iv != nullptr; iv = iv->m_next)
{
if (iv->m_column_ix == cix)
{
s = iv->text();
break;
}
}
if (s.empty())
s = "?";
size_t offset = l;
if (s.length() + l >= kMaxLineLength)
{
os << std::endl;
offset = 0;
}
if (detail::write_value(os, s, offset, 1) != 0)
os << std::endl;
}
}
os << "# " << std::endl;
}
} // namespace cif::v2 } // namespace cif::v2
\ No newline at end of file
...@@ -24,8 +24,8 @@ ...@@ -24,8 +24,8 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#include <cif++/v2/category.hpp> #include <cif++/cif/category.hpp>
#include <cif++/v2/condition.hpp> #include <cif++/cif/condition.hpp>
namespace cif::v2 namespace cif::v2
{ {
......
...@@ -24,174 +24,148 @@ ...@@ -24,174 +24,148 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#pragma once #include <cif++/cif/datablock.hpp>
#include <cif++/v2/forward_decl.hpp>
#include <cif++/v2/category.hpp>
namespace cif::v2 namespace cif::v2
{ {
// -------------------------------------------------------------------- void datablock::set_validator(const validator *v)
{
m_validator = v;
for (auto &cat : *this)
cat.set_validator(v, *this);
}
class datablock : public std::list<category> const validator *datablock::get_validator() const
{ {
public: return m_validator;
datablock() = default; }
datablock(std::string_view name) bool datablock::is_valid() const
: m_name(name) {
{ if (m_validator == nullptr)
} throw std::runtime_error("Validator not specified");
datablock(const datablock &) = default; bool result = true;
for (auto &cat : *this)
result = cat.is_valid() and result;
datablock(datablock &&) = default; return result;
}
datablock &operator=(const datablock &) = default; // --------------------------------------------------------------------
datablock &operator=(datablock &&) = default;
// -------------------------------------------------------------------- category &datablock::operator[](std::string_view name)
{
auto i = std::find_if(begin(), end(), [name](const category &c)
{ return iequals(c.name(), name); });
const std::string &name() const { return m_name; } if (i != end())
return *i;
void set_validator(const validator *v) emplace_back(name);
{ return back();
m_validator = v; }
for (auto &cat : *this) const category &datablock::operator[](std::string_view name) const
cat.set_validator(v, *this); {
} static const category s_empty;
auto i = std::find_if(begin(), end(), [name](const category &c)
{ return iequals(c.name(), name); });
return i == end() ? s_empty : *i;
}
const validator *get_validator() const category *datablock::get(std::string_view name)
{ {
return m_validator; auto i = std::find_if(begin(), end(), [name](const category &c)
} { return iequals(c.name(), name); });
return i == end() ? nullptr : &*i;
}
bool is_valid() const const category *datablock::get(std::string_view name) const
{ {
if (m_validator == nullptr) return const_cast<datablock *>(this)->get(name);
throw std::runtime_error("Validator not specified"); }
bool result = true;
for (auto &cat : *this)
result = cat.is_valid() and result;
return result;
}
// -------------------------------------------------------------------- std::tuple<datablock::iterator, bool> datablock::emplace(std::string_view name)
{
bool is_new = true;
category &operator[](std::string_view name) auto i = begin();
while (i != end())
{ {
auto i = std::find_if(begin(), end(), [name](const category &c) if (iequals(name, i->name()))
{ return iequals(c.name(), name); }); {
is_new = false;
if (i != end()) if (i != begin())
return *i; {
auto n = std::next(i);
splice(begin(), *this, i, n);
}
emplace_back(name); break;
return back(); }
}
const category &operator[](std::string_view name) const ++i;
{
static const category s_empty;
auto i = std::find_if(begin(), end(), [name](const category &c)
{ return iequals(c.name(), name); });
return i == end() ? s_empty : *i;
} }
category *get(std::string_view name) if (is_new)
{ {
auto i = std::find_if(begin(), end(), [name](const category &c) auto &c = emplace_front(name);
{ return iequals(c.name(), name); }); c.set_validator(m_validator, *this);
return i == end() ? nullptr : &*i;
} }
const category *get(std::string_view name) const return std::make_tuple(begin(), is_new);
}
std::vector<std::string> datablock::get_tag_order() const
{
std::vector<std::string> result;
for (auto &cat : *this)
{ {
return const_cast<datablock *>(this)->get(name); auto cto = cat.get_tag_order();
result.insert(result.end(), cto.begin(), cto.end());
} }
std::tuple<iterator, bool> emplace(std::string_view name) return result;
{ }
bool is_new = true;
auto i = begin(); void datablock::write(std::ostream &os) const
while (i != end()) {
{ os << "data_" << m_name << std::endl
if (iequals(name, i->name())) << "# " << std::endl;
{
is_new = false;
if (i != begin()) // mmcif support, sort of. First write the 'entry' Category
{ // and if it exists, _AND_ we have a Validator, write out the
auto n = std::next(i); // audit_conform record.
splice(begin(), *this, i, n);
}
break; for (auto &cat : *this)
} {
if (cat.name() != "entry")
continue;
++i; cat.write(os);
}
if (is_new) if (m_validator != nullptr)
{ {
auto &c = emplace_front(name); category auditConform("audit_conform");
c.set_validator(m_validator, *this); auditConform.emplace({
{"dict_name", m_validator->name()},
{"dict_version", m_validator->version()}});
auditConform.write(os);
} }
return std::make_tuple(begin(), is_new); break;
}
for (auto &cat : *this)
{
if (cat.name() != "entry" and cat.name() != "audit_conform")
cat.write(os);
} }
}
// void write(std::ostream &os) const } // namespace cif::cif
// { \ No newline at end of file
// // std::shared_lock lock(mLock);
// os << "data_" << m_name << std::endl
// << "# " << std::endl;
// // mmcif support, sort of. First write the 'entry' Category
// // and if it exists, _AND_ we have a Validator, write out the
// // audit_conform record.
// for (auto &cat : m_categories)
// {
// if (cat.name() != "entry")
// continue;
// cat.write(os);
// // if (mValidator != nullptr)
// // {
// // Category auditConform(*this, "audit_conform", nullptr);
// // auditConform.emplace({{"dict_name", mValidator->dictName()},
// // {"dict_version", mValidator->dictVersion()}});
// // auditConform.write(os);
// // }
// break;
// }
// for (auto &cat : m_categories)
// {
// if (cat.name() != "entry" and cat.name() != "audit_conform")
// cat.write(os);
// }
// }
// friend std::ostream &operator<<(std::ostream &os, const datablock &db)
// {
// db.write(os);
// return os;
// }
private:
std::string m_name;
const validator *m_validator = nullptr;
};
} // namespace cif::v2
\ No newline at end of file
...@@ -24,10 +24,10 @@ ...@@ -24,10 +24,10 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#include <cif++/v2/condition.hpp> #include <cif++/cif/condition.hpp>
#include <cif++/v2/dictionary_parser.hpp> #include <cif++/cif/dictionary_parser.hpp>
#include <cif++/v2/file.hpp> #include <cif++/cif/file.hpp>
#include <cif++/v2/parser.hpp> #include <cif++/cif/parser.hpp>
namespace cif::v2 namespace cif::v2
{ {
......
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#include <cif++/v2/row.hpp> #include <cif++/cif/row.hpp>
namespace cif::v2 namespace cif::v2
{ {
......
...@@ -30,11 +30,11 @@ ...@@ -30,11 +30,11 @@
#include <regex> #include <regex>
#include <stack> #include <stack>
#include <cif++/CifUtils.hpp> #include <cif++/utilities.hpp>
#include <cif++/v2/forward_decl.hpp> #include <cif++/cif/forward_decl.hpp>
#include <cif++/v2/parser.hpp> #include <cif++/cif/parser.hpp>
#include <cif++/v2/file.hpp> #include <cif++/cif/file.hpp>
namespace cif namespace cif
{ {
......
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#include <cif++/v2/category.hpp> #include <cif++/cif/category.hpp>
namespace cif::v2 namespace cif::v2
{ {
......
...@@ -30,10 +30,10 @@ ...@@ -30,10 +30,10 @@
#include <gzstream/gzstream.hpp> #include <gzstream/gzstream.hpp>
#include <cif++/v2/dictionary_parser.hpp> #include <cif++/cif/dictionary_parser.hpp>
#include <cif++/v2/validate.hpp> #include <cif++/cif/validate.hpp>
#include <cif++/CifUtils.hpp> #include <cif++/utilities.hpp>
namespace cif namespace cif
{ {
......
...@@ -34,7 +34,7 @@ ...@@ -34,7 +34,7 @@
#include <boost/numeric/ublas/matrix.hpp> #include <boost/numeric/ublas/matrix.hpp>
#include <cif++/AtomType.hpp> #include <cif++/AtomType.hpp>
#include <cif++/CifUtils.hpp> #include <cif++/utilities.hpp>
#include <cif++/Compound.hpp> #include <cif++/Compound.hpp>
#include <cif++/PDB2Cif.hpp> #include <cif++/PDB2Cif.hpp>
#include <cif++/PDB2CifRemark3.hpp> #include <cif++/PDB2CifRemark3.hpp>
......
...@@ -32,7 +32,7 @@ ...@@ -32,7 +32,7 @@
#include <cif++/AtomType.hpp> #include <cif++/AtomType.hpp>
#include <cif++/Compound.hpp> #include <cif++/Compound.hpp>
#include <cif++/PDB2CifRemark3.hpp> #include <cif++/PDB2CifRemark3.hpp>
#include <cif++/CifUtils.hpp> #include <cif++/utilities.hpp>
using cif::Datablock; using cif::Datablock;
using cif::Category; using cif::Category;
......
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
#include <random> #include <random>
#include <valarray> #include <valarray>
#include <cif++/Point.hpp> #include <cif++/point.hpp>
namespace mmcif namespace mmcif
{ {
......
...@@ -26,8 +26,8 @@ ...@@ -26,8 +26,8 @@
#include <cmath> #include <cmath>
#include <cif++/AtomType.hpp> #include <cif++/cif.hpp>
#include <cif++/Cif++.hpp> #include <cif++/structure/AtomType.hpp>
namespace mmcif namespace mmcif
{ {
......
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
#include <cif++/BondMap.hpp> #include <cif++/BondMap.hpp>
#include <cif++/Cif++.hpp> #include <cif++/Cif++.hpp>
#include <cif++/CifUtils.hpp> #include <cif++/utilities.hpp>
#include <cif++/Compound.hpp> #include <cif++/Compound.hpp>
namespace mmcif namespace mmcif
......
...@@ -34,7 +34,7 @@ ...@@ -34,7 +34,7 @@
#include <cif++/Cif++.hpp> #include <cif++/Cif++.hpp>
#include <cif++/CifParser.hpp> #include <cif++/CifParser.hpp>
#include <cif++/CifUtils.hpp> #include <cif++/utilities.hpp>
#include <cif++/Compound.hpp> #include <cif++/Compound.hpp>
#include <cif++/Point.hpp> #include <cif++/Point.hpp>
......
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#include <cif++/Structure.hpp> #include <cif++/structure/Structure.hpp>
#include <filesystem> #include <filesystem>
#include <fstream> #include <fstream>
...@@ -39,9 +39,9 @@ ...@@ -39,9 +39,9 @@
#include <boost/format.hpp> #include <boost/format.hpp>
#endif #endif
#include <cif++/Cif2PDB.hpp> #include <cif++/pdb/Cif2PDB.hpp>
#include <cif++/CifParser.hpp> #include <cif++/cif/parser.hpp>
#include <cif++/PDB2Cif.hpp> #include <cif++/pdb/PDB2Cif.hpp>
// #include <cif++/AtomShape.hpp> // #include <cif++/AtomShape.hpp>
namespace fs = std::filesystem; namespace fs = std::filesystem;
......
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
#include <mutex> #include <mutex>
#include <cif++/Symmetry.hpp> #include <cif++/Symmetry.hpp>
#include <cif++/CifUtils.hpp> #include <cif++/utilities.hpp>
#include "SymOpTable_data.hpp" #include "SymOpTable_data.hpp"
......
...@@ -27,7 +27,9 @@ ...@@ -27,7 +27,9 @@
#include <atomic> #include <atomic>
#include <cassert> #include <cassert>
#include <cmath> #include <cmath>
#include <cstring>
#include <fstream> #include <fstream>
#include <functional>
#include <iomanip> #include <iomanip>
#include <iostream> #include <iostream>
#include <map> #include <map>
...@@ -43,7 +45,7 @@ ...@@ -43,7 +45,7 @@
#include <termios.h> #include <termios.h>
#endif #endif
#include <cif++/CifUtils.hpp> #include <cif++/utilities.hpp>
#include "revision.hpp" #include "revision.hpp"
...@@ -54,7 +56,7 @@ namespace fs = std::filesystem; ...@@ -54,7 +56,7 @@ namespace fs = std::filesystem;
namespace cif namespace cif
{ {
extern int VERBOSE; int VERBOSE = 0;
// -------------------------------------------------------------------- // --------------------------------------------------------------------
......
...@@ -29,8 +29,8 @@ ...@@ -29,8 +29,8 @@
#include <stdexcept> #include <stdexcept>
#include <cif++/Cif++.hpp> #include <cif++/cif.hpp>
#include <cif++/Structure.hpp> #include <cif++/structure/Structure.hpp>
// -------------------------------------------------------------------- // --------------------------------------------------------------------
......
...@@ -29,9 +29,8 @@ ...@@ -29,9 +29,8 @@
#include <stdexcept> #include <stdexcept>
#include <cif++/Cif++.hpp> #include <cif++/cif.hpp>
#include <cif++/Structure.hpp> #include <cif++/structure/Structure.hpp>
#include <cif++/CifValidator.hpp>
// -------------------------------------------------------------------- // --------------------------------------------------------------------
......
...@@ -31,12 +31,12 @@ ...@@ -31,12 +31,12 @@
// #include <cif++/DistanceMap.hpp> // #include <cif++/DistanceMap.hpp>
// #include <cif++/BondMap.hpp> // #include <cif++/BondMap.hpp>
#include <cif++/Cif++-v2.hpp> #include <cif++/cif.hpp>
// #include <cif++/CifValidator.hpp> // #include <cif++/CifValidator.hpp>
// #include <cif++/CifParser.hpp> // #include <cif++/CifParser.hpp>
#include <cif++/v2/parser.hpp> #include <cif++/cif/parser.hpp>
#include <cif++/v2/dictionary_parser.hpp> #include <cif++/cif/dictionary_parser.hpp>
namespace tt = boost::test_tools; namespace tt = boost::test_tools;
...@@ -2176,4 +2176,8 @@ BOOST_AUTO_TEST_CASE(replace_all_test) ...@@ -2176,4 +2176,8 @@ BOOST_AUTO_TEST_CASE(replace_all_test)
cif::replace_all(s, ",", ", "); cif::replace_all(s, ",", ", ");
BOOST_CHECK_EQUAL(s, "aap, noot, mies"); BOOST_CHECK_EQUAL(s, "aap, noot, mies");
}
\ No newline at end of file cif::replace_all(s, ", ", ", ");
BOOST_CHECK_EQUAL(s, "aap, noot, mies");
}
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