Remove atdna and fmt

This commit is contained in:
2025-01-02 01:17:06 -08:00
parent fa346ace47
commit f7c1cd8f59
35 changed files with 104 additions and 4658 deletions

View File

@@ -1,152 +0,0 @@
#pragma once
/* BIG FAT WARNING!!!
*
* The type-structure of this file is expected to remain consistent for 'atdna'
* Any changes to the types or namespacing must be reflected in 'atdna/main.cpp'
*/
#include <memory>
#include <string>
#include <vector>
#include <sys/types.h>
#include "athena/DNAOp.hpp"
#include "athena/Global.hpp"
#include "athena/IStreamReader.hpp"
#include "athena/IStreamWriter.hpp"
using namespace std::literals;
namespace athena::io {
/**
* @brief Base DNA class used against 'atdna'
* @tparam DNAE Default-endianness for contained DNA values
*
* Athena bundles a build-tool called 'atdna'. This tool functions
* just like the 'clang' compiler, except it emits a full .cpp implementation
* with all read/write calls necessary to marshal the DNA structure to/from
* a streamed medium
*/
template <Endian DNAE>
struct DNA {
/**
* @brief Designated byte-order used for serializing fields
*/
static constexpr Endian DNAEndian = DNAE;
/**
* @brief Template type signaling atdna to capture the value where it's used
* @tparam T The type of the value. Can be any numeric type or atVec* type
* @tparam VE Endianness of the value
*/
template <typename T, Endian VE = DNAE>
using Value = T;
/**
* @brief Template type wrapping std::vector and signaling atdna to manipulate it where it's used
* @tparam T The type of contained elements. Can be any numeric type, atVec* type, or another DNA subclass
* @tparam cntVar C++ expression wrapped in DNA_COUNT macro to determine number of elements for vector
* @tparam VE Endianness of the contained values
*/
template <typename T, size_t cntVar, Endian VE = DNAE>
using Vector = std::vector<T>;
/**
* @brief Template type wrapping std::unique_ptr<atUint8[]> and signaling atdna to read a
* raw byte-buffer where it's used
* @tparam sizeVar C++ expression wrapped in DNA_COUNT macro to determine number of bytes for buffer
*/
template <size_t sizeVar>
using Buffer = std::unique_ptr<atUint8[]>;
/**
* @brief Template type wrapping std::string and signaling atdna to read string data where it's used
* @tparam sizeVar C++ expression wrapped in DNA_COUNT macro to determine number of characters for string
* -1 literal indicates null-terminated string
*/
template <atInt32 sizeVar = -1>
using String = std::string;
/**
* @brief Template type wrapping std::wstring and signaling atdna to read wstring data where it's used
* @tparam sizeVar C++ expression wrapped in DNA_COUNT macro to determine number of characters for wstring
* -1 literal indicates null-terminated wstring
*/
template <atInt32 sizeVar = -1, Endian VE = DNAE>
using WString = std::wstring;
/**
* @brief Meta Template signaling atdna to insert a stream seek where it's used
* @tparam offset C++ expression wrapped in DNA_COUNT macro to determine number of bytes to seek
* @tparam direction SeekOrigin to seek relative to
*/
template <off_t offset, SeekOrigin direction>
struct Seek {};
/**
* @brief Meta Template signaling atdna to insert an aligning stream seek where it's used
* @tparam align Number of bytes to align to
*/
template <size_t align>
struct Align {};
/**
* @brief Meta Template preventing atdna from emitting read/write implementations
*/
struct Delete {};
/* Bring fundamental operations into DNA subclasses for easier per-op overrides */
using Read = athena::io::Read<PropType::None>;
using Write = athena::io::Write<PropType::None>;
using BinarySize = athena::io::BinarySize<PropType::None>;
using PropCount = athena::io::PropCount<PropType::None>;
using ReadYaml = athena::io::ReadYaml<PropType::None>;
using WriteYaml = athena::io::WriteYaml<PropType::None>;
};
/**
* @brief Virtual DNA wrapper for subclasses that utilize virtual method calls
* @tparam DNAE Default-endianness for contained DNA values
*
* Typically, static template-based DNA resolution is sufficient; however, formats
* with a tree of variously-typed data structures would benefit from having a vtable.
*
* Note: It's not recommended to implement these directly. Instead, use the AT_DECL_DNA or
* AT_DECL_EXPLCIT_DNA macro in the subclasses. Specializing the Enumerate method
* is the proper way to override individual I/O operations. Owners of the virtualized
* subclass will typically use a unique_ptr to reference the data; specializing their own
* Enumerate methods as such:
*
* template <> void MySubclass::Enumerate<Read>(typename Read::StreamT& r)
* { (Do stuff with `r`) }
*/
template <Endian DNAE>
struct DNAV : DNA<DNAE> {
virtual ~DNAV() = default;
virtual void read(athena::io::IStreamReader& r) = 0;
virtual void write(athena::io::IStreamWriter& w) const = 0;
virtual void binarySize(size_t& s) const = 0;
virtual std::string_view DNATypeV() const = 0;
};
template <Endian DNAE>
struct DNAVYaml : DNAV<DNAE> {
virtual ~DNAVYaml() = default;
void read(athena::io::IStreamReader& r) override = 0;
void write(athena::io::IStreamWriter& w) const override = 0;
void binarySize(size_t& s) const override = 0;
virtual void read(athena::io::YAMLDocReader& r) = 0;
virtual void write(athena::io::YAMLDocWriter& w) const = 0;
};
/** Macro to supply count variable to atdna and mute it for other compilers */
#ifdef __clang__
#define AT_DNA_COUNT(...) sizeof(__VA_ARGS__)
#else
#define AT_DNA_COUNT(...) 0
#endif
} // namespace athena::io

File diff suppressed because it is too large Load Diff

View File

@@ -1,121 +0,0 @@
#pragma once
#include <string>
#include "athena/DNA.hpp"
#include "athena/FileReader.hpp"
#include "athena/FileWriter.hpp"
#include "athena/YAMLDocReader.hpp"
#include "athena/YAMLDocWriter.hpp"
namespace athena::io {
template <class T>
std::string_view __GetDNAName(const T& dna) {
if constexpr (__IsDNAVRecord_v<T>) {
return dna.DNATypeV();
} else {
return dna.DNAType();
}
}
template <class T>
std::string ToYAMLString(const T& dna) {
YAMLDocWriter docWriter(__GetDNAName(dna));
std::string res;
yaml_emitter_set_output(docWriter.getEmitter(), (yaml_write_handler_t*)YAMLStdStringWriter, &res);
yaml_emitter_set_unicode(docWriter.getEmitter(), true);
yaml_emitter_set_width(docWriter.getEmitter(), -1);
dna.write(docWriter);
if (!docWriter.finish(nullptr))
return std::string();
return res;
}
template <class T>
bool FromYAMLString(T& dna, std::string_view str) {
YAMLStdStringViewReaderState reader(str);
YAMLDocReader docReader;
yaml_parser_set_input(docReader.getParser(), (yaml_read_handler_t*)YAMLStdStringReader, &reader);
if (!docReader.parse(nullptr))
return false;
dna.read(docReader);
return true;
}
template <class DNASubtype>
bool ValidateFromYAMLString(std::string_view str) {
YAMLStdStringViewReaderState reader(str);
YAMLDocReader docReader;
yaml_parser_set_input(docReader.getParser(), (yaml_read_handler_t*)YAMLStdStringReader, &reader);
bool retval = docReader.ValidateClassType(DNASubtype::DNAType());
return retval;
}
template <class T>
bool ToYAMLStream(const T& dna, athena::io::IStreamWriter& fout) {
YAMLDocWriter docWriter(__GetDNAName(dna));
yaml_emitter_set_unicode(docWriter.getEmitter(), true);
yaml_emitter_set_width(docWriter.getEmitter(), -1);
dna.write(docWriter);
return docWriter.finish(&fout);
}
template <class T>
bool ToYAMLStream(const T& dna, athena::io::IStreamWriter& fout, void (T::*fn)(YAMLDocWriter& out) const) {
YAMLDocWriter docWriter(__GetDNAName(dna));
yaml_emitter_set_unicode(docWriter.getEmitter(), true);
yaml_emitter_set_width(docWriter.getEmitter(), -1);
(dna.*fn)(docWriter);
return docWriter.finish(&fout);
}
template <class T>
bool FromYAMLStream(T& dna, athena::io::IStreamReader& fin) {
YAMLDocReader docReader;
if (!docReader.parse(&fin))
return false;
dna.read(docReader);
return true;
}
template <class T>
bool FromYAMLStream(T& dna, athena::io::IStreamReader& fin, void (T::*fn)(YAMLDocReader& in)) {
YAMLDocReader docReader;
if (!docReader.parse(&fin))
return false;
(dna.*fn)(docReader);
return true;
}
template <class T, typename NameT>
bool MergeToYAMLFile(const T& dna, const NameT& filename) {
athena::io::FileReader r(filename);
YAMLDocWriter docWriter(__GetDNAName(dna), r.isOpen() ? &r : nullptr);
r.close();
dna.write(docWriter);
athena::io::FileWriter w(filename);
if (!w.isOpen())
return false;
return docWriter.finish(&w);
}
template <class DNASubtype>
bool ValidateFromYAMLStream(athena::io::IStreamReader& fin) {
YAMLDocReader reader;
atUint64 pos = fin.position();
yaml_parser_set_input(reader.getParser(), (yaml_read_handler_t*)YAMLAthenaReader, &fin);
bool retval = reader.ValidateClassType(DNASubtype::DNAType());
fin.seek(pos, athena::SeekOrigin::Begin);
return retval;
}
} // namespace athena::io

View File

@@ -3,7 +3,7 @@
#include <ostream>
#include "athena/Types.hpp"
#include <fmt/format.h>
#include <format>
#ifdef _MSC_VER
#pragma warning(disable : 4996)
@@ -17,11 +17,11 @@
#include <sys/stat.h>
#if !defined(S_ISREG) && defined(S_IFMT) && defined(S_IFREG)
#define S_ISREG(m) (((m)&S_IFMT) == S_IFREG)
#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
#endif
#if !defined(S_ISDIR) && defined(S_IFMT) && defined(S_IFDIR)
#define S_ISDIR(m) (((m)&S_IFMT) == S_IFDIR)
#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
#endif
#if !defined(S_ISLNK)
@@ -118,27 +118,10 @@ enum class SeekOrigin { Begin, Current, End };
enum class Endian { Little, Big };
namespace io {
template <Endian DNAE>
struct DNA;
template <Endian DNAE>
struct DNAV;
template <class T>
using __IsDNARecord = std::disjunction<std::is_base_of<DNA<Endian::Big>, T>, std::is_base_of<DNA<Endian::Little>, T>>;
template <class T>
constexpr bool __IsDNARecord_v = __IsDNARecord<T>::value;
template <class T>
using __IsDNAVRecord =
std::disjunction<std::is_base_of<DNAV<Endian::Big>, T>, std::is_base_of<DNAV<Endian::Little>, T>>;
template <class T>
constexpr bool __IsDNAVRecord_v = __IsDNAVRecord<T>::value;
} // namespace io
} // namespace athena
typedef void (*atEXCEPTION_HANDLER)(athena::error::Level level, const char* /*file*/, const char*, int /*line*/,
fmt::string_view fmt, fmt::format_args args);
std::string_view fmt, std::format_args args);
atEXCEPTION_HANDLER atGetExceptionHandler();
/**
@@ -150,54 +133,47 @@ void atSetExceptionHandler(atEXCEPTION_HANDLER func);
std::ostream& operator<<(std::ostream& os, const athena::SeekOrigin& origin);
std::ostream& operator<<(std::ostream& os, const athena::Endian& endian);
template <typename First, typename... Rest>
constexpr auto __FIRST_ARG__(First first, Rest...) { return first; }
template <typename S, typename... Args>
auto __make_args_checked__(const S& format_str, Args&&... args) {
return fmt::make_args_checked<Args...>(format_str, std::forward<Args>(args)...);
}
#ifndef NDEBUG
#define atDebug(...) \
#define atDebug(fmt, ...) \
do { \
atEXCEPTION_HANDLER __handler = atGetExceptionHandler(); \
if (__handler) \
__handler(athena::error::Level::Message, __FILE__, AT_PRETTY_FUNCTION, __LINE__, __FIRST_ARG__(__VA_ARGS__), \
__make_args_checked__(__VA_ARGS__)); \
__handler(athena::error::Level::Message, __FILE__, AT_PRETTY_FUNCTION, __LINE__, fmt, \
std::make_format_args(__VA_ARGS__)); \
} while (0)
#else
#define atDebug(...)
#endif
#define atMessage(...) \
#define atMessage(fmt, ...) \
do { \
atEXCEPTION_HANDLER __handler = atGetExceptionHandler(); \
if (__handler) \
__handler(athena::error::Level::Message, __FILE__, AT_PRETTY_FUNCTION, __LINE__, __FIRST_ARG__(__VA_ARGS__), \
__make_args_checked__(__VA_ARGS__)); \
__handler(athena::error::Level::Message, __FILE__, AT_PRETTY_FUNCTION, __LINE__, fmt, \
std::make_format_args(__VA_ARGS__)); \
} while (0)
#define atWarning(...) \
#define atWarning(fmt, ...) \
do { \
atEXCEPTION_HANDLER __handler = atGetExceptionHandler(); \
if (__handler) { \
__handler(athena::error::Level::Warning, __FILE__, AT_PRETTY_FUNCTION, __LINE__, __FIRST_ARG__(__VA_ARGS__), \
__make_args_checked__(__VA_ARGS__)); \
__handler(athena::error::Level::Warning, __FILE__, AT_PRETTY_FUNCTION, __LINE__, fmt, \
std::make_format_args(__VA_ARGS__)); \
} \
} while (0)
#define atError(...) \
#define atError(fmt, ...) \
do { \
atEXCEPTION_HANDLER __handler = atGetExceptionHandler(); \
if (__handler) \
__handler(athena::error::Level::Error, __FILE__, AT_PRETTY_FUNCTION, __LINE__, __FIRST_ARG__(__VA_ARGS__), \
__make_args_checked__(__VA_ARGS__)); \
__handler(athena::error::Level::Error, __FILE__, AT_PRETTY_FUNCTION, __LINE__, fmt, \
std::make_format_args(__VA_ARGS__)); \
} while (0)
#define atFatal(...) \
#define atFatal(fmt, ...) \
do { \
atEXCEPTION_HANDLER __handler = atGetExceptionHandler(); \
if (__handler) \
__handler(athena::error::Level::Fatal, __FILE__, AT_PRETTY_FUNCTION, __LINE__, __FIRST_ARG__(__VA_ARGS__), \
__make_args_checked__(__VA_ARGS__)); \
__handler(athena::error::Level::Fatal, __FILE__, AT_PRETTY_FUNCTION, __LINE__, fmt, \
std::make_format_args(__VA_ARGS__)); \
} while (0)

View File

@@ -661,7 +661,7 @@ public:
utf8proc_int32_t wc;
utf8proc_ssize_t len = utf8proc_iterate(buf, -1, &wc);
if (len < 0) {
atWarning(FMT_STRING("invalid UTF-8 character while decoding"));
atWarning("invalid UTF-8 character while decoding");
return;
}
buf += len;
@@ -675,7 +675,7 @@ public:
if (*buf) {
utf8proc_ssize_t len = utf8proc_iterate(buf, -1, &wc);
if (len < 0) {
atWarning(FMT_STRING("invalid UTF-8 character while decoding"));
atWarning("invalid UTF-8 character while decoding");
return;
}
buf += len;
@@ -709,7 +709,7 @@ public:
utf8proc_int32_t wc;
utf8proc_ssize_t len = utf8proc_iterate(buf, -1, &wc);
if (len < 0) {
atWarning(FMT_STRING("invalid UTF-8 character while decoding"));
atWarning("invalid UTF-8 character while decoding");
return;
}
buf += len;
@@ -723,7 +723,7 @@ public:
if (*buf) {
utf8proc_ssize_t len = utf8proc_iterate(buf, -1, &wc);
if (len < 0) {
atWarning(FMT_STRING("invalid UTF-8 character while decoding"));
atWarning("invalid UTF-8 character while decoding");
return;
}
buf += len;
@@ -758,7 +758,7 @@ public:
utf8proc_int32_t wc;
utf8proc_ssize_t len = utf8proc_iterate(buf, -1, &wc);
if (len < 0) {
atWarning(FMT_STRING("invalid UTF-8 character while decoding"));
atWarning("invalid UTF-8 character while decoding");
return;
}
buf += len;
@@ -772,7 +772,7 @@ public:
if (*buf) {
utf8proc_ssize_t len = utf8proc_iterate(buf, -1, &wc);
if (len < 0) {
atWarning(FMT_STRING("invalid UTF-8 character while decoding"));
atWarning("invalid UTF-8 character while decoding");
return;
}
buf += len;

View File

@@ -61,12 +61,6 @@ public:
RecordRAII enterSubRecord(std::string_view name = {});
template <class T>
void enumerate(std::string_view name, T& record, std::enable_if_t<__IsDNARecord_v<T>>* = nullptr) {
if (auto rec = enterSubRecord(name))
record.read(*this);
}
class VectorRAII {
friend class YAMLDocReader;
YAMLDocReader* m_r = nullptr;

View File

@@ -47,12 +47,6 @@ public:
RecordRAII enterSubRecord(std::string_view name = {});
template <class T>
void enumerate(std::string_view name, T& record, std::enable_if_t<__IsDNARecord_v<T>>* = nullptr) {
if (auto rec = enterSubRecord(name))
record.write(*this);
}
class VectorRAII {
friend class YAMLDocWriter;
YAMLDocWriter* m_w = nullptr;