mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2025-04-20 00:02:55 +00:00
Add set define proxy to set a define based on an expression
This commit is contained in:
parent
a36d1c430a
commit
03dd0f06b2
100
src/RawTemplater/Templating/SetDefineStreamProxy.cpp
Normal file
100
src/RawTemplater/Templating/SetDefineStreamProxy.cpp
Normal file
@ -0,0 +1,100 @@
|
||||
#include "SetDefineStreamProxy.h"
|
||||
|
||||
#include "Parsing/ParsingException.h"
|
||||
|
||||
using namespace templating;
|
||||
|
||||
SetDefineStreamProxy::SetDefineStreamProxy(IParserLineStream* stream)
|
||||
: m_stream(stream),
|
||||
m_defines_proxy(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
void SetDefineStreamProxy::SetDefinesProxy(DefinesStreamProxy* definesProxy)
|
||||
{
|
||||
m_defines_proxy = definesProxy;
|
||||
}
|
||||
|
||||
bool SetDefineStreamProxy::MatchSetDirective(const ParserLine& line, const unsigned directiveStartPosition, const unsigned directiveEndPosition) const
|
||||
{
|
||||
auto currentPosition = directiveStartPosition;
|
||||
|
||||
if (directiveEndPosition - directiveStartPosition != std::char_traits<char>::length(SET_DIRECTIVE)
|
||||
|| !MatchString(line, currentPosition, SET_DIRECTIVE, std::char_traits<char>::length(SET_DIRECTIVE)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!SkipWhitespace(line, currentPosition))
|
||||
return false;
|
||||
|
||||
const auto nameStartPosition = currentPosition;
|
||||
if (!ExtractIdentifier(line, currentPosition))
|
||||
throw ParsingException(CreatePos(line, currentPosition), "Invalid set directive.");
|
||||
|
||||
auto name = line.m_line.substr(nameStartPosition, currentPosition - nameStartPosition);
|
||||
|
||||
if (!SkipWhitespace(line, currentPosition))
|
||||
throw ParsingException(CreatePos(line, currentPosition), "Invalid set directive.");
|
||||
|
||||
const auto expressionString = line.m_line.substr(currentPosition, line.m_line.size() - currentPosition);
|
||||
if (expressionString.empty())
|
||||
throw ParsingException(CreatePos(line, currentPosition), "Cannot set without an expression.");
|
||||
|
||||
const auto expression = m_defines_proxy->ParseExpression(expressionString);
|
||||
if (!expression)
|
||||
throw ParsingException(CreatePos(line, currentPosition), "Failed to parse set expression");
|
||||
|
||||
if (!expression->IsStatic())
|
||||
throw ParsingException(CreatePos(line, currentPosition), "set expression must be static");
|
||||
|
||||
const auto value = expression->EvaluateStatic();
|
||||
|
||||
if (value.m_type != SimpleExpressionValue::Type::STRING)
|
||||
throw ParsingException(CreatePos(line, currentPosition), "set expression must evaluate to string");
|
||||
|
||||
m_defines_proxy->AddDefine(DefinesStreamProxy::Define(std::move(name), *value.m_string_value));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SetDefineStreamProxy::MatchDirectives(const ParserLine& line) const
|
||||
{
|
||||
unsigned directiveStartPos, directiveEndPos;
|
||||
|
||||
if (!FindDirective(line, directiveStartPos, directiveEndPos))
|
||||
return false;
|
||||
|
||||
directiveStartPos++;
|
||||
|
||||
return MatchSetDirective(line, directiveStartPos, directiveEndPos);
|
||||
}
|
||||
|
||||
ParserLine SetDefineStreamProxy::NextLine()
|
||||
{
|
||||
auto line = m_stream->NextLine();
|
||||
|
||||
while (MatchDirectives(line))
|
||||
line = m_stream->NextLine();
|
||||
|
||||
return line;
|
||||
}
|
||||
|
||||
bool SetDefineStreamProxy::IncludeFile(const std::string& filename)
|
||||
{
|
||||
return m_stream->IncludeFile(filename);
|
||||
}
|
||||
|
||||
void SetDefineStreamProxy::PopCurrentFile()
|
||||
{
|
||||
m_stream->PopCurrentFile();
|
||||
}
|
||||
|
||||
bool SetDefineStreamProxy::IsOpen() const
|
||||
{
|
||||
return m_stream->IsOpen();
|
||||
}
|
||||
|
||||
bool SetDefineStreamProxy::Eof() const
|
||||
{
|
||||
return m_stream->Eof();
|
||||
}
|
31
src/RawTemplater/Templating/SetDefineStreamProxy.h
Normal file
31
src/RawTemplater/Templating/SetDefineStreamProxy.h
Normal file
@ -0,0 +1,31 @@
|
||||
#pragma once
|
||||
|
||||
#include "Utils/ClassUtils.h"
|
||||
#include "Parsing/Impl/AbstractDirectiveStreamProxy.h"
|
||||
#include "Parsing/Impl/DefinesStreamProxy.h"
|
||||
|
||||
namespace templating
|
||||
{
|
||||
class SetDefineStreamProxy final : public AbstractDirectiveStreamProxy
|
||||
{
|
||||
public:
|
||||
explicit SetDefineStreamProxy(IParserLineStream* stream);
|
||||
|
||||
void SetDefinesProxy(DefinesStreamProxy* definesProxy);
|
||||
|
||||
ParserLine NextLine() override;
|
||||
bool IncludeFile(const std::string& filename) override;
|
||||
void PopCurrentFile() override;
|
||||
_NODISCARD bool IsOpen() const override;
|
||||
_NODISCARD bool Eof() const override;
|
||||
|
||||
private:
|
||||
static constexpr const char* SET_DIRECTIVE = "set";
|
||||
|
||||
_NODISCARD bool MatchSetDirective(const ParserLine& line, unsigned directiveStartPosition, unsigned directiveEndPosition) const;
|
||||
_NODISCARD bool MatchDirectives(const ParserLine& line) const;
|
||||
|
||||
IParserLineStream* const m_stream;
|
||||
DefinesStreamProxy* m_defines_proxy;
|
||||
};
|
||||
}
|
@ -8,6 +8,7 @@
|
||||
|
||||
#include "Utils/ClassUtils.h"
|
||||
#include "DirectiveEscapeStreamProxy.h"
|
||||
#include "SetDefineStreamProxy.h"
|
||||
#include "TemplatingStreamProxy.h"
|
||||
#include "Parsing/ParsingException.h"
|
||||
#include "Parsing/Impl/DefinesStreamProxy.h"
|
||||
@ -32,16 +33,19 @@ namespace templating
|
||||
m_base_stream = std::make_unique<ParserSingleInputStream>(stream, fileName);
|
||||
|
||||
m_templating_proxy = std::make_unique<TemplatingStreamProxy>(m_base_stream.get(), templaterControl);
|
||||
m_defines_proxy = std::make_unique<DefinesStreamProxy>(m_templating_proxy.get(), true);
|
||||
m_set_define_proxy = std::make_unique<SetDefineStreamProxy>(m_templating_proxy.get());
|
||||
m_defines_proxy = std::make_unique<DefinesStreamProxy>(m_set_define_proxy.get(), true);
|
||||
m_directive_escape_proxy = std::make_unique<DirectiveEscapeStreamProxy>(m_defines_proxy.get());
|
||||
m_skip_until_first_non_empty_proxy = std::make_unique<SkipUntilFirstNonEmptyProxy>(m_directive_escape_proxy.get());
|
||||
|
||||
m_templating_proxy->SetDefinesProxy(m_defines_proxy.get());
|
||||
m_set_define_proxy->SetDefinesProxy(m_defines_proxy.get());
|
||||
m_stream = m_skip_until_first_non_empty_proxy.get();
|
||||
}
|
||||
|
||||
std::unique_ptr<IParserLineStream> m_base_stream;
|
||||
std::unique_ptr<TemplatingStreamProxy> m_templating_proxy;
|
||||
std::unique_ptr<SetDefineStreamProxy> m_set_define_proxy;
|
||||
std::unique_ptr<DefinesStreamProxy> m_defines_proxy;
|
||||
std::unique_ptr<DirectiveEscapeStreamProxy> m_directive_escape_proxy;
|
||||
std::unique_ptr<SkipUntilFirstNonEmptyProxy> m_skip_until_first_non_empty_proxy;
|
||||
|
@ -140,7 +140,7 @@ bool TemplatingStreamProxy::MatchFilenameDirective(const ParserLine& line, const
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TemplatingStreamProxy::MatchDirectives(const ParserLine& line)
|
||||
bool TemplatingStreamProxy::MatchDirectives(const ParserLine& line) const
|
||||
{
|
||||
unsigned directiveStartPos, directiveEndPos;
|
||||
|
||||
|
@ -45,7 +45,7 @@ namespace templating
|
||||
_NODISCARD bool MatchSwitchDirective(const ParserLine& line, unsigned directiveStartPosition, unsigned directiveEndPosition) const;
|
||||
_NODISCARD bool MatchOptionsDirective(const ParserLine& line, unsigned directiveStartPosition, unsigned directiveEndPosition) const;
|
||||
_NODISCARD bool MatchFilenameDirective(const ParserLine& line, unsigned directiveStartPosition, unsigned directiveEndPosition) const;
|
||||
bool MatchDirectives(const ParserLine& line);
|
||||
_NODISCARD bool MatchDirectives(const ParserLine& line) const;
|
||||
|
||||
IParserLineStream* const m_stream;
|
||||
ITemplaterControl* const m_templater_control;
|
||||
|
Loading…
x
Reference in New Issue
Block a user