Преглед изворни кода

Properly report line numbers for style sheet parser errors.

Michael Ragazzon пре 6 година
родитељ
комит
1f8eb1e99e

+ 4 - 1
Include/RmlUi/Core/BaseXMLParser.h

@@ -62,7 +62,9 @@ class RMLUICORE_API BaseXMLParser
 
 		/// Get the line number in the stream.
 		/// @return The line currently being processed in the XML stream.
-		int GetLineNumber();
+		int GetLineNumber() const;
+		/// Get the line number of the last open tag in the stream.
+		int GetLineNumberOpenTag() const;
 
 		/// Called when the parser finds the beginning of an element tag.
 		virtual void HandleElementStart(const String& name, const XMLAttributes& attributes);
@@ -104,6 +106,7 @@ class RMLUICORE_API BaseXMLParser
 		int buffer_size;
 		int buffer_used;
 		int line_number;
+		int line_number_open_tag;
 		int open_tag_depth;
 
 		// The element attributes being read.

+ 1 - 1
Include/RmlUi/Core/StyleSheet.h

@@ -80,7 +80,7 @@ public:
 	virtual ~StyleSheet();
 
 	/// Loads a style from a CSS definition.
-	bool LoadStyleSheet(Stream* stream);
+	bool LoadStyleSheet(Stream* stream, int begin_line_number = 1);
 
 	/// Combines this style sheet with another one, producing a new sheet.
 	SharedPtr<StyleSheet> CombineStyleSheet(const StyleSheet& sheet) const;

+ 10 - 2
Source/Core/BaseXMLParser.cpp

@@ -76,11 +76,16 @@ void BaseXMLParser::Parse(Stream* stream)
 }
 
 // Get the current file line number
-int BaseXMLParser::GetLineNumber()
+int BaseXMLParser::GetLineNumber() const
 {
 	return line_number;
 }
 
+int BaseXMLParser::GetLineNumberOpenTag() const
+{
+	return line_number_open_tag;
+}
+
 // Called when the parser finds the beginning of an element tag.
 void BaseXMLParser::HandleElementStart(const String& RMLUI_UNUSED_PARAMETER(name), const XMLAttributes& RMLUI_UNUSED_PARAMETER(attributes))
 {
@@ -112,6 +117,7 @@ void BaseXMLParser::ReadHeader()
 void BaseXMLParser::ReadBody()
 {
 	open_tag_depth = 0;
+	line_number_open_tag = 0;
 
 	for(;;)
 	{
@@ -148,7 +154,9 @@ void BaseXMLParser::ReadBody()
 		}
 		else
 		{
-			if (!ReadOpenTag())
+			if (ReadOpenTag())
+				line_number_open_tag = line_number;
+			else
 				break;
 		}
 	}

+ 1 - 0
Source/Core/DocumentHeader.cpp

@@ -45,6 +45,7 @@ void DocumentHeader::MergeHeader(const DocumentHeader& header)
 
 	// Combine internal data	
 	rcss_inline.insert(rcss_inline.end(), header.rcss_inline.begin(), header.rcss_inline.end());	
+	rcss_inline_line_numbers.insert(rcss_inline_line_numbers.end(), header.rcss_inline_line_numbers.begin(), header.rcss_inline_line_numbers.end());
 	scripts_inline.insert(scripts_inline.end(), header.scripts_inline.begin(), header.scripts_inline.end());
 	
 	// Combine external data, keeping relative paths

+ 3 - 0
Source/Core/DocumentHeader.h

@@ -34,6 +34,8 @@
 namespace Rml {
 namespace Core {
 
+using LineNumberList = std::vector<int>;
+
 /**
 	The document header struct contains the
 	header details gathered from an XML document parse.
@@ -53,6 +55,7 @@ public:
 
 	/// Inline RCSS definitions
 	StringList rcss_inline;
+	LineNumberList rcss_inline_line_numbers;
 	/// External RCSS definitions that should be loaded
 	StringList rcss_external;
 

+ 1 - 1
Source/Core/ElementDocument.cpp

@@ -104,7 +104,7 @@ void ElementDocument::ProcessHeader(const DocumentHeader* document_header)
 			auto stream = std::make_unique<StreamMemory>((const byte*) header.rcss_inline[i].c_str(), header.rcss_inline[i].size());
 			stream->SetSourceURL(document_header->source);
 
-			if (inline_sheet->LoadStyleSheet(stream.get()))
+			if (inline_sheet->LoadStyleSheet(stream.get(), header.rcss_inline_line_numbers[i]))
 			{
 				if (new_style_sheet)
 				{

+ 2 - 2
Source/Core/StyleSheet.cpp

@@ -58,10 +58,10 @@ StyleSheet::~StyleSheet()
 {
 }
 
-bool StyleSheet::LoadStyleSheet(Stream* stream)
+bool StyleSheet::LoadStyleSheet(Stream* stream, int begin_line_number)
 {
 	StyleSheetParser parser;
-	specificity_offset = parser.Parse(root.get(), stream, *this, keyframes, decorator_map, spritesheet_list);
+	specificity_offset = parser.Parse(root.get(), stream, *this, keyframes, decorator_map, spritesheet_list, begin_line_number);
 	return specificity_offset >= 0;
 }
 

+ 2 - 2
Source/Core/StyleSheetParser.cpp

@@ -319,10 +319,10 @@ bool StyleSheetParser::ParseDecoratorBlock(const String& at_name, DecoratorSpeci
 	return true;
 }
 
-int StyleSheetParser::Parse(StyleSheetNode* node, Stream* _stream, const StyleSheet& style_sheet, KeyframesMap& keyframes, DecoratorSpecificationMap& decorator_map, SpritesheetList& spritesheet_list)
+int StyleSheetParser::Parse(StyleSheetNode* node, Stream* _stream, const StyleSheet& style_sheet, KeyframesMap& keyframes, DecoratorSpecificationMap& decorator_map, SpritesheetList& spritesheet_list, int begin_line_number)
 {
 	int rule_count = 0;
-	line_number = 0;
+	line_number = begin_line_number;
 	stream = _stream;
 	stream_file_name = Replace(stream->GetSourceURL().GetURL(), '|', ':');
 

+ 1 - 1
Source/Core/StyleSheetParser.h

@@ -53,7 +53,7 @@ public:
 	/// @param node The root node the stream will be parsed into
 	/// @param stream The stream to read
 	/// @return The number of parsed rules, or -1 if an error occured.
-	int Parse(StyleSheetNode* node, Stream* stream, const StyleSheet& style_sheet, KeyframesMap& keyframes, DecoratorSpecificationMap& decorator_map, SpritesheetList& spritesheet_list);
+	int Parse(StyleSheetNode* node, Stream* stream, const StyleSheet& style_sheet, KeyframesMap& keyframes, DecoratorSpecificationMap& decorator_map, SpritesheetList& spritesheet_list, int begin_line_number);
 
 	/// Parses the given string into the property dictionary
 	/// @param parsed_properties The properties dictionary the properties will be read into

+ 3 - 0
Source/Core/XMLNodeHandlerHead.cpp

@@ -133,7 +133,10 @@ bool XMLNodeHandlerHead::ElementData(XMLParser* parser, const String& data)
 
 	// Store an inline style
 	if (tag == "style" && data.size() > 0)
+	{
 		parser->GetDocumentHeader()->rcss_inline.push_back(data);
+		parser->GetDocumentHeader()->rcss_inline_line_numbers.push_back(parser->GetLineNumberOpenTag());
+	}
 
 	return true;
 }