From 6decad0b8e7e369bd8215f31a45dd3eae982d2a9 Mon Sep 17 00:00:00 2001 From: Andreas Stöckel Date: Wed, 21 Jan 2015 01:17:49 +0100 Subject: Some further refactoring -- renamed Scope to ParserScope, got rid of parser namespace, added new functionality to RegistryClass, wrote documentation, added function for extracting file extensions to Utils --- src/plugins/css/CSSParser.cpp | 8 +++----- src/plugins/css/CSSParser.hpp | 20 +++----------------- src/plugins/xml/XmlParser.cpp | 12 ++---------- src/plugins/xml/XmlParser.hpp | 18 ++---------------- 4 files changed, 10 insertions(+), 48 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/css/CSSParser.cpp b/src/plugins/css/CSSParser.cpp index 40486cc..8cb41ea 100644 --- a/src/plugins/css/CSSParser.cpp +++ b/src/plugins/css/CSSParser.cpp @@ -19,10 +19,9 @@ #include "CSSParser.hpp" #include +#include namespace ousia { -namespace parser { -namespace css { // CSS code tokens static const int CURLY_OPEN = 1; @@ -75,7 +74,7 @@ static const std::map CSS_DESCRIPTORS = { {ESCAPE, {CodeTokenMode::ESCAPE, ESCAPE}}, {LINEBREAK, {CodeTokenMode::LINEBREAK, LINEBREAK}}}; -Rooted CSSParser::parse(CharReader &reader, ParserContext &ctx) +Rooted CSSParser::doParse(CharReader &reader, ParserContext &ctx) { CodeTokenizer tokenizer{reader, CSS_ROOT, CSS_DESCRIPTORS}; tokenizer.ignoreComments = true; @@ -362,5 +361,4 @@ bool CSSParser::expect(int expectedType, CodeTokenizer &tokenizer, Token &t, return true; } } -} -} + diff --git a/src/plugins/css/CSSParser.hpp b/src/plugins/css/CSSParser.hpp index 1ec54f5..c6594f6 100644 --- a/src/plugins/css/CSSParser.hpp +++ b/src/plugins/css/CSSParser.hpp @@ -24,6 +24,7 @@ * * @author Benjamin Paassen - bpaassen@techfak.uni-bielefeld.de */ + #ifndef _OUSIA_CSS_PARSER_HPP_ #define _OUSIA_CSS_PARSER_HPP_ @@ -36,8 +37,6 @@ #include namespace ousia { -namespace parser { -namespace css { /** * This is a context free, recursive parser for a subset of the CSS3 language @@ -139,7 +138,7 @@ private: bool expect(int expectedType, CodeTokenizer &tokenizer, Token &t, bool force, ParserContext &ctx); -public: +protected: /** * This parses the given input as CSS content as specified by the grammar * seen above. The return value is a Rooted reference to the root of the @@ -157,21 +156,8 @@ public: * @return returns the root node of the resulting SelectorTree. For more * information on the return conventions consult the Parser.hpp. */ - Rooted parse(CharReader &reader, ParserContext &ctx) override; - - using Parser::parse; - - /** - * As befits a class called CSSParser, this Parser parses CSS. - */ - std::set mimetypes() - { - std::set out{"text/css"}; - return out; - } + Rooted doParse(CharReader &reader, ParserContext &ctx) override; }; } -} -} #endif diff --git a/src/plugins/xml/XmlParser.cpp b/src/plugins/xml/XmlParser.cpp index 434a72c..ef738d8 100644 --- a/src/plugins/xml/XmlParser.cpp +++ b/src/plugins/xml/XmlParser.cpp @@ -25,13 +25,12 @@ #include #include #include +#include #include #include "XmlParser.hpp" namespace ousia { -namespace parser { -namespace xml { using namespace ousia::model; @@ -291,12 +290,7 @@ static void xmlCharacterDataHandler(void *p, const XML_Char *s, int len) /* Class XmlParser */ -std::set XmlParser::mimetypes() -{ - return std::set{{"text/vnd.ousia.oxm", "text/vnd.ousia.oxd"}}; -} - -Rooted XmlParser::parse(CharReader &reader, ParserContext &ctx) +Rooted XmlParser::doParse(CharReader &reader, ParserContext &ctx) { // Create the parser object ScopedExpatXmlParser p{"UTF-8"}; @@ -346,6 +340,4 @@ Rooted XmlParser::parse(CharReader &reader, ParserContext &ctx) return nullptr; } } -} -} diff --git a/src/plugins/xml/XmlParser.hpp b/src/plugins/xml/XmlParser.hpp index 62f0128..3c0ffb7 100644 --- a/src/plugins/xml/XmlParser.hpp +++ b/src/plugins/xml/XmlParser.hpp @@ -31,23 +31,13 @@ #include namespace ousia { -namespace parser { -namespace xml { /** * The XmlParser class implements parsing the various types of Ousía XML * documents using the expat stream XML parser. */ class XmlParser : public Parser { -public: - /** - * Returns the mimetype supported by the XmlParser which is - * "text/vnd.ousia.oxm" and "text/vnd.ousia.oxd". - * - * @return a list containing the mimetype supported by Ousía. - */ - std::set mimetypes() override; - +protected: /** * Parses the given input stream as XML file and returns the parsed * top-level node. @@ -56,13 +46,9 @@ public: * @param ctx is a reference to the ParserContext instance that should be * used. */ - Rooted parse(CharReader &reader, ParserContext &ctx) override; - - using Parser::parse; + Rooted doParse(CharReader &reader, ParserContext &ctx) override; }; -} -} } #endif /* _OUSIA_XML_PARSER_HPP_ */ -- cgit v1.2.3 From 3c659c2737b26d8ee28c727b277325852df8dd09 Mon Sep 17 00:00:00 2001 From: Andreas Stöckel Date: Wed, 21 Jan 2015 01:24:37 +0100 Subject: Do only perform relative file lookups if a relative path is given (to allow users to include files without accidently including a global resource) --- src/plugins/filesystem/FileLocator.cpp | 5 +++++ test/plugins/filesystem/FileLocatorTest.cpp | 20 ++++++++++++++++++++ testdata/filesystem/b/d.txt | 1 + 3 files changed, 26 insertions(+) create mode 100644 testdata/filesystem/b/d.txt (limited to 'src/plugins') diff --git a/src/plugins/filesystem/FileLocator.cpp b/src/plugins/filesystem/FileLocator.cpp index 467363b..af5244c 100644 --- a/src/plugins/filesystem/FileLocator.cpp +++ b/src/plugins/filesystem/FileLocator.cpp @@ -143,6 +143,11 @@ bool FileLocator::doLocate(Resource &resource, const std::string &path, } } + // If the path starts with "./" only perform relative lookups! + if (path.substr(0, 2) == "./") { + return false; + } + // Otherwise look in the search paths, search backwards, last defined search // paths have a higher precedence auto it = searchPaths.find(type); diff --git a/test/plugins/filesystem/FileLocatorTest.cpp b/test/plugins/filesystem/FileLocatorTest.cpp index 17d43dd..beb091d 100644 --- a/test/plugins/filesystem/FileLocatorTest.cpp +++ b/test/plugins/filesystem/FileLocatorTest.cpp @@ -142,6 +142,26 @@ TEST(FileLocator, testLocate) assert_not_located(locator, "c.txt", "", ResourceType::SCRIPT); } +TEST(FileLocator, testLocateRelative) +{ + FileLocator locator; + locator.addUnittestSearchPath("filesystem"); + + // Add the respective search path + locator.addUnittestSearchPath("filesystem/b"); + + Resource resA, resC; + ASSERT_TRUE(locator.locate(resA, "a.txt")); + ASSERT_TRUE(locator.locate(resC, "c.txt")); + + Resource resD; + ASSERT_TRUE(locator.locate(resD, "d.txt")); + ASSERT_TRUE(locator.locate(resD, "d.txt", ResourceType::UNKNOWN, resA)); + ASSERT_TRUE(locator.locate(resD, "d.txt", ResourceType::UNKNOWN, resC)); + ASSERT_FALSE(locator.locate(resD, "./d.txt", ResourceType::UNKNOWN, resA)); + ASSERT_TRUE(locator.locate(resD, "./d.txt", ResourceType::UNKNOWN, resC)); +} + TEST(FileLocator, testStream) { FileLocator locator; diff --git a/testdata/filesystem/b/d.txt b/testdata/filesystem/b/d.txt new file mode 100644 index 0000000..3e676fe --- /dev/null +++ b/testdata/filesystem/b/d.txt @@ -0,0 +1 @@ +file d -- cgit v1.2.3 From b3ebc84c8dfa7379a3977ed7305fd7cf7fdd8ee7 Mon Sep 17 00:00:00 2001 From: Andreas Stöckel Date: Thu, 22 Jan 2015 02:43:13 +0100 Subject: Improved FileLocator --- src/plugins/filesystem/FileLocator.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/filesystem/FileLocator.cpp b/src/plugins/filesystem/FileLocator.cpp index af5244c..6804c6d 100644 --- a/src/plugins/filesystem/FileLocator.cpp +++ b/src/plugins/filesystem/FileLocator.cpp @@ -131,7 +131,7 @@ bool FileLocator::doLocate(Resource &resource, const std::string &path, base /= path; // If we already found a fitting resource there, use that. - if (fs::exists(base)) { + if (fs::exists(base) && fs::is_file(base)) { std::string location = fs::canonical(base).generic_string(); #ifdef FILELOCATOR_DEBUG_PRINT std::cout << "FileLocator: Found \"" << path << "\" at " @@ -143,8 +143,8 @@ bool FileLocator::doLocate(Resource &resource, const std::string &path, } } - // If the path starts with "./" only perform relative lookups! - if (path.substr(0, 2) == "./") { + // If the path starts with "./" or "../" only perform relative lookups! + if (path.substr(0, 2) == "./" || path.substr(0, 3) == "../") { return false; } @@ -159,7 +159,7 @@ bool FileLocator::doLocate(Resource &resource, const std::string &path, #endif fs::path p{*it}; p /= path; - if (fs::exists(p)) { + if (fs::exists(p) && fs::is_file(p)) { std::string location = fs::canonical(p).generic_string(); #ifdef FILELOCATOR_DEBUG_PRINT std::cout << "FileLocator: Found \"" << path << "\" in " -- cgit v1.2.3 From 2fbb15a2d80b878af1919fea7331c945d6ab43a0 Mon Sep 17 00:00:00 2001 From: Andreas Stöckel Date: Fri, 23 Jan 2015 15:28:39 +0100 Subject: replaced nonexistant is_file with is_regular_file --- src/plugins/filesystem/FileLocator.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/filesystem/FileLocator.cpp b/src/plugins/filesystem/FileLocator.cpp index 6804c6d..356394e 100644 --- a/src/plugins/filesystem/FileLocator.cpp +++ b/src/plugins/filesystem/FileLocator.cpp @@ -131,7 +131,7 @@ bool FileLocator::doLocate(Resource &resource, const std::string &path, base /= path; // If we already found a fitting resource there, use that. - if (fs::exists(base) && fs::is_file(base)) { + if (fs::exists(base) && fs::is_regular_file(base)) { std::string location = fs::canonical(base).generic_string(); #ifdef FILELOCATOR_DEBUG_PRINT std::cout << "FileLocator: Found \"" << path << "\" at " @@ -159,7 +159,7 @@ bool FileLocator::doLocate(Resource &resource, const std::string &path, #endif fs::path p{*it}; p /= path; - if (fs::exists(p) && fs::is_file(p)) { + if (fs::exists(p) && fs::is_regular_file(p)) { std::string location = fs::canonical(p).generic_string(); #ifdef FILELOCATOR_DEBUG_PRINT std::cout << "FileLocator: Found \"" << path << "\" in " -- cgit v1.2.3 From 31873a51b21ca8d549c172f9e773818356021a55 Mon Sep 17 00:00:00 2001 From: Andreas Stöckel Date: Fri, 23 Jan 2015 15:30:07 +0100 Subject: Adapted XMLParser to new SourceLocation --- src/plugins/xml/XmlParser.cpp | 40 +++++++++++++++++++++++++--------------- 1 file changed, 25 insertions(+), 15 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/xml/XmlParser.cpp b/src/plugins/xml/XmlParser.cpp index ef738d8..78d9df8 100644 --- a/src/plugins/xml/XmlParser.cpp +++ b/src/plugins/xml/XmlParser.cpp @@ -131,11 +131,12 @@ public: !(defaultValue.isObject() && defaultValue.asObject() == nullptr); Rooted structType = scope().getLeaf().cast(); - Rooted attribute = structType->createAttribute( - name, defaultValue, optional, logger()); + Rooted attribute = + structType->createAttribute(name, defaultValue, optional, logger()); // Try to resolve the type - scope().resolve(type, logger(), + scope().resolve( + type, logger(), [attribute](Handle type, Logger &logger) mutable { attribute->setType(type, logger); }, @@ -234,16 +235,23 @@ public: /* Adapter Expat -> ParserStack */ +struct XMLParserUserData { + SourceId sourceId; +}; + static SourceLocation syncLoggerPosition(XML_Parser p) { + // Fetch the parser stack and the associated user data + ParserStack *stack = static_cast(XML_GetUserData(p)); + XMLParserUserData *ud = + static_cast(stack->getUserData()); + // Fetch the current location in the XML file - int line = XML_GetCurrentLineNumber(p); - int column = XML_GetCurrentColumnNumber(p); size_t offs = XML_GetCurrentByteIndex(p); - SourceLocation loc{line, column, offs}; - // Update the default location of the current logger instance - ParserStack *stack = static_cast(XML_GetUserData(p)); + // Build the source location and update the default location of the current + // logger instance + SourceLocation loc{ud->sourceId, offs}; stack->getContext().logger.setDefaultLocation(loc); return loc; } @@ -270,9 +278,9 @@ static void xmlStartElementHandler(void *p, const XML_Char *name, static void xmlEndElementHandler(void *p, const XML_Char *name) { XML_Parser parser = static_cast(p); - syncLoggerPosition(parser); - ParserStack *stack = static_cast(XML_GetUserData(parser)); + + syncLoggerPosition(parser); stack->end(); } @@ -297,7 +305,10 @@ Rooted XmlParser::doParse(CharReader &reader, ParserContext &ctx) // Create the parser stack instance and pass the reference to the state // machine descriptor - ParserStack stack{ctx, XML_HANDLERS}; + XMLParserUserData data; + data.sourceId = reader.getSourceId(); + + ParserStack stack{ctx, XML_HANDLERS, &data}; XML_SetUserData(&p, &stack); XML_UseParserAsHandlerArg(&p); @@ -321,15 +332,14 @@ Rooted XmlParser::doParse(CharReader &reader, ParserContext &ctx) // Parse the data and handle any XML error if (!XML_ParseBuffer(&p, bytesRead, bytesRead == 0)) { - // Fetch the current line number and column - int line = XML_GetCurrentLineNumber(&p); - int column = XML_GetCurrentColumnNumber(&p); + // Fetch the xml parser byte offset size_t offs = XML_GetCurrentByteIndex(&p); // Throw a corresponding exception XML_Error code = XML_GetErrorCode(&p); std::string msg = std::string{XML_ErrorString(code)}; - throw LoggableException{"XML: " + msg, line, column, offs}; + throw LoggableException{"XML: " + msg, + SourceLocation{reader.getSourceId(), offs}}; } // Abort once there are no more bytes in the stream -- cgit v1.2.3