Bin2Cpp
All checks were successful
Bin2CPP / Build & Test Debug with ./ConanProfiles/clang (Unity Build: ON) (push) Successful in 1m44s
Bin2CPP / Build & Test Debug with ./ConanProfiles/clang (Unity Build: OFF) (push) Successful in 1m45s
Bin2CPP / Build & Test Debug with ./ConanProfiles/clangd (Unity Build: OFF) (push) Successful in 48s
Bin2CPP / Build & Test Debug with ./ConanProfiles/clangd (Unity Build: ON) (push) Successful in 49s
Bin2CPP / Build & Test Debug with ./ConanProfiles/clangd_asan (Unity Build: OFF) (push) Successful in 1m6s
Bin2CPP / Build & Test Debug with ./ConanProfiles/clangd_asan (Unity Build: ON) (push) Successful in 1m5s
Bin2CPP / Build & Test RelWithDebInfo with ./ConanProfiles/clang (Unity Build: OFF) (push) Successful in 1m28s
Bin2CPP / Build & Test RelWithDebInfo with ./ConanProfiles/clang (Unity Build: ON) (push) Successful in 1m28s
Bin2CPP / Build & Test RelWithDebInfo with ./ConanProfiles/clangd (Unity Build: OFF) (push) Successful in 1m8s
Bin2CPP / Build & Test RelWithDebInfo with ./ConanProfiles/clangd (Unity Build: ON) (push) Successful in 1m7s
Bin2CPP / Build & Test RelWithDebInfo with ./ConanProfiles/clangd_asan (Unity Build: OFF) (push) Successful in 1m24s
Bin2CPP / Build & Test RelWithDebInfo with ./ConanProfiles/clangd_asan (Unity Build: ON) (push) Successful in 1m22s
Bin2CPP / Build & Test Release with ./ConanProfiles/clang (Unity Build: OFF) (push) Successful in 38s
Bin2CPP / Build & Test Release with ./ConanProfiles/clang (Unity Build: ON) (push) Successful in 34s
Bin2CPP / Build & Test Release with ./ConanProfiles/clangd (Unity Build: OFF) (push) Successful in 31s
Bin2CPP / Build & Test Release with ./ConanProfiles/clangd (Unity Build: ON) (push) Successful in 30s
Bin2CPP / Build & Test Release with ./ConanProfiles/clangd_asan (Unity Build: OFF) (push) Successful in 43s
Bin2CPP / Build & Test Release with ./ConanProfiles/clangd_asan (Unity Build: ON) (push) Successful in 44s
Bin2CPP / Clang Format Checks (push) Successful in 9s
All checks were successful
Bin2CPP / Build & Test Debug with ./ConanProfiles/clang (Unity Build: ON) (push) Successful in 1m44s
Bin2CPP / Build & Test Debug with ./ConanProfiles/clang (Unity Build: OFF) (push) Successful in 1m45s
Bin2CPP / Build & Test Debug with ./ConanProfiles/clangd (Unity Build: OFF) (push) Successful in 48s
Bin2CPP / Build & Test Debug with ./ConanProfiles/clangd (Unity Build: ON) (push) Successful in 49s
Bin2CPP / Build & Test Debug with ./ConanProfiles/clangd_asan (Unity Build: OFF) (push) Successful in 1m6s
Bin2CPP / Build & Test Debug with ./ConanProfiles/clangd_asan (Unity Build: ON) (push) Successful in 1m5s
Bin2CPP / Build & Test RelWithDebInfo with ./ConanProfiles/clang (Unity Build: OFF) (push) Successful in 1m28s
Bin2CPP / Build & Test RelWithDebInfo with ./ConanProfiles/clang (Unity Build: ON) (push) Successful in 1m28s
Bin2CPP / Build & Test RelWithDebInfo with ./ConanProfiles/clangd (Unity Build: OFF) (push) Successful in 1m8s
Bin2CPP / Build & Test RelWithDebInfo with ./ConanProfiles/clangd (Unity Build: ON) (push) Successful in 1m7s
Bin2CPP / Build & Test RelWithDebInfo with ./ConanProfiles/clangd_asan (Unity Build: OFF) (push) Successful in 1m24s
Bin2CPP / Build & Test RelWithDebInfo with ./ConanProfiles/clangd_asan (Unity Build: ON) (push) Successful in 1m22s
Bin2CPP / Build & Test Release with ./ConanProfiles/clang (Unity Build: OFF) (push) Successful in 38s
Bin2CPP / Build & Test Release with ./ConanProfiles/clang (Unity Build: ON) (push) Successful in 34s
Bin2CPP / Build & Test Release with ./ConanProfiles/clangd (Unity Build: OFF) (push) Successful in 31s
Bin2CPP / Build & Test Release with ./ConanProfiles/clangd (Unity Build: ON) (push) Successful in 30s
Bin2CPP / Build & Test Release with ./ConanProfiles/clangd_asan (Unity Build: OFF) (push) Successful in 43s
Bin2CPP / Build & Test Release with ./ConanProfiles/clangd_asan (Unity Build: ON) (push) Successful in 44s
Bin2CPP / Clang Format Checks (push) Successful in 9s
This commit is contained in:
@@ -1,4 +1,62 @@
|
||||
int main([[maybe_unused]] int argc, [[maybe_unused]] char** argv)
|
||||
#include <Generator.hpp>
|
||||
#include <Log.hpp>
|
||||
|
||||
#include <CLI/CLI.hpp>
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
Bin2CPP::Singleton<Bin2CPP::Log>::Lifetime loggerLifetime;
|
||||
|
||||
CLI::App app {"Bin2CPP allows you to generate a C++ header containing the binary content of an input file"};
|
||||
argv = app.ensure_utf8(argv);
|
||||
|
||||
std::string input;
|
||||
app.add_option("-f,--input", input, "The input file")->required();
|
||||
std::string output;
|
||||
app.add_option("-o,--output", output, "The output file")->required();
|
||||
std::optional<std::string> arrayType;
|
||||
app.add_option("--arrayType", arrayType, "The type of the array");
|
||||
std::optional<std::string> arrayInclude;
|
||||
app.add_option("--arrayInclude", arrayInclude, "Include for the array type");
|
||||
std::optional<std::string> arrayName;
|
||||
app.add_option("--arrayName", arrayName, "The array name");
|
||||
std::optional<std::string> customNamespace;
|
||||
app.add_option("--namespace", customNamespace, "The namespace");
|
||||
|
||||
CLI11_PARSE(app, argc, argv);
|
||||
|
||||
Bin2CPP::Generator generator(input);
|
||||
if (arrayType)
|
||||
{
|
||||
generator.SetMapping(Bin2CPP::MappingKey::ARRAY_TYPE, arrayType.value());
|
||||
}
|
||||
if (arrayInclude)
|
||||
{
|
||||
generator.SetMapping(Bin2CPP::MappingKey::ARRAY_TYPE_INCLUDE, arrayInclude.value());
|
||||
}
|
||||
if (arrayName)
|
||||
{
|
||||
generator.SetMapping(Bin2CPP::MappingKey::ARRAY_NAME, arrayName.value());
|
||||
}
|
||||
if (customNamespace)
|
||||
{
|
||||
generator.SetMapping(Bin2CPP::MappingKey::NAMESPACE, customNamespace.value());
|
||||
}
|
||||
|
||||
if (generator.Generate())
|
||||
{
|
||||
std::ofstream out(output);
|
||||
if (!out)
|
||||
{
|
||||
BIN2CPP_LOG_ERROR("Failed to open '{}'", output);
|
||||
return 1;
|
||||
}
|
||||
|
||||
out << generator.Get();
|
||||
out.close();
|
||||
}
|
||||
|
||||
BIN2CPP_LOG_INFO("'{}' Generated !", output);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -36,9 +36,9 @@ target_link_libraries(${PROJECT_NAME}
|
||||
Bin2CPPCompileAndLinkFlags
|
||||
PUBLIC
|
||||
$<IF:$<BOOL:${ASAN}>,mimalloc-asan,mimalloc-static>
|
||||
EASTL::EASTL
|
||||
quill::quill
|
||||
$<$<CONFIG:Debug,RelWithDebInfo>:cpptrace::cpptrace>)
|
||||
$<$<CONFIG:Debug,RelWithDebInfo>:cpptrace::cpptrace>
|
||||
magic_enum::magic_enum)
|
||||
|
||||
target_compile_definitions(${PROJECT_NAME}
|
||||
PUBLIC
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
/**
|
||||
* Auto-generated header from: {{FILENAME}}
|
||||
* Generated by Bin2CPP
|
||||
*
|
||||
* DO NOT TOUCH
|
||||
*/
|
||||
#ifndef {{GUARD_NAME}}
|
||||
#define {{GUARD_NAME}}
|
||||
#include {{ARRAY_TYPE_INCLUDE}}
|
||||
#include <cstddef>
|
||||
|
||||
namespace {{NAMESPACE}} {
|
||||
|
||||
inline constexpr {{ARRAY_TYPE}}<std::byte, {{ARRAY_SIZE}}> {{ARRAY_NAME}} = {
|
||||
{{DATA}}
|
||||
};
|
||||
|
||||
} // namespace {{NAMESPACE}}
|
||||
|
||||
#endif // {{GUARD_NAME}}
|
||||
@@ -6,7 +6,275 @@
|
||||
*********************************************************************/
|
||||
#include <Generator.hpp>
|
||||
|
||||
#include <Assert.hpp>
|
||||
#include <GeneratedTemplate.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
#include <regex>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
namespace Bin2CPP
|
||||
{
|
||||
Generator::Generator(const std::string_view p_inputFile):
|
||||
m_inputFile(p_inputFile)
|
||||
{
|
||||
}
|
||||
|
||||
/****************************************************************************************/
|
||||
|
||||
void Generator::SetMapping(const MappingKey p_key, const std::string_view p_value)
|
||||
{
|
||||
const std::optional<std::size_t> index = magic_enum::enum_index(p_key);
|
||||
BIN2CPP_CRITICAL_ASSERT(index.has_value(), "Incorrect mapping key! Got {}", magic_enum::enum_integer(p_key));
|
||||
|
||||
m_mappingTable[index.value()] = p_value;
|
||||
}
|
||||
|
||||
/****************************************************************************************/
|
||||
|
||||
bool Generator::Generate()
|
||||
{
|
||||
if (!ComputeMappings())
|
||||
{
|
||||
BIN2CPP_LOG_ERROR("Invalid mappings! Can't generate file!");
|
||||
return false;
|
||||
}
|
||||
|
||||
m_result = g_generatedTemplate;
|
||||
|
||||
for (std::uint32_t i = 0; i < m_mappingTable.size(); ++i)
|
||||
{
|
||||
const std::string KEY = magic_enum::enum_name(magic_enum::enum_value<MappingKey>(i)).data();
|
||||
const std::string& VALUE = m_mappingTable[i];
|
||||
|
||||
const std::string pattern = "\\{\\{" + KEY + "\\}\\}";
|
||||
std::regex placeholderRegex(pattern);
|
||||
m_result = std::regex_replace(m_result, placeholderRegex, VALUE);
|
||||
}
|
||||
|
||||
return Validate();
|
||||
}
|
||||
|
||||
/****************************************************************************************/
|
||||
|
||||
std::string_view Generator::Get() const
|
||||
{
|
||||
return m_result;
|
||||
}
|
||||
|
||||
/****************************************************************************************/
|
||||
|
||||
bool Generator::ComputeMappings()
|
||||
{
|
||||
std::filesystem::path file {m_inputFile.data()};
|
||||
if (!std::filesystem::exists(file))
|
||||
{
|
||||
BIN2CPP_LOG_ERROR("File '{}' does not exists!", m_inputFile);
|
||||
return false;
|
||||
}
|
||||
if (std::filesystem::is_directory(file))
|
||||
{
|
||||
BIN2CPP_LOG_ERROR("'{}' is not a file!", m_inputFile);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!ComputeFilename())
|
||||
{
|
||||
BIN2CPP_LOG_ERROR("Failed to compute filename");
|
||||
return false;
|
||||
}
|
||||
if (!ComputeGuardName())
|
||||
{
|
||||
BIN2CPP_LOG_ERROR("Failed to compute GuardName");
|
||||
return false;
|
||||
}
|
||||
if (!ComputeArrayTypeInclude())
|
||||
{
|
||||
BIN2CPP_LOG_ERROR("Failed to compute ArrayTypeInclude");
|
||||
return false;
|
||||
}
|
||||
if (!ComputeArrayType())
|
||||
{
|
||||
BIN2CPP_LOG_ERROR("Failed to compute ArrayType");
|
||||
return false;
|
||||
}
|
||||
if (!ComputeArrayName())
|
||||
{
|
||||
BIN2CPP_LOG_ERROR("Failed to compute ArrayName");
|
||||
return false;
|
||||
}
|
||||
|
||||
std::ifstream in {m_inputFile.data(), std::ios::binary};
|
||||
if (!in)
|
||||
{
|
||||
BIN2CPP_LOG_ERROR("Failed to open '{}'", m_inputFile);
|
||||
return false;
|
||||
}
|
||||
in.seekg(0, std::ios::end);
|
||||
const size_t fileSize = static_cast<size_t>(in.tellg());
|
||||
in.seekg(0, std::ios::beg);
|
||||
|
||||
std::vector<std::byte> data(fileSize);
|
||||
in.read(std::bit_cast<char*>(data.data()), fileSize);
|
||||
|
||||
if (!ComputeArraySize(data))
|
||||
{
|
||||
BIN2CPP_LOG_ERROR("Failed to compute ArraySize");
|
||||
return false;
|
||||
}
|
||||
if (!ComputeData(data))
|
||||
{
|
||||
BIN2CPP_LOG_ERROR("Failed to compute Data");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/****************************************************************************************/
|
||||
|
||||
bool Generator::ComputeFilename()
|
||||
{
|
||||
std::filesystem::path file {m_inputFile.data()};
|
||||
m_mappingTable[magic_enum::enum_index(MappingKey::FILENAME).value()] = file.filename().string().c_str();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/****************************************************************************************/
|
||||
|
||||
bool Generator::ComputeGuardName()
|
||||
{
|
||||
std::filesystem::path file {m_inputFile.data()};
|
||||
std::string guardName = file.filename().string();
|
||||
|
||||
std::transform(guardName.begin(),
|
||||
guardName.end(),
|
||||
guardName.begin(),
|
||||
[](const char c)
|
||||
{
|
||||
if (!std::isalnum(c))
|
||||
{
|
||||
return static_cast<int>('_');
|
||||
}
|
||||
else
|
||||
{
|
||||
return std::toupper(c);
|
||||
}
|
||||
});
|
||||
m_mappingTable[magic_enum::enum_index(MappingKey::GUARD_NAME).value()] = std::format("{}_HPP", guardName);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/****************************************************************************************/
|
||||
|
||||
bool Generator::ComputeArrayTypeInclude()
|
||||
{
|
||||
std::string& value = m_mappingTable[magic_enum::enum_index(MappingKey::ARRAY_TYPE_INCLUDE).value()];
|
||||
if (value.empty())
|
||||
{
|
||||
value = "<array>";
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/****************************************************************************************/
|
||||
|
||||
bool Generator::ComputeArrayType()
|
||||
{
|
||||
std::string& value = m_mappingTable[magic_enum::enum_index(MappingKey::ARRAY_TYPE).value()];
|
||||
if (value.empty())
|
||||
{
|
||||
value = "std::array";
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/****************************************************************************************/
|
||||
|
||||
bool Generator::ComputeArrayName()
|
||||
{
|
||||
std::string& value = m_mappingTable[magic_enum::enum_index(MappingKey::ARRAY_NAME).value()];
|
||||
if (value.empty())
|
||||
{
|
||||
std::filesystem::path file {m_inputFile.data()};
|
||||
value = std::format("g_{}", file.filename().string());
|
||||
|
||||
std::transform(value.begin(),
|
||||
value.end(),
|
||||
value.begin(),
|
||||
[](const char c)
|
||||
{
|
||||
if (!std::isalnum(c))
|
||||
{
|
||||
return static_cast<int>('_');
|
||||
}
|
||||
else
|
||||
{
|
||||
return static_cast<int>(c);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/****************************************************************************************/
|
||||
|
||||
bool Generator::ComputeArraySize(const std::span<std::byte> p_data)
|
||||
{
|
||||
m_mappingTable[magic_enum::enum_index(MappingKey::ARRAY_SIZE).value()] = std::to_string(p_data.size());
|
||||
return true;
|
||||
}
|
||||
|
||||
/****************************************************************************************/
|
||||
|
||||
bool Generator::ComputeData(const std::span<std::byte> p_data)
|
||||
{
|
||||
std::string& value = m_mappingTable[magic_enum::enum_index(MappingKey::DATA).value()];
|
||||
value.clear();
|
||||
|
||||
constexpr std::size_t bytesPerLine = 5;
|
||||
constexpr std::string_view linePrefix = "\n ";
|
||||
|
||||
for (std::size_t i = 0; i < p_data.size(); ++i)
|
||||
{
|
||||
if (i > 0 && i % bytesPerLine == 0)
|
||||
{
|
||||
value.append(linePrefix.data(), linePrefix.size());
|
||||
}
|
||||
|
||||
const std::string element = std::format("std::byte{{0x{:02X}}}", std::to_integer<std::uint8_t>(p_data[i]));
|
||||
value.append(element.data(), element.size());
|
||||
|
||||
if (i + 1 < p_data.size())
|
||||
{
|
||||
value.append(", ");
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/****************************************************************************************/
|
||||
|
||||
bool Generator::Validate()
|
||||
{
|
||||
std::regex unreplacedRegex(R"(\{\{[A-Z_]+\}\})");
|
||||
std::smatch match;
|
||||
|
||||
if (std::regex_search(m_result, match, unreplacedRegex))
|
||||
{
|
||||
BIN2CPP_LOG_ERROR("Warning: Unreplaced placeholder found: {}", match.str());
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
} // namespace Bin2CPP
|
||||
|
||||
@@ -1,87 +0,0 @@
|
||||
/*********************************************************************
|
||||
* \file EASTLFormatters.hpp
|
||||
*
|
||||
* \author Romain BOULLARD
|
||||
* \date February 2026
|
||||
*********************************************************************/
|
||||
#ifndef BIN2CPP_EASTLFORMATTERS_HPP
|
||||
#define BIN2CPP_EASTLFORMATTERS_HPP
|
||||
#include <quill/DeferredFormatCodec.h>
|
||||
|
||||
#include <format>
|
||||
|
||||
#include <EASTL/string.h>
|
||||
#include <EASTL/string_view.h>
|
||||
|
||||
// STRING
|
||||
|
||||
template<>
|
||||
struct std::formatter<eastl::string>
|
||||
{
|
||||
constexpr auto parse(std::format_parse_context& ctx)
|
||||
{
|
||||
return ctx.begin();
|
||||
}
|
||||
|
||||
template<typename FormatContext>
|
||||
auto format(const eastl::string& p_string, FormatContext& ctx) const
|
||||
{
|
||||
return std::format_to(ctx.out(), "{}", p_string.c_str());
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct fmtquill::formatter<eastl::string>
|
||||
{
|
||||
constexpr auto parse(format_parse_context& ctx)
|
||||
{
|
||||
return ctx.begin();
|
||||
}
|
||||
|
||||
auto format(const eastl::string& p_string, format_context& ctx) const
|
||||
{
|
||||
return fmtquill::format_to(ctx.out(), "{}", p_string.c_str());
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct quill::Codec<eastl::string>: quill::DeferredFormatCodec<eastl::string>
|
||||
{
|
||||
};
|
||||
|
||||
// STRING_VIEW
|
||||
|
||||
template<>
|
||||
struct std::formatter<eastl::string_view>
|
||||
{
|
||||
constexpr auto parse(std::format_parse_context& ctx)
|
||||
{
|
||||
return ctx.begin();
|
||||
}
|
||||
|
||||
template<typename FormatContext>
|
||||
auto format(const eastl::string_view& p_stringView, FormatContext& ctx) const
|
||||
{
|
||||
return std::format_to(ctx.out(), "{}", p_stringView.data());
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct fmtquill::formatter<eastl::string_view>
|
||||
{
|
||||
constexpr auto parse(format_parse_context& ctx)
|
||||
{
|
||||
return ctx.begin();
|
||||
}
|
||||
|
||||
auto format(const eastl::string_view& p_stringView, format_context& ctx) const
|
||||
{
|
||||
return fmtquill::format_to(ctx.out(), "{}", p_stringView.data());
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct quill::Codec<eastl::string_view>: quill::DeferredFormatCodec<eastl::string_view>
|
||||
{
|
||||
};
|
||||
#endif
|
||||
36
Bin2CPP/Sources/Bin2CPPLib/Include/GeneratedTemplate.hpp
Normal file
36
Bin2CPP/Sources/Bin2CPPLib/Include/GeneratedTemplate.hpp
Normal file
@@ -0,0 +1,36 @@
|
||||
/*********************************************************************
|
||||
* \file GeneratedTemplate.hpp
|
||||
*
|
||||
* \author Romain BOULLARD
|
||||
* \date March 2026
|
||||
*********************************************************************/
|
||||
#ifndef BIN2CPP_GENERATED_TEMPLATE_HPP
|
||||
#define BIN2CPP_GENERATED_TEMPLATE_HPP
|
||||
#include <string_view>
|
||||
|
||||
namespace Bin2CPP
|
||||
{
|
||||
constexpr std::string_view g_generatedTemplate = R"(/**
|
||||
* Auto-generated header from: {{FILENAME}}
|
||||
* Generated by Bin2CPP
|
||||
*
|
||||
* DO NOT TOUCH
|
||||
*/
|
||||
#ifndef {{GUARD_NAME}}
|
||||
#define {{GUARD_NAME}}
|
||||
#include {{ARRAY_TYPE_INCLUDE}}
|
||||
#include <cstddef>
|
||||
|
||||
namespace {{NAMESPACE}}
|
||||
{
|
||||
inline constexpr {{ARRAY_TYPE}}<std::byte, {{ARRAY_SIZE}}> {{ARRAY_NAME}} = {
|
||||
{{DATA}}
|
||||
};
|
||||
|
||||
} // namespace {{NAMESPACE}}
|
||||
|
||||
#endif // {{GUARD_NAME}}
|
||||
)";
|
||||
} // namespace Bin2CPP
|
||||
|
||||
#endif
|
||||
@@ -6,9 +6,152 @@
|
||||
*********************************************************************/
|
||||
#ifndef BIN2CPP_GENERATOR_HPP
|
||||
#define BIN2CPP_GENERATOR_HPP
|
||||
#include <magic_enum/magic_enum.hpp>
|
||||
|
||||
#include <array>
|
||||
#include <span>
|
||||
#include <string>
|
||||
|
||||
namespace Bin2CPP
|
||||
{
|
||||
enum class MappingKey
|
||||
{
|
||||
FILENAME,
|
||||
GUARD_NAME,
|
||||
NAMESPACE,
|
||||
ARRAY_TYPE_INCLUDE,
|
||||
ARRAY_TYPE,
|
||||
ARRAY_SIZE,
|
||||
ARRAY_NAME,
|
||||
DATA
|
||||
};
|
||||
|
||||
class Generator
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* \param p_inputFile the Input file
|
||||
*/
|
||||
Generator(const std::string_view p_inputFile);
|
||||
|
||||
Generator(const Generator& p_generator) = default;
|
||||
Generator(Generator&& p_generator) = default;
|
||||
|
||||
/**
|
||||
* Set a mapping
|
||||
*
|
||||
*/
|
||||
void SetMapping(const MappingKey p_key, const std::string_view p_value);
|
||||
|
||||
/**
|
||||
* Generate
|
||||
*
|
||||
* \return True if successful, false otherwise
|
||||
*/
|
||||
[[nodiscard]]
|
||||
bool Generate();
|
||||
|
||||
/**
|
||||
* Get
|
||||
*
|
||||
*/
|
||||
[[nodiscard]]
|
||||
std::string_view Get() const;
|
||||
|
||||
~Generator() = default;
|
||||
|
||||
Generator& operator=(const Generator& p_generator) = default;
|
||||
Generator& operator=(Generator&& p_generator) = default;
|
||||
|
||||
private:
|
||||
/**
|
||||
* Compute the mappings
|
||||
*
|
||||
* \return True if all mappings have valid values, false otherwise
|
||||
*/
|
||||
[[nodiscard]]
|
||||
bool ComputeMappings();
|
||||
|
||||
/**
|
||||
* Compute the filename mapping
|
||||
*
|
||||
* \return True if success, false otherwise
|
||||
*/
|
||||
[[nodiscard]]
|
||||
bool ComputeFilename();
|
||||
|
||||
/**
|
||||
* Compute the guardName mapping
|
||||
*
|
||||
* \return True if success, false otherwise
|
||||
*/
|
||||
[[nodiscard]]
|
||||
bool ComputeGuardName();
|
||||
|
||||
/**
|
||||
* Compute the arrayTypeInclude mapping
|
||||
*
|
||||
* \return True if success, false otherwise
|
||||
*/
|
||||
[[nodiscard]]
|
||||
bool ComputeArrayTypeInclude();
|
||||
|
||||
/**
|
||||
* Compute the arrayType mapping
|
||||
*
|
||||
* \return True if success, false otherwise
|
||||
*/
|
||||
[[nodiscard]]
|
||||
bool ComputeArrayType();
|
||||
|
||||
/**
|
||||
* Compute the arrayName mapping
|
||||
*
|
||||
* \return True if success, false otherwise
|
||||
*/
|
||||
[[nodiscard]]
|
||||
bool ComputeArrayName();
|
||||
|
||||
/**
|
||||
* Compute the arraySize mapping
|
||||
*
|
||||
* \return True if success, false otherwise
|
||||
*/
|
||||
[[nodiscard]]
|
||||
bool ComputeArraySize(const std::span<std::byte> p_data);
|
||||
|
||||
/**
|
||||
* Compute the data mapping
|
||||
*
|
||||
* \return True if success, false otherwise
|
||||
*/
|
||||
[[nodiscard]]
|
||||
bool ComputeData(const std::span<std::byte> p_data);
|
||||
|
||||
/**
|
||||
* Validate generated is correct (no remaining tags)
|
||||
*
|
||||
* \return True if valid, false otherwise
|
||||
*/
|
||||
[[nodiscard]]
|
||||
bool Validate();
|
||||
|
||||
/**
|
||||
* The mapping table
|
||||
*/
|
||||
std::array<std::string, magic_enum::enum_count<MappingKey>()> m_mappingTable;
|
||||
|
||||
/**
|
||||
* The input file
|
||||
*/
|
||||
std::string m_inputFile;
|
||||
|
||||
/**
|
||||
* The result
|
||||
*/
|
||||
std::string m_result;
|
||||
};
|
||||
} // namespace Bin2CPP
|
||||
#endif
|
||||
|
||||
@@ -6,10 +6,9 @@
|
||||
*********************************************************************/
|
||||
#ifndef BIN2CPP_LOG_HPP
|
||||
#define BIN2CPP_LOG_HPP
|
||||
#include <EASTLFormatters.hpp>
|
||||
#include <Singleton.hpp>
|
||||
|
||||
#include <EASTL/array.h>
|
||||
#include <array>
|
||||
|
||||
#ifdef BIN2CPP_WINDOWS
|
||||
#pragma warning(disable: 4702)
|
||||
@@ -56,7 +55,7 @@ class Log
|
||||
/*
|
||||
* The sinks
|
||||
*/
|
||||
eastl::array<std::shared_ptr<quill::Sink>, 1> m_sinks;
|
||||
std::array<std::shared_ptr<quill::Sink>, 1> m_sinks;
|
||||
};
|
||||
} // namespace Bin2CPP
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
*********************************************************************/
|
||||
#ifndef BIN2CPP_SINGLETON_HPP
|
||||
#define BIN2CPP_SINGLETON_HPP
|
||||
#include <EASTL/optional.h>
|
||||
#include <optional>
|
||||
|
||||
namespace Bin2CPP
|
||||
{
|
||||
@@ -98,7 +98,7 @@ class Singleton
|
||||
/**
|
||||
* The singleton.
|
||||
*/
|
||||
inline static eastl::optional<TYPE> ms_instance;
|
||||
inline static std::optional<TYPE> ms_instance;
|
||||
};
|
||||
} // namespace Bin2CPP
|
||||
#endif
|
||||
|
||||
@@ -17,4 +17,123 @@ class GeneratorFixture: public ::testing::Test
|
||||
protected:
|
||||
Singleton<Log>::Lifetime m_lifetime;
|
||||
};
|
||||
|
||||
/****************************************************************************************/
|
||||
|
||||
TEST_F(GeneratorFixture, GenerateDefault)
|
||||
{
|
||||
Generator generator("Fixture/toto.txt");
|
||||
EXPECT_TRUE(generator.Generate());
|
||||
|
||||
constexpr std::string_view expectedResult = R"(/**
|
||||
* Auto-generated header from: toto.txt
|
||||
* Generated by Bin2CPP
|
||||
*
|
||||
* DO NOT TOUCH
|
||||
*/
|
||||
#ifndef TOTO_TXT_HPP
|
||||
#define TOTO_TXT_HPP
|
||||
#include <array>
|
||||
#include <cstddef>
|
||||
|
||||
namespace
|
||||
{
|
||||
inline constexpr std::array<std::byte, 11> g_toto_txt = {
|
||||
std::byte{0x48}, std::byte{0x65}, std::byte{0x6C}, std::byte{0x6C}, std::byte{0x6F},
|
||||
std::byte{0x20}, std::byte{0x57}, std::byte{0x6F}, std::byte{0x72}, std::byte{0x6C},
|
||||
std::byte{0x64}
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif // TOTO_TXT_HPP
|
||||
)";
|
||||
EXPECT_STREQ(expectedResult.data(), generator.Get().data());
|
||||
}
|
||||
|
||||
/****************************************************************************************/
|
||||
|
||||
TEST_F(GeneratorFixture, GenerateNamespace)
|
||||
{
|
||||
Generator generator("Fixture/toto.txt");
|
||||
generator.SetMapping(MappingKey::NAMESPACE, "Test");
|
||||
EXPECT_TRUE(generator.Generate());
|
||||
|
||||
constexpr std::string_view expectedResult = R"(/**
|
||||
* Auto-generated header from: toto.txt
|
||||
* Generated by Bin2CPP
|
||||
*
|
||||
* DO NOT TOUCH
|
||||
*/
|
||||
#ifndef TOTO_TXT_HPP
|
||||
#define TOTO_TXT_HPP
|
||||
#include <array>
|
||||
#include <cstddef>
|
||||
|
||||
namespace Test
|
||||
{
|
||||
inline constexpr std::array<std::byte, 11> g_toto_txt = {
|
||||
std::byte{0x48}, std::byte{0x65}, std::byte{0x6C}, std::byte{0x6C}, std::byte{0x6F},
|
||||
std::byte{0x20}, std::byte{0x57}, std::byte{0x6F}, std::byte{0x72}, std::byte{0x6C},
|
||||
std::byte{0x64}
|
||||
};
|
||||
|
||||
} // namespace Test
|
||||
|
||||
#endif // TOTO_TXT_HPP
|
||||
)";
|
||||
EXPECT_STREQ(expectedResult.data(), generator.Get().data());
|
||||
}
|
||||
|
||||
/****************************************************************************************/
|
||||
|
||||
TEST_F(GeneratorFixture, GenerateCustomArray)
|
||||
{
|
||||
Generator generator("Fixture/toto.txt");
|
||||
generator.SetMapping(MappingKey::ARRAY_TYPE, "eastl::array");
|
||||
generator.SetMapping(MappingKey::ARRAY_TYPE_INCLUDE, "<EASTL/array.h>");
|
||||
generator.SetMapping(MappingKey::ARRAY_NAME, "g_myArray");
|
||||
EXPECT_TRUE(generator.Generate());
|
||||
|
||||
constexpr std::string_view expectedResult = R"(/**
|
||||
* Auto-generated header from: toto.txt
|
||||
* Generated by Bin2CPP
|
||||
*
|
||||
* DO NOT TOUCH
|
||||
*/
|
||||
#ifndef TOTO_TXT_HPP
|
||||
#define TOTO_TXT_HPP
|
||||
#include <EASTL/array.h>
|
||||
#include <cstddef>
|
||||
|
||||
namespace
|
||||
{
|
||||
inline constexpr eastl::array<std::byte, 11> g_myArray = {
|
||||
std::byte{0x48}, std::byte{0x65}, std::byte{0x6C}, std::byte{0x6C}, std::byte{0x6F},
|
||||
std::byte{0x20}, std::byte{0x57}, std::byte{0x6F}, std::byte{0x72}, std::byte{0x6C},
|
||||
std::byte{0x64}
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif // TOTO_TXT_HPP
|
||||
)";
|
||||
EXPECT_STREQ(expectedResult.data(), generator.Get().data());
|
||||
}
|
||||
|
||||
/****************************************************************************************/
|
||||
|
||||
TEST_F(GeneratorFixture, NonExistentFile)
|
||||
{
|
||||
Generator generator("Fixture/tata.txt");
|
||||
EXPECT_FALSE(generator.Generate());
|
||||
}
|
||||
|
||||
/****************************************************************************************/
|
||||
|
||||
TEST_F(GeneratorFixture, Directory)
|
||||
{
|
||||
Generator generator("Fixture/");
|
||||
EXPECT_FALSE(generator.Generate());
|
||||
}
|
||||
} // namespace Bin2CPP
|
||||
|
||||
@@ -5,7 +5,7 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
||||
find_package(Threads REQUIRED)
|
||||
endif()
|
||||
|
||||
find_package(EASTL REQUIRED)
|
||||
find_package(magic_enum REQUIRED)
|
||||
find_package(CLI11 REQUIRED)
|
||||
find_package(quill REQUIRED)
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ tools.build:exelinkflags=["/LTCG", "/INCREMENTAL:NO"]
|
||||
tools.build:sharedlinkflags=["/LTCG", "/INCREMENTAL:NO"]
|
||||
|
||||
tools.build:cflags=["/Zc:preprocessor", "/Zc:__STDC__", "/D_CRT_DECLARE_NONSTDC_NAMES=1", "/GL"]
|
||||
tools.build:cxxflags=["/Zc:preprocessor", "/Zc:__cplusplus", "/Zc:enumTypes", "/Zc:templateScope", "/Zc:strictStrings", "/Zc:rvalueCast", "/Zc:hiddenFriend", "/Zc:externConstexpr", "/Zc:ternary", "/GL"]
|
||||
tools.build:cxxflags=["/Zc:preprocessor", "/permissive-", "/Zc:__cplusplus", "/Zc:enumTypes", "/Zc:templateScope", "/Zc:throwingNew"]
|
||||
|
||||
[tool_requires]
|
||||
!cmake/*: cmake/[>=4.2]
|
||||
|
||||
@@ -12,8 +12,7 @@ build_type=Debug
|
||||
tools.cmake.cmaketoolchain:user_toolchain+={{profile_dir}}/msvc_ccache.cmake
|
||||
|
||||
tools.build:cflags=["/Zc:preprocessor", "/Zc:__STDC__", "/D_CRT_DECLARE_NONSTDC_NAMES=1"]
|
||||
tools.build:cxxflags=["/Zc:preprocessor", "/Zc:__cplusplus", "/Zc:enumTypes", "/Zc:templateScope", "/Zc:strictStrings", "/Zc:rvalueCast", "/Zc:hiddenFriend", "/Zc:externConstexpr", "/Zc:ternary"]
|
||||
|
||||
tools.build:cxxflags=["/Zc:preprocessor", "/permissive-", "/Zc:__cplusplus", "/Zc:enumTypes", "/Zc:templateScope", "/Zc:throwingNew"]
|
||||
[tool_requires]
|
||||
!cmake/*: cmake/[>=4.2]
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ tools.build:exelinkflags=["/INCREMENTAL:NO"]
|
||||
tools.build:sharedlinkflags=["/INCREMENTAL:NO"]
|
||||
|
||||
tools.build:cflags=["/Zc:preprocessor", "/Zc:__STDC__", "/D_CRT_DECLARE_NONSTDC_NAMES=1"]
|
||||
tools.build:cxxflags=["/Zc:preprocessor", "/Zc:__cplusplus", "/Zc:enumTypes", "/Zc:templateScope", "/Zc:strictStrings", "/Zc:rvalueCast", "/Zc:hiddenFriend", "/Zc:externConstexpr", "/Zc:ternary"]
|
||||
tools.build:cxxflags=["/Zc:preprocessor", "/permissive-", "/Zc:__cplusplus", "/Zc:enumTypes", "/Zc:templateScope", "/Zc:throwingNew"]
|
||||
|
||||
[tool_requires]
|
||||
!cmake/*: cmake/[>=4.2]
|
||||
|
||||
@@ -45,7 +45,7 @@ class Bin2CPP(ConanFile):
|
||||
|
||||
def requirements(self):
|
||||
self.requires("quill/11.0.2", transitive_headers=True)
|
||||
self.requires("eastl/3.27.01@bigfootdev/main", transitive_headers=True)
|
||||
self.requires("magic_enum/0.9.7", transitive_headers=True)
|
||||
self.requires("mimalloc/3.2.8@bigfootdev/main", transitive_headers=True)
|
||||
self.requires("cli11/2.6.1@bigfootdev/main")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user