String parsing without originalDirectory setter
This commit is contained in:
parent
25fa15acbe
commit
ba23ed810a
6 changed files with 41 additions and 61 deletions
|
|
@ -33,21 +33,23 @@ void Parser::reset()
|
|||
}
|
||||
|
||||
void Parser::parseFile(const fs::path& path)
|
||||
{
|
||||
parseVirtualFile(path, nullptr);
|
||||
}
|
||||
|
||||
void Parser::parseString(const fs::path& path, absl::string_view sfzView)
|
||||
{
|
||||
parseVirtualFile(path, absl::make_unique<StringViewReader>(path, sfzView));
|
||||
}
|
||||
|
||||
void Parser::parseVirtualFile(const fs::path& path, std::unique_ptr<Reader> reader)
|
||||
{
|
||||
reset();
|
||||
|
||||
if (_listener)
|
||||
_listener->onParseBegin();
|
||||
|
||||
if (path.empty())
|
||||
return;
|
||||
|
||||
if (path.is_relative())
|
||||
setOriginalDirectory(originalDirectory() / path);
|
||||
else
|
||||
setOriginalDirectory(path.parent_path());
|
||||
|
||||
includeNewFile(path);
|
||||
includeNewFile(path, std::move(reader));
|
||||
processTopLevel();
|
||||
flushCurrentHeader();
|
||||
|
||||
|
|
@ -55,32 +57,14 @@ void Parser::parseFile(const fs::path& path)
|
|||
_listener->onParseEnd();
|
||||
}
|
||||
|
||||
void Parser::parseString(absl::string_view sfzView)
|
||||
{
|
||||
reset();
|
||||
|
||||
if (_listener)
|
||||
_listener->onParseBegin();
|
||||
|
||||
_included.push_back(absl::make_unique<StringViewReader>(sfzView));
|
||||
processTopLevel();
|
||||
flushCurrentHeader();
|
||||
|
||||
if (_listener)
|
||||
_listener->onParseEnd();
|
||||
}
|
||||
|
||||
void Parser::setOriginalDirectory(const fs::path& originalDirectory) noexcept
|
||||
{
|
||||
_originalDirectory = originalDirectory;
|
||||
}
|
||||
|
||||
void Parser::includeNewFile(const fs::path& path)
|
||||
void Parser::includeNewFile(const fs::path& path, std::unique_ptr<Reader> reader)
|
||||
{
|
||||
fs::path fullPath =
|
||||
(path.empty() || path.is_absolute()) ? path : _originalDirectory / path;
|
||||
|
||||
if (_pathsIncluded.find(fullPath.string()) != _pathsIncluded.end()) {
|
||||
if (_pathsIncluded.empty())
|
||||
_originalDirectory = fullPath.parent_path();
|
||||
else if (_pathsIncluded.find(fullPath.string()) != _pathsIncluded.end()) {
|
||||
if (_recursiveIncludeGuardEnabled)
|
||||
return;
|
||||
}
|
||||
|
|
@ -92,15 +76,18 @@ void Parser::includeNewFile(const fs::path& path)
|
|||
return;
|
||||
}
|
||||
|
||||
auto fileReader = absl::make_unique<FileReader>(fullPath);
|
||||
if (fileReader->hasError()) {
|
||||
SourceLocation loc = fileReader->location();
|
||||
emitError({ loc, loc }, "Cannot open file for reading: " + fullPath.string());
|
||||
return;
|
||||
if (!reader) {
|
||||
auto fileReader = absl::make_unique<FileReader>(fullPath);
|
||||
if (fileReader->hasError()) {
|
||||
SourceLocation loc = fileReader->location();
|
||||
emitError({ loc, loc }, "Cannot open file for reading: " + fullPath.string());
|
||||
return;
|
||||
}
|
||||
reader = std::move(fileReader);
|
||||
}
|
||||
|
||||
_pathsIncluded.insert(fullPath.string());
|
||||
_included.push_back(std::move(fileReader));
|
||||
_included.push_back(std::move(reader));
|
||||
}
|
||||
|
||||
void Parser::processTopLevel()
|
||||
|
|
|
|||
|
|
@ -29,13 +29,13 @@ public:
|
|||
|
||||
void addDefinition(absl::string_view id, absl::string_view value);
|
||||
void parseFile(const fs::path& path);
|
||||
void parseString(absl::string_view sfzView);
|
||||
void parseString(const fs::path& path, absl::string_view sfzView);
|
||||
void parseVirtualFile(const fs::path& path, std::unique_ptr<Reader> reader);
|
||||
|
||||
void setRecursiveIncludeGuardEnabled(bool en) { _recursiveIncludeGuardEnabled = en; }
|
||||
void setMaximumIncludeDepth(size_t depth) { _maxIncludeDepth = depth; }
|
||||
|
||||
const fs::path& originalDirectory() const noexcept { return _originalDirectory; }
|
||||
void setOriginalDirectory(const fs::path& originalDirectory) noexcept;
|
||||
|
||||
typedef absl::flat_hash_set<std::string> IncludeFileSet;
|
||||
typedef absl::flat_hash_map<std::string, std::string> DefinitionSet;
|
||||
|
|
@ -63,7 +63,7 @@ public:
|
|||
void setListener(Listener* listener) noexcept { _listener = listener; }
|
||||
|
||||
private:
|
||||
void includeNewFile(const fs::path& path);
|
||||
void includeNewFile(const fs::path& path, std::unique_ptr<Reader> reader = nullptr);
|
||||
void processTopLevel();
|
||||
void processDirective();
|
||||
void processHeader();
|
||||
|
|
|
|||
|
|
@ -139,10 +139,9 @@ int FileReader::getNextStreamByte()
|
|||
return _fileStream.get();
|
||||
}
|
||||
|
||||
StringViewReader::StringViewReader(absl::string_view sfzView)
|
||||
: Reader({}), _sfzView(sfzView)
|
||||
StringViewReader::StringViewReader(const fs::path& filePath, absl::string_view sfzView)
|
||||
: Reader(filePath), _sfzView(sfzView)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
int StringViewReader::getNextStreamByte()
|
||||
|
|
|
|||
|
|
@ -124,7 +124,7 @@ private:
|
|||
*/
|
||||
class StringViewReader : public Reader {
|
||||
public:
|
||||
explicit StringViewReader(absl::string_view sfzView);
|
||||
explicit StringViewReader(const fs::path& filePath, absl::string_view sfzView);
|
||||
|
||||
protected:
|
||||
int getNextStreamByte() override;
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@
|
|||
#include "parser/Parser.h"
|
||||
#include <QApplication>
|
||||
#include <QTimer>
|
||||
#include <QTemporaryFile>
|
||||
#include <QFileInfo>
|
||||
#include <QDir>
|
||||
#include <QTextBlock>
|
||||
|
|
@ -114,14 +113,8 @@ void Application::requestParseCheck()
|
|||
void Application::runParseCheck()
|
||||
{
|
||||
QByteArray code = _ui.sfzEdit->toPlainText().toLatin1();
|
||||
|
||||
QTemporaryFile temp(QDir::tempPath() + "/parseXXXXXX.sfz");
|
||||
temp.open();
|
||||
temp.write(code);
|
||||
temp.flush();
|
||||
|
||||
_blockTextChanged = true;
|
||||
_parser.parseFile(temp.fileName().toStdString());
|
||||
_parser.parseString("/virtual.sfz", absl::string_view(code.data(), code.size()));
|
||||
_blockTextChanged = false;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -179,7 +179,7 @@ TEST_CASE("[Parsing] Empty")
|
|||
sfz::Parser parser;
|
||||
ParsingMocker mock;
|
||||
parser.setListener(&mock);
|
||||
parser.parseString("");
|
||||
parser.parseString("/empty.sfz", "");
|
||||
REQUIRE(mock.beginnings == 1);
|
||||
REQUIRE(mock.endings == 1);
|
||||
REQUIRE(mock.errors.empty());
|
||||
|
|
@ -201,7 +201,7 @@ TEST_CASE("[Parsing] Empty2")
|
|||
sfz::Parser parser;
|
||||
ParsingMocker mock;
|
||||
parser.setListener(&mock);
|
||||
parser.parseString(emptySfz);
|
||||
parser.parseString("/empty2.sfz", emptySfz);
|
||||
REQUIRE(mock.beginnings == 1);
|
||||
REQUIRE(mock.endings == 1);
|
||||
REQUIRE(mock.errors.empty());
|
||||
|
|
@ -224,7 +224,7 @@ TEST_CASE("[Parsing] Jpcima good region")
|
|||
sfz::Parser parser;
|
||||
ParsingMocker mock;
|
||||
parser.setListener(&mock);
|
||||
parser.parseString(R"(
|
||||
parser.parseString("/goodRegion.sfz", R"(
|
||||
<region> sample=*silence key=69
|
||||
sample=My Directory/My Wave.wav // path with spaces and a comment
|
||||
sample=My Directory/My Wave.wav key=69 // path with spaces, and other opcode following
|
||||
|
|
@ -256,7 +256,7 @@ void memberTestNew(absl::string_view member, absl::string_view opcode, absl::str
|
|||
sfz::Parser parser;
|
||||
ParsingMocker mock;
|
||||
parser.setListener(&mock);
|
||||
parser.parseString(absl::StrCat("<region> ", member));
|
||||
parser.parseString("/memberTestNew.sfz", absl::StrCat("<region> ", member));
|
||||
REQUIRE(mock.opcodes.size() == 1);
|
||||
REQUIRE(mock.headers.size() == 1);
|
||||
REQUIRE(mock.fullBlockHeaders.size() == 1);
|
||||
|
|
@ -296,7 +296,7 @@ TEST_CASE("[Parsing] bad headers")
|
|||
sfz::Parser parser;
|
||||
ParsingMocker mock;
|
||||
parser.setListener(&mock);
|
||||
parser.parseString(
|
||||
parser.parseString("/badHeaders.sfz",
|
||||
R"(<>
|
||||
<ab@cd> dummy_member=no
|
||||
)"
|
||||
|
|
@ -317,7 +317,7 @@ void defineTestNew(const std::string& directive, const std::string& variable, co
|
|||
sfz::Parser parser;
|
||||
ParsingMocker mock;
|
||||
parser.setListener(&mock);
|
||||
parser.parseString(directive);
|
||||
parser.parseString("/defineTestNew.sfz", directive);
|
||||
const auto defines = parser.getDefines();
|
||||
REQUIRE(defines.contains(variable));
|
||||
REQUIRE(defines.at(variable) == value);
|
||||
|
|
@ -342,7 +342,8 @@ TEST_CASE("[Parsing] Malformed includes")
|
|||
sfz::Parser parser;
|
||||
ParsingMocker mock;
|
||||
parser.setListener(&mock);
|
||||
parser.parseString(R"(#include "MyFileWhichDoesNotExist1.sfz
|
||||
parser.parseString("/malformedIncludes.sfz",
|
||||
R"(#include "MyFileWhichDoesNotExist1.sfz
|
||||
#include MyFileWhichDoesNotExist1.sfz)");
|
||||
REQUIRE(mock.errors.size() == 2);
|
||||
REQUIRE(mock.errors[0].start.lineNumber == 0);
|
||||
|
|
@ -362,7 +363,7 @@ TEST_CASE("[Parsing] Headers (new parser)")
|
|||
sfz::Parser parser;
|
||||
ParsingMocker mock;
|
||||
parser.setListener(&mock);
|
||||
parser.parseString("<header>param1=value1 param2=value2 <next>");
|
||||
parser.parseString("/headers.sfz", "<header>param1=value1 param2=value2 <next>");
|
||||
std::vector<std::vector<sfz::Opcode>> expectedMembers = {
|
||||
{{"param1", "value1"}, {"param2", "value2"}},
|
||||
{}
|
||||
|
|
@ -391,7 +392,7 @@ TEST_CASE("[Parsing] Headers (new parser)")
|
|||
sfz::Parser parser;
|
||||
ParsingMocker mock;
|
||||
parser.setListener(&mock);
|
||||
parser.parseString("<header>param1=value1 param2=value2");
|
||||
parser.parseString("/eolHeaderMatch.sfz", "<header>param1=value1 param2=value2");
|
||||
std::vector<std::vector<sfz::Opcode>> expectedMembers = {
|
||||
{{"param1", "value1"}, {"param2", "value2"}}
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue