mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2025-04-20 00:02:55 +00:00
Add stream proxy for declaring pack values
This commit is contained in:
parent
efa39a8ac3
commit
3f08be0564
@ -8,11 +8,13 @@
|
|||||||
#include "Parsing/Impl/CommentRemovingStreamProxy.h"
|
#include "Parsing/Impl/CommentRemovingStreamProxy.h"
|
||||||
#include "Parsing/Impl/DefinesStreamProxy.h"
|
#include "Parsing/Impl/DefinesStreamProxy.h"
|
||||||
#include "Parsing/Impl/IncludingStreamProxy.h"
|
#include "Parsing/Impl/IncludingStreamProxy.h"
|
||||||
|
#include "Parsing/Impl/PackDefinitionStreamProxy.h"
|
||||||
#include "Parsing/Impl/ParserFilesystemStream.h"
|
#include "Parsing/Impl/ParserFilesystemStream.h"
|
||||||
|
|
||||||
HeaderFileReader::HeaderFileReader(const ZoneCodeGeneratorArguments* args, std::string filename)
|
HeaderFileReader::HeaderFileReader(const ZoneCodeGeneratorArguments* args, std::string filename)
|
||||||
: m_args(args),
|
: m_args(args),
|
||||||
m_filename(std::move(filename)),
|
m_filename(std::move(filename)),
|
||||||
|
m_pack_value_supplier(nullptr),
|
||||||
m_stream(nullptr)
|
m_stream(nullptr)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -35,13 +37,16 @@ void HeaderFileReader::SetupStreamProxies()
|
|||||||
{
|
{
|
||||||
auto commentProxy = std::make_unique<CommentRemovingStreamProxy>(m_stream);
|
auto commentProxy = std::make_unique<CommentRemovingStreamProxy>(m_stream);
|
||||||
auto includeProxy = std::make_unique<IncludingStreamProxy>(commentProxy.get());
|
auto includeProxy = std::make_unique<IncludingStreamProxy>(commentProxy.get());
|
||||||
auto definesProxy = std::make_unique<DefinesStreamProxy>(includeProxy.get());
|
auto packProxy = std::make_unique<PackDefinitionStreamProxy>(includeProxy.get());
|
||||||
|
auto definesProxy = std::make_unique<DefinesStreamProxy>(packProxy.get());
|
||||||
definesProxy->AddDefine(ZONE_CODE_GENERATOR_DEFINE_NAME, ZONE_CODE_GENERATOR_DEFINE_VALUE);
|
definesProxy->AddDefine(ZONE_CODE_GENERATOR_DEFINE_NAME, ZONE_CODE_GENERATOR_DEFINE_VALUE);
|
||||||
|
|
||||||
|
m_pack_value_supplier = packProxy.get();
|
||||||
m_stream = definesProxy.get();
|
m_stream = definesProxy.get();
|
||||||
|
|
||||||
m_open_streams.emplace_back(std::move(commentProxy));
|
m_open_streams.emplace_back(std::move(commentProxy));
|
||||||
m_open_streams.emplace_back(std::move(includeProxy));
|
m_open_streams.emplace_back(std::move(includeProxy));
|
||||||
|
m_open_streams.emplace_back(std::move(packProxy));
|
||||||
m_open_streams.emplace_back(std::move(definesProxy));
|
m_open_streams.emplace_back(std::move(definesProxy));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "ZoneCodeGeneratorArguments.h"
|
#include "ZoneCodeGeneratorArguments.h"
|
||||||
|
#include "Parsing/IPackValueSupplier.h"
|
||||||
#include "Parsing/IParserLineStream.h"
|
#include "Parsing/IParserLineStream.h"
|
||||||
#include "Persistence/IDataRepository.h"
|
#include "Persistence/IDataRepository.h"
|
||||||
|
|
||||||
@ -15,6 +16,7 @@ class HeaderFileReader
|
|||||||
std::string m_filename;
|
std::string m_filename;
|
||||||
|
|
||||||
std::vector<std::unique_ptr<IParserLineStream>> m_open_streams;
|
std::vector<std::unique_ptr<IParserLineStream>> m_open_streams;
|
||||||
|
IPackValueSupplier* m_pack_value_supplier;
|
||||||
IParserLineStream* m_stream;
|
IParserLineStream* m_stream;
|
||||||
|
|
||||||
bool OpenBaseStream();
|
bool OpenBaseStream();
|
||||||
|
14
src/ZoneCodeGeneratorLib/Parsing/IPackValueSupplier.h
Normal file
14
src/ZoneCodeGeneratorLib/Parsing/IPackValueSupplier.h
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
class IPackValueSupplier
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
IPackValueSupplier() = default;
|
||||||
|
virtual ~IPackValueSupplier() = default;
|
||||||
|
IPackValueSupplier(const IPackValueSupplier& other) = default;
|
||||||
|
IPackValueSupplier(IPackValueSupplier&& other) noexcept = default;
|
||||||
|
IPackValueSupplier& operator=(const IPackValueSupplier& other) = default;
|
||||||
|
IPackValueSupplier& operator=(IPackValueSupplier&& other) noexcept = default;
|
||||||
|
|
||||||
|
virtual int GetCurrentPack() = 0;
|
||||||
|
};
|
@ -0,0 +1,92 @@
|
|||||||
|
#include "PackDefinitionStreamProxy.h"
|
||||||
|
|
||||||
|
#include "Parsing/ParsingException.h"
|
||||||
|
|
||||||
|
PackDefinitionStreamProxy::PackDefinitionStreamProxy(IParserLineStream* stream)
|
||||||
|
: m_stream(stream)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PackDefinitionStreamProxy::MatchPackDirective(const ParserLine& line, unsigned directivePosition)
|
||||||
|
{
|
||||||
|
auto packValue = 0;
|
||||||
|
|
||||||
|
if (!MatchString(line, directivePosition, PRAGMA_PACK_DIRECTIVE, std::char_traits<char>::length(PRAGMA_PACK_DIRECTIVE)))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!MatchNextCharacter(line, directivePosition, '('))
|
||||||
|
throw ParsingException(CreatePos(line, directivePosition), "Invalid pack directive.");
|
||||||
|
|
||||||
|
bool isPush;
|
||||||
|
if (MatchNextString(line, directivePosition, PUSH_KEYWORD, std::char_traits<char>::length(PUSH_KEYWORD)))
|
||||||
|
isPush = true;
|
||||||
|
else if (MatchNextString(line, directivePosition, POP_KEYWORD, std::char_traits<char>::length(POP_KEYWORD)))
|
||||||
|
isPush = false;
|
||||||
|
else
|
||||||
|
throw ParsingException(CreatePos(line, directivePosition), "Unknown pack directive command.");
|
||||||
|
|
||||||
|
if(isPush)
|
||||||
|
{
|
||||||
|
if (!MatchNextCharacter(line, directivePosition, ','))
|
||||||
|
throw ParsingException(CreatePos(line, directivePosition), "Invalid pack directive.");
|
||||||
|
|
||||||
|
if (!ExtractInteger(line, directivePosition, packValue))
|
||||||
|
throw ParsingException(CreatePos(line, directivePosition), "Invalid pack value.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!MatchNextCharacter(line, directivePosition, ')'))
|
||||||
|
throw ParsingException(CreatePos(line, directivePosition), "Invalid pack directive.");
|
||||||
|
|
||||||
|
if(isPush)
|
||||||
|
m_current_pack.push(packValue);
|
||||||
|
else if (!m_current_pack.empty())
|
||||||
|
m_current_pack.pop();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PackDefinitionStreamProxy::MatchDirectives(const ParserLine& line)
|
||||||
|
{
|
||||||
|
unsigned directivePos;
|
||||||
|
|
||||||
|
if (!FindDirective(line, directivePos))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
directivePos++;
|
||||||
|
return MatchPackDirective(line, directivePos);
|
||||||
|
}
|
||||||
|
|
||||||
|
ParserLine PackDefinitionStreamProxy::NextLine()
|
||||||
|
{
|
||||||
|
auto line = m_stream->NextLine();
|
||||||
|
|
||||||
|
while (MatchDirectives(line))
|
||||||
|
line = m_stream->NextLine();
|
||||||
|
|
||||||
|
return line;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PackDefinitionStreamProxy::IncludeFile(const std::string& filename)
|
||||||
|
{
|
||||||
|
return m_stream->IncludeFile(filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PackDefinitionStreamProxy::PopCurrentFile()
|
||||||
|
{
|
||||||
|
m_stream->PopCurrentFile();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PackDefinitionStreamProxy::IsOpen() const
|
||||||
|
{
|
||||||
|
return m_stream->IsOpen();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PackDefinitionStreamProxy::Eof() const
|
||||||
|
{
|
||||||
|
return m_stream->Eof();
|
||||||
|
}
|
||||||
|
|
||||||
|
int PackDefinitionStreamProxy::GetCurrentPack()
|
||||||
|
{
|
||||||
|
return m_current_pack.empty() ? DEFAULT_PACK : m_current_pack.top();
|
||||||
|
}
|
@ -0,0 +1,35 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stack>
|
||||||
|
|
||||||
|
#include "AbstractDirectiveStreamProxy.h"
|
||||||
|
#include "Parsing/IPackValueSupplier.h"
|
||||||
|
#include "Parsing/IParserLineStream.h"
|
||||||
|
|
||||||
|
class PackDefinitionStreamProxy final : public AbstractDirectiveStreamProxy, public IPackValueSupplier
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static constexpr int DEFAULT_PACK = 8;
|
||||||
|
|
||||||
|
private:
|
||||||
|
static constexpr const char* PRAGMA_PACK_DIRECTIVE = "pragma pack";
|
||||||
|
static constexpr const char* PUSH_KEYWORD = "push";
|
||||||
|
static constexpr const char* POP_KEYWORD = "pop";
|
||||||
|
|
||||||
|
IParserLineStream* const m_stream;
|
||||||
|
std::stack<int> m_current_pack;
|
||||||
|
|
||||||
|
_NODISCARD bool MatchPackDirective(const ParserLine& line, unsigned directivePosition);
|
||||||
|
_NODISCARD bool MatchDirectives(const ParserLine& line);
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit PackDefinitionStreamProxy(IParserLineStream* stream);
|
||||||
|
|
||||||
|
ParserLine NextLine() override;
|
||||||
|
bool IncludeFile(const std::string& filename) override;
|
||||||
|
void PopCurrentFile() override;
|
||||||
|
_NODISCARD bool IsOpen() const override;
|
||||||
|
_NODISCARD bool Eof() const override;
|
||||||
|
|
||||||
|
int GetCurrentPack() override;
|
||||||
|
};
|
@ -0,0 +1,39 @@
|
|||||||
|
#include <catch2/catch.hpp>
|
||||||
|
|
||||||
|
#include "Parsing/Impl/PackDefinitionStreamProxy.h"
|
||||||
|
#include "Parsing/Mock/MockParserLineStream.h"
|
||||||
|
|
||||||
|
namespace test::parsing::impl::pack_definition_stream_proxy
|
||||||
|
{
|
||||||
|
void ExpectLine(IParserLineStream* stream, const int lineNumber, const std::string& value)
|
||||||
|
{
|
||||||
|
auto line = stream->NextLine();
|
||||||
|
REQUIRE(line.m_line_number == lineNumber);
|
||||||
|
REQUIRE(line.m_line == value);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("PackDefinitionStreamProxy: Ensure simple pack directives are working", "[parsing][parsingstream]")
|
||||||
|
{
|
||||||
|
const std::vector<std::string> lines
|
||||||
|
{
|
||||||
|
"hello world",
|
||||||
|
"#pragma pack(push, 32)",
|
||||||
|
"hello galaxy",
|
||||||
|
"#pragma pack(pop)",
|
||||||
|
"hello universe"
|
||||||
|
};
|
||||||
|
|
||||||
|
MockParserLineStream mockStream(lines);
|
||||||
|
PackDefinitionStreamProxy proxy(&mockStream);
|
||||||
|
|
||||||
|
REQUIRE(proxy.GetCurrentPack() == PackDefinitionStreamProxy::DEFAULT_PACK);
|
||||||
|
ExpectLine(&proxy, 1, "hello world");
|
||||||
|
REQUIRE(proxy.GetCurrentPack() == PackDefinitionStreamProxy::DEFAULT_PACK);
|
||||||
|
ExpectLine(&proxy, 3, "hello galaxy");
|
||||||
|
REQUIRE(proxy.GetCurrentPack() == 32);
|
||||||
|
ExpectLine(&proxy, 5, "hello universe");
|
||||||
|
REQUIRE(proxy.GetCurrentPack() == PackDefinitionStreamProxy::DEFAULT_PACK);
|
||||||
|
|
||||||
|
REQUIRE(proxy.Eof());
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user