mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2025-04-20 00:02:55 +00:00
Use shared ptr for line filenames to be able to still use filenames when original file has been closed
This commit is contained in:
parent
6b7a71a1bb
commit
a8f0fbd3bb
@ -1,15 +1,12 @@
|
||||
#include "IParserLineStream.h"
|
||||
|
||||
const std::string ParserLine::EMPTY_STRING;
|
||||
|
||||
ParserLine::ParserLine()
|
||||
: m_filename(EMPTY_STRING),
|
||||
m_line_number(0)
|
||||
: m_line_number(0)
|
||||
{
|
||||
}
|
||||
|
||||
ParserLine::ParserLine(const std::string& filename, const int lineNumber, std::string line)
|
||||
: m_filename(filename),
|
||||
ParserLine::ParserLine(std::shared_ptr<std::string> filename, const int lineNumber, std::string line)
|
||||
: m_filename(std::move(filename)),
|
||||
m_line_number(lineNumber),
|
||||
m_line(std::move(line))
|
||||
{
|
||||
|
@ -2,20 +2,19 @@
|
||||
|
||||
#include <string>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
#include "Utils/ClassUtils.h"
|
||||
|
||||
class ParserLine
|
||||
{
|
||||
static const std::string EMPTY_STRING;
|
||||
|
||||
public:
|
||||
std::reference_wrapper<const std::string> m_filename;
|
||||
std::shared_ptr<std::string> m_filename;
|
||||
int m_line_number;
|
||||
std::string m_line;
|
||||
|
||||
ParserLine();
|
||||
ParserLine(const std::string& filename, int lineNumber, std::string line);
|
||||
ParserLine(std::shared_ptr<std::string> filename, int lineNumber, std::string line);
|
||||
|
||||
_NODISCARD bool IsEof() const;
|
||||
};
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
TokenPos AbstractDirectiveStreamProxy::CreatePos(const ParserLine& line, const unsigned position)
|
||||
{
|
||||
return TokenPos(line.m_filename.get(), line.m_line_number, static_cast<int>(position + 1));
|
||||
return TokenPos(*line.m_filename, line.m_line_number, static_cast<int>(position + 1));
|
||||
}
|
||||
|
||||
bool AbstractDirectiveStreamProxy::SkipWhitespace(const ParserLine& line, unsigned& position)
|
||||
|
@ -100,7 +100,7 @@ protected:
|
||||
_NODISCARD TokenPos GetPreviousCharacterPos() const
|
||||
{
|
||||
const auto& currentLine = CurrentLine();
|
||||
return TokenPos(currentLine.m_filename, currentLine.m_line_number, m_current_line_offset);
|
||||
return TokenPos(*currentLine.m_filename, currentLine.m_line_number, m_current_line_offset);
|
||||
}
|
||||
|
||||
_NODISCARD TokenPos GetNextCharacterPos()
|
||||
@ -109,10 +109,10 @@ protected:
|
||||
if (m_current_line_offset + 1 >= currentLine.m_line.size())
|
||||
{
|
||||
PeekChar();
|
||||
return TokenPos(m_line_cache.back().m_filename, m_line_cache.back().m_line_number, 1);
|
||||
return TokenPos(*m_line_cache.back().m_filename, m_line_cache.back().m_line_number, 1);
|
||||
}
|
||||
|
||||
return TokenPos(currentLine.m_filename, currentLine.m_line_number, m_current_line_offset + 1);
|
||||
return TokenPos(*currentLine.m_filename, currentLine.m_line_number, m_current_line_offset + 1);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -155,7 +155,7 @@ protected:
|
||||
while (true)
|
||||
{
|
||||
if (m_current_line_offset >= lineSize)
|
||||
throw ParsingException(TokenPos(currentLine.m_filename, currentLine.m_line_number, m_current_line_offset), "Unclosed string");
|
||||
throw ParsingException(TokenPos(*currentLine.m_filename, currentLine.m_line_number, m_current_line_offset), "Unclosed string");
|
||||
|
||||
if (currentLine.m_line[m_current_line_offset] == '\"')
|
||||
break;
|
||||
@ -189,7 +189,7 @@ protected:
|
||||
auto exponent = false;
|
||||
|
||||
if (*currentCharacter == '-' || *currentCharacter == '+')
|
||||
currentCharacter++;
|
||||
++currentCharacter;
|
||||
|
||||
while (*currentCharacter)
|
||||
{
|
||||
@ -208,7 +208,7 @@ protected:
|
||||
if (exponent)
|
||||
throw ParsingException(GetPreviousCharacterPos(), "Invalid number");
|
||||
if (currentCharacter[1] == '-')
|
||||
currentCharacter++;
|
||||
++currentCharacter;
|
||||
exponent = true;
|
||||
isInteger = false;
|
||||
}
|
||||
@ -221,7 +221,7 @@ protected:
|
||||
break;
|
||||
}
|
||||
|
||||
currentCharacter++;
|
||||
++currentCharacter;
|
||||
}
|
||||
|
||||
return isInteger;
|
||||
@ -290,7 +290,6 @@ protected:
|
||||
public:
|
||||
const TokenType& GetToken(unsigned index) override
|
||||
{
|
||||
assert(index >= 0);
|
||||
while (index >= m_token_cache.size())
|
||||
m_token_cache.emplace_back(GetNextToken());
|
||||
|
||||
@ -307,7 +306,7 @@ public:
|
||||
const auto& lastToken = m_token_cache.back();
|
||||
while (!m_line_cache.empty()
|
||||
&& (m_line_cache.front().m_line_number != lastToken.GetPos().m_line
|
||||
|| m_line_cache.front().m_filename.get() != lastToken.GetPos().m_filename.get()))
|
||||
|| *m_line_cache.front().m_filename != lastToken.GetPos().m_filename.get()))
|
||||
{
|
||||
m_line_cache.pop_front();
|
||||
m_line_index--;
|
||||
@ -319,7 +318,7 @@ public:
|
||||
m_token_cache.erase(m_token_cache.begin(), m_token_cache.begin() + amount);
|
||||
const auto& firstToken = m_token_cache.front();
|
||||
while (m_line_cache.front().m_line_number != firstToken.GetPos().m_line
|
||||
|| m_line_cache.front().m_filename.get() != firstToken.GetPos().m_filename.get())
|
||||
|| *m_line_cache.front().m_filename != firstToken.GetPos().m_filename.get())
|
||||
{
|
||||
m_line_cache.pop_front();
|
||||
m_line_index--;
|
||||
@ -341,7 +340,7 @@ public:
|
||||
{
|
||||
for (const auto& line : m_line_cache)
|
||||
{
|
||||
if (line.m_filename.get() == pos.m_filename.get()
|
||||
if (*line.m_filename == pos.m_filename.get()
|
||||
&& line.m_line_number == pos.m_line)
|
||||
return line;
|
||||
}
|
||||
|
@ -70,7 +70,7 @@ bool IncludingStreamProxy::MatchIncludeDirective(const ParserLine& line, const u
|
||||
unsigned filenameStart, filenameEnd;
|
||||
|
||||
if (!ExtractIncludeFilename(line, currentPos, filenameStart, filenameEnd))
|
||||
throw ParsingException(TokenPos(line.m_filename, line.m_line_number, static_cast<int>(currentPos)), INCLUDE_QUOTES_ERROR);
|
||||
throw ParsingException(TokenPos(*line.m_filename, line.m_line_number, static_cast<int>(currentPos)), INCLUDE_QUOTES_ERROR);
|
||||
|
||||
if (filenameEnd <= filenameStart)
|
||||
throw ParsingException(CreatePos(line, currentPos), "No filename specified");
|
||||
@ -103,7 +103,7 @@ bool IncludingStreamProxy::MatchPragmaOnceDirective(const ParserLine& line, cons
|
||||
if (!MatchString(line, currentPos, ONCE_PRAGMA_COMMAND, std::char_traits<char>::length(ONCE_PRAGMA_COMMAND)))
|
||||
return false;
|
||||
|
||||
const auto absolutePath = absolute(fs::path(line.m_filename.get()));
|
||||
const auto absolutePath = absolute(fs::path(*line.m_filename));
|
||||
const auto absolutePathStr = absolutePath.string();
|
||||
|
||||
const auto existingPath = m_included_files.find(absolutePathStr);
|
||||
|
@ -15,7 +15,7 @@ class IncludingStreamProxy final : public AbstractDirectiveStreamProxy
|
||||
IParserLineStream* const m_stream;
|
||||
std::set<std::string> m_included_files;
|
||||
|
||||
_NODISCARD static bool ExtractIncludeFilename(const ParserLine& line, unsigned includeDirectivePosition, unsigned& directiveStartPos, unsigned& filenameEndPos);
|
||||
_NODISCARD static bool ExtractIncludeFilename(const ParserLine& line, unsigned includeDirectivePosition, unsigned& filenameStartPosition, unsigned& filenameEndPosition);
|
||||
_NODISCARD bool MatchIncludeDirective(const ParserLine& line, unsigned directiveStartPos, unsigned directiveEndPos) const;
|
||||
_NODISCARD bool MatchPragmaOnceDirective(const ParserLine& line, unsigned directiveStartPos, unsigned directiveEndPos);
|
||||
_NODISCARD bool MatchDirectives(const ParserLine& line);
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
#include <stack>
|
||||
|
||||
#include "Utils/ClassUtils.h"
|
||||
#include "AbstractDirectiveStreamProxy.h"
|
||||
#include "Parsing/IPackValueSupplier.h"
|
||||
#include "Parsing/IParserLineStream.h"
|
||||
@ -32,5 +33,5 @@ public:
|
||||
_NODISCARD bool IsOpen() const override;
|
||||
_NODISCARD bool Eof() const override;
|
||||
|
||||
int GetCurrentPack() const override;
|
||||
_NODISCARD int GetCurrentPack() const override;
|
||||
};
|
||||
|
@ -6,13 +6,13 @@
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
ParserFilesystemStream::FileInfo::FileInfo(std::string filePath)
|
||||
: m_file_path(std::move(filePath)),
|
||||
m_stream(m_file_path),
|
||||
: m_file_path(std::make_shared<std::string>(std::move(filePath))),
|
||||
m_stream(*m_file_path),
|
||||
m_line_number(1)
|
||||
{
|
||||
}
|
||||
|
||||
ParserFilesystemStream::ParserFilesystemStream(std::string path)
|
||||
ParserFilesystemStream::ParserFilesystemStream(const std::string& path)
|
||||
{
|
||||
const auto absolutePath = absolute(fs::path(path));
|
||||
m_files.emplace(FileInfo(absolutePath.string()));
|
||||
@ -74,7 +74,7 @@ bool ParserFilesystemStream::IncludeFile(const std::string& filename)
|
||||
if (m_files.empty())
|
||||
return false;
|
||||
|
||||
auto newFilePath = fs::path(m_files.top().m_file_path);
|
||||
auto newFilePath = fs::path(*m_files.top().m_file_path);
|
||||
newFilePath.remove_filename().concat(filename);
|
||||
newFilePath = absolute(newFilePath);
|
||||
|
||||
|
@ -10,7 +10,7 @@ class ParserFilesystemStream final : public IParserLineStream
|
||||
class FileInfo
|
||||
{
|
||||
public:
|
||||
std::string m_file_path;
|
||||
std::shared_ptr<std::string> m_file_path;
|
||||
std::ifstream m_stream;
|
||||
int m_line_number;
|
||||
|
||||
@ -19,7 +19,7 @@ class ParserFilesystemStream final : public IParserLineStream
|
||||
std::stack<FileInfo> m_files;
|
||||
|
||||
public:
|
||||
explicit ParserFilesystemStream(std::string path);
|
||||
explicit ParserFilesystemStream(const std::string& path);
|
||||
|
||||
ParserLine NextLine() override;
|
||||
bool IncludeFile(const std::string& filename) override;
|
||||
|
@ -5,14 +5,14 @@
|
||||
ParserMultiInputStream::FileInfo::FileInfo(std::unique_ptr<std::istream> stream, std::string filePath)
|
||||
: m_owned_stream(std::move(stream)),
|
||||
m_stream(*m_owned_stream),
|
||||
m_file_path(std::move(filePath)),
|
||||
m_file_path(std::make_shared<std::string>(std::move(filePath))),
|
||||
m_line_number(1)
|
||||
{
|
||||
}
|
||||
|
||||
ParserMultiInputStream::FileInfo::FileInfo(std::istream& stream, std::string filePath)
|
||||
: m_stream(stream),
|
||||
m_file_path(std::move(filePath)),
|
||||
m_file_path(std::make_shared<std::string>(std::move(filePath))),
|
||||
m_line_number(1)
|
||||
{
|
||||
}
|
||||
@ -79,7 +79,7 @@ bool ParserMultiInputStream::IncludeFile(const std::string& filename)
|
||||
if (!m_include_callback)
|
||||
return false;
|
||||
|
||||
auto newFile = m_include_callback(filename, m_files.empty() ? "" : m_files.top().m_file_path);
|
||||
auto newFile = m_include_callback(filename, m_files.empty() ? "" : *m_files.top().m_file_path);
|
||||
if (!newFile)
|
||||
return false;
|
||||
|
||||
|
@ -18,7 +18,7 @@ private:
|
||||
public:
|
||||
std::unique_ptr<std::istream> m_owned_stream;
|
||||
std::istream& m_stream;
|
||||
std::string m_file_path;
|
||||
std::shared_ptr<std::string> m_file_path;
|
||||
int m_line_number;
|
||||
|
||||
FileInfo(std::unique_ptr<std::istream> stream, std::string filePath);
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
ParserSingleInputStream::ParserSingleInputStream(std::istream& stream, std::string fileName)
|
||||
: m_stream(stream),
|
||||
m_file_name(std::move(fileName)),
|
||||
m_file_name(std::make_shared<std::string>(std::move(fileName))),
|
||||
m_line_number(1)
|
||||
{
|
||||
}
|
||||
|
@ -1,13 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
#include <istream>
|
||||
#include <memory>
|
||||
|
||||
#include "Parsing/IParserLineStream.h"
|
||||
|
||||
class ParserSingleInputStream final : public IParserLineStream
|
||||
{
|
||||
std::istream& m_stream;
|
||||
std::string m_file_name;
|
||||
std::shared_ptr<std::string> m_file_name;
|
||||
int m_line_number;
|
||||
|
||||
public:
|
||||
|
@ -2,8 +2,6 @@
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
const std::string MockParserLineStream::MOCK_FILENAME = "Mockfile";
|
||||
|
||||
MockParserLineStream::MockParserLineStream(const std::vector<std::string>& lines)
|
||||
{
|
||||
AddIncludeLines(MOCK_FILENAME, lines);
|
||||
@ -11,7 +9,7 @@ MockParserLineStream::MockParserLineStream(const std::vector<std::string>& lines
|
||||
}
|
||||
|
||||
MockParserLineStream::IncludePos::IncludePos(std::string filename, const std::vector<std::string>& lines)
|
||||
: m_filename(std::move(filename)),
|
||||
: m_filename(std::make_shared<std::string>(std::move(filename))),
|
||||
m_lines(lines),
|
||||
m_pos(0)
|
||||
{
|
||||
|
@ -8,13 +8,13 @@
|
||||
class MockParserLineStream final : public IParserLineStream
|
||||
{
|
||||
public:
|
||||
static const std::string MOCK_FILENAME;
|
||||
static constexpr const char* MOCK_FILENAME = "MockFile";
|
||||
|
||||
private:
|
||||
class IncludePos
|
||||
{
|
||||
public:
|
||||
std::string m_filename;
|
||||
std::shared_ptr<std::string> m_filename;
|
||||
const std::vector<std::string>& m_lines;
|
||||
unsigned m_pos;
|
||||
|
||||
|
@ -27,21 +27,21 @@ namespace test::parsing::impl::including_stream_proxy
|
||||
{
|
||||
auto line = proxy.NextLine();
|
||||
REQUIRE(line.m_line_number == 1);
|
||||
REQUIRE(line.m_filename.get() == MockParserLineStream::MOCK_FILENAME);
|
||||
REQUIRE(*line.m_filename == MockParserLineStream::MOCK_FILENAME);
|
||||
REQUIRE(line.m_line == "Hello world");
|
||||
}
|
||||
|
||||
{
|
||||
auto line = proxy.NextLine();
|
||||
REQUIRE(line.m_line_number == 1);
|
||||
REQUIRE(line.m_filename.get() == "ASDF.txt");
|
||||
REQUIRE(*line.m_filename == "ASDF.txt");
|
||||
REQUIRE(line.m_line == "Hello galaxy");
|
||||
}
|
||||
|
||||
{
|
||||
auto line = proxy.NextLine();
|
||||
REQUIRE(line.m_line_number == 3);
|
||||
REQUIRE(line.m_filename.get() == MockParserLineStream::MOCK_FILENAME);
|
||||
REQUIRE(*line.m_filename == MockParserLineStream::MOCK_FILENAME);
|
||||
REQUIRE(line.m_line == "and bye");
|
||||
}
|
||||
|
||||
@ -70,21 +70,21 @@ namespace test::parsing::impl::including_stream_proxy
|
||||
{
|
||||
auto line = proxy.NextLine();
|
||||
REQUIRE(line.m_line_number == 1);
|
||||
REQUIRE(line.m_filename.get() == MockParserLineStream::MOCK_FILENAME);
|
||||
REQUIRE(*line.m_filename == MockParserLineStream::MOCK_FILENAME);
|
||||
REQUIRE(line.m_line == "Hello world");
|
||||
}
|
||||
|
||||
{
|
||||
auto line = proxy.NextLine();
|
||||
REQUIRE(line.m_line_number == 1);
|
||||
REQUIRE(line.m_filename.get() == "ASDF.txt");
|
||||
REQUIRE(*line.m_filename == "ASDF.txt");
|
||||
REQUIRE(line.m_line == "Hello galaxy");
|
||||
}
|
||||
|
||||
{
|
||||
auto line = proxy.NextLine();
|
||||
REQUIRE(line.m_line_number == 3);
|
||||
REQUIRE(line.m_filename.get() == MockParserLineStream::MOCK_FILENAME);
|
||||
REQUIRE(*line.m_filename == MockParserLineStream::MOCK_FILENAME);
|
||||
REQUIRE(line.m_line == "and bye");
|
||||
}
|
||||
|
||||
@ -113,21 +113,21 @@ namespace test::parsing::impl::including_stream_proxy
|
||||
{
|
||||
auto line = proxy.NextLine();
|
||||
REQUIRE(line.m_line_number == 1);
|
||||
REQUIRE(line.m_filename.get() == MockParserLineStream::MOCK_FILENAME);
|
||||
REQUIRE(*line.m_filename == MockParserLineStream::MOCK_FILENAME);
|
||||
REQUIRE(line.m_line == "Hello world");
|
||||
}
|
||||
|
||||
{
|
||||
auto line = proxy.NextLine();
|
||||
REQUIRE(line.m_line_number == 1);
|
||||
REQUIRE(line.m_filename.get() == "ASDF.txt");
|
||||
REQUIRE(*line.m_filename == "ASDF.txt");
|
||||
REQUIRE(line.m_line == "Hello galaxy");
|
||||
}
|
||||
|
||||
{
|
||||
auto line = proxy.NextLine();
|
||||
REQUIRE(line.m_line_number == 3);
|
||||
REQUIRE(line.m_filename.get() == MockParserLineStream::MOCK_FILENAME);
|
||||
REQUIRE(*line.m_filename == MockParserLineStream::MOCK_FILENAME);
|
||||
REQUIRE(line.m_line == "and bye");
|
||||
}
|
||||
|
||||
@ -158,21 +158,21 @@ namespace test::parsing::impl::including_stream_proxy
|
||||
{
|
||||
auto line = proxy.NextLine();
|
||||
REQUIRE(line.m_line_number == 1);
|
||||
REQUIRE(line.m_filename.get() == MockParserLineStream::MOCK_FILENAME);
|
||||
REQUIRE(*line.m_filename == MockParserLineStream::MOCK_FILENAME);
|
||||
REQUIRE(line.m_line == "Hello world");
|
||||
}
|
||||
|
||||
{
|
||||
auto line = proxy.NextLine();
|
||||
REQUIRE(line.m_line_number == 2);
|
||||
REQUIRE(line.m_filename.get() == "ASDF.txt");
|
||||
REQUIRE(*line.m_filename == "ASDF.txt");
|
||||
REQUIRE(line.m_line == "Hello galaxy");
|
||||
}
|
||||
|
||||
{
|
||||
auto line = proxy.NextLine();
|
||||
REQUIRE(line.m_line_number == 4);
|
||||
REQUIRE(line.m_filename.get() == MockParserLineStream::MOCK_FILENAME);
|
||||
REQUIRE(*line.m_filename == MockParserLineStream::MOCK_FILENAME);
|
||||
REQUIRE(line.m_line == "and bye");
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user