From b1ce0425359b9920eca345e9d4bdb81543264d21 Mon Sep 17 00:00:00 2001 From: Jesse Beder Date: Mon, 27 Jul 2009 02:56:18 +0000 Subject: [PATCH] Collected pos, line, and column into a Mark struct --- include/exceptions.h | 37 ++++++++-------- include/node.h | 18 ++++---- include/nodeimpl.h | 4 +- src/exp.cpp | 10 ++--- src/map.cpp | 10 ++--- src/node.cpp | 11 +++-- src/parser.cpp | 8 ++-- src/scanner.cpp | 27 ++++++------ src/scanner.h | 7 +-- src/scanscalar.cpp | 20 ++++----- src/scantoken.cpp | 82 ++++++++++++++++++------------------ src/sequence.cpp | 8 ++-- src/simplekey.cpp | 12 +++--- src/stream.cpp | 10 ++--- src/stream.h | 11 ++++- src/token.h | 5 ++- yaml-reader/emittertests.cpp | 2 +- 17 files changed, 145 insertions(+), 137 deletions(-) diff --git a/include/exceptions.h b/include/exceptions.h index 2df88b6..b70c82a 100644 --- a/include/exceptions.h +++ b/include/exceptions.h @@ -1,5 +1,6 @@ #pragma once +#include "mark.h" #include #include #include @@ -60,16 +61,16 @@ namespace YAML class Exception: public std::exception { public: - Exception(int line_, int column_, const std::string& msg_) - : line(line_), column(column_), msg(msg_) { + Exception(const Mark& mark_, const std::string& msg_) + : mark(mark_), msg(msg_) { std::stringstream output; - output << "Error at line " << line+1 << ", column " << column+1 << ": " << msg; + output << "Error at line " << mark.line+1 << ", column " << mark.column+1 << ": " << msg; what_ = output.str(); } virtual ~Exception() throw() {} virtual const char *what() const throw() { return what_.c_str(); } - int line, column; + Mark mark; std::string msg; private: @@ -78,53 +79,53 @@ namespace YAML class ParserException: public Exception { public: - ParserException(int line_, int column_, const std::string& msg_) - : Exception(line_, column_, msg_) {} + ParserException(const Mark& mark_, const std::string& msg_) + : Exception(mark_, msg_) {} }; class RepresentationException: public Exception { public: - RepresentationException(int line_, int column_, const std::string& msg_) - : Exception(line_, column_, msg_) {} + RepresentationException(const Mark& mark_, const std::string& msg_) + : Exception(mark_, msg_) {} }; // representation exceptions class InvalidScalar: public RepresentationException { public: - InvalidScalar(int line_, int column_) - : RepresentationException(line_, column_, ErrorMsg::INVALID_SCALAR) {} + InvalidScalar(const Mark& mark_) + : RepresentationException(mark_, ErrorMsg::INVALID_SCALAR) {} }; class KeyNotFound: public RepresentationException { public: - KeyNotFound(int line_, int column_) - : RepresentationException(line_, column_, ErrorMsg::KEY_NOT_FOUND) {} + KeyNotFound(const Mark& mark_) + : RepresentationException(mark_, ErrorMsg::KEY_NOT_FOUND) {} }; template class TypedKeyNotFound: public KeyNotFound { public: - TypedKeyNotFound(int line_, int column_, const T& key_) - : KeyNotFound(line_, column_), key(key_) {} + TypedKeyNotFound(const Mark& mark_, const T& key_) + : KeyNotFound(mark_), key(key_) {} ~TypedKeyNotFound() throw() {} T key; }; template - TypedKeyNotFound MakeTypedKeyNotFound(int line, int column, const T& key) { - return TypedKeyNotFound (line, column, key); + TypedKeyNotFound MakeTypedKeyNotFound(const Mark& mark, const T& key) { + return TypedKeyNotFound (mark, key); } class BadDereference: public RepresentationException { public: BadDereference() - : RepresentationException(-1, -1, ErrorMsg::BAD_DEREFERENCE) {} + : RepresentationException(Mark::null(), ErrorMsg::BAD_DEREFERENCE) {} }; class EmitterException: public Exception { public: EmitterException(const std::string& msg_) - : Exception(-1, -1, msg_) {} + : Exception(Mark::null(), msg_) {} }; } diff --git a/include/node.h b/include/node.h index fd54c13..3ae77c3 100644 --- a/include/node.h +++ b/include/node.h @@ -1,14 +1,15 @@ #pragma once +#include "conversion.h" +#include "exceptions.h" +#include "iterator.h" +#include "mark.h" +#include "noncopyable.h" +#include "parserstate.h" +#include #include #include #include -#include "parserstate.h" -#include "exceptions.h" -#include "iterator.h" -#include "conversion.h" -#include "noncopyable.h" -#include namespace YAML { @@ -30,8 +31,7 @@ namespace YAML CONTENT_TYPE GetType() const; // file location of start of this node - int GetLine() const { return m_line; } - int GetColumn() const { return m_column; } + const Mark GetMark() const { return m_mark; } // accessors Iterator begin() const; @@ -85,7 +85,7 @@ namespace YAML void ParseAlias(Scanner *pScanner, const ParserState& state); private: - int m_line, m_column; + Mark m_mark; std::string m_anchor, m_tag; Content *m_pContent; bool m_alias; diff --git a/include/nodeimpl.h b/include/nodeimpl.h index 9bfc2d7..268176f 100644 --- a/include/nodeimpl.h +++ b/include/nodeimpl.h @@ -15,7 +15,7 @@ namespace YAML template inline void operator >> (const Node& node, T& value) { if(!node.Read(value)) - throw InvalidScalar(node.m_line, node.m_column); + throw InvalidScalar(node.m_mark); } template @@ -51,7 +51,7 @@ namespace YAML } } - throw MakeTypedKeyNotFound(m_line, m_column, key); + throw MakeTypedKeyNotFound(m_mark, key); } template diff --git a/src/exp.cpp b/src/exp.cpp index 7148acc..028b7d7 100644 --- a/src/exp.cpp +++ b/src/exp.cpp @@ -7,7 +7,7 @@ namespace YAML { namespace Exp { - unsigned ParseHex(const std::string& str, int line, int column) + unsigned ParseHex(const std::string& str, const Mark& mark) { unsigned value = 0; for(unsigned i=0;i= 0xD800 && value <= 0xDFFF) || value > 0x10FFFF) { std::stringstream msg; msg << ErrorMsg::INVALID_UNICODE << value; - throw ParserException(in.line, in.column, msg.str()); + throw ParserException(in.mark(), msg.str()); } // now break it up into chars @@ -107,7 +107,7 @@ namespace YAML } std::stringstream msg; - throw ParserException(in.line, in.column, ErrorMsg::INVALID_ESCAPE + ch); + throw ParserException(in.mark(), ErrorMsg::INVALID_ESCAPE + ch); } } } diff --git a/src/map.cpp b/src/map.cpp index 3565b70..46a6977 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -58,11 +58,11 @@ namespace YAML while(1) { if(pScanner->empty()) - throw ParserException(-1, -1, ErrorMsg::END_OF_MAP); + throw ParserException(Mark::null(), ErrorMsg::END_OF_MAP); Token token = pScanner->peek(); if(token.type != TT_KEY && token.type != TT_BLOCK_END) - throw ParserException(token.line, token.column, ErrorMsg::END_OF_MAP); + throw ParserException(token.mark, ErrorMsg::END_OF_MAP); pScanner->pop(); if(token.type == TT_BLOCK_END) @@ -91,7 +91,7 @@ namespace YAML while(1) { if(pScanner->empty()) - throw ParserException(-1, -1, ErrorMsg::END_OF_MAP_FLOW); + throw ParserException(Mark::null(), ErrorMsg::END_OF_MAP_FLOW); Token& token = pScanner->peek(); // first check for end @@ -102,7 +102,7 @@ namespace YAML // now it better be a key if(token.type != TT_KEY) - throw ParserException(token.line, token.column, ErrorMsg::END_OF_MAP_FLOW); + throw ParserException(token.mark, ErrorMsg::END_OF_MAP_FLOW); pScanner->pop(); @@ -122,7 +122,7 @@ namespace YAML if(nextToken.type == TT_FLOW_ENTRY) pScanner->pop(); else if(nextToken.type != TT_FLOW_MAP_END) - throw ParserException(nextToken.line, nextToken.column, ErrorMsg::END_OF_MAP_FLOW); + throw ParserException(nextToken.mark, ErrorMsg::END_OF_MAP_FLOW); // assign the map with the actual pointers m_data[pKey.release()] = pValue.release(); diff --git a/src/node.cpp b/src/node.cpp index f41af12..a1fdbd6 100644 --- a/src/node.cpp +++ b/src/node.cpp @@ -47,8 +47,7 @@ namespace YAML return; // save location - m_line = pScanner->peek().line; - m_column = pScanner->peek().column; + m_mark = pScanner->peek().mark; ParseHeader(pScanner, state); @@ -119,7 +118,7 @@ namespace YAML { Token& token = pScanner->peek(); if(m_tag != "") - throw ParserException(token.line, token.column, ErrorMsg::MULTIPLE_TAGS); + throw ParserException(token.mark, ErrorMsg::MULTIPLE_TAGS); m_tag = state.TranslateTag(token.value); @@ -132,7 +131,7 @@ namespace YAML { Token& token = pScanner->peek(); if(m_anchor != "") - throw ParserException(token.line, token.column, ErrorMsg::MULTIPLE_ANCHORS); + throw ParserException(token.mark, ErrorMsg::MULTIPLE_ANCHORS); m_anchor = token.value; m_alias = false; @@ -143,9 +142,9 @@ namespace YAML { Token& token = pScanner->peek(); if(m_anchor != "") - throw ParserException(token.line, token.column, ErrorMsg::MULTIPLE_ALIASES); + throw ParserException(token.mark, ErrorMsg::MULTIPLE_ALIASES); if(m_tag != "") - throw ParserException(token.line, token.column, ErrorMsg::ALIAS_CONTENT); + throw ParserException(token.mark, ErrorMsg::ALIAS_CONTENT); m_anchor = token.value; m_alias = true; diff --git a/src/parser.cpp b/src/parser.cpp index 6b49429..e3b088b 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -98,17 +98,17 @@ namespace YAML void Parser::HandleYamlDirective(Token *pToken) { if(pToken->params.size() != 1) - throw ParserException(pToken->line, pToken->column, ErrorMsg::YAML_DIRECTIVE_ARGS); + throw ParserException(pToken->mark, ErrorMsg::YAML_DIRECTIVE_ARGS); std::stringstream str(pToken->params[0]); str >> m_state.version.major; str.get(); str >> m_state.version.minor; if(!str || str.peek() != EOF) - throw ParserException(pToken->line, pToken->column, ErrorMsg::YAML_VERSION + pToken->params[0]); + throw ParserException(pToken->mark, ErrorMsg::YAML_VERSION + pToken->params[0]); if(m_state.version.major > 1) - throw ParserException(pToken->line, pToken->column, ErrorMsg::YAML_MAJOR_VERSION); + throw ParserException(pToken->mark, ErrorMsg::YAML_MAJOR_VERSION); // TODO: warning on major == 1, minor > 2? } @@ -118,7 +118,7 @@ namespace YAML void Parser::HandleTagDirective(Token *pToken) { if(pToken->params.size() != 2) - throw ParserException(pToken->line, pToken->column, ErrorMsg::TAG_DIRECTIVE_ARGS); + throw ParserException(pToken->mark, ErrorMsg::TAG_DIRECTIVE_ARGS); std::string handle = pToken->params[0], prefix = pToken->params[1]; m_state.tags[handle] = prefix; diff --git a/src/scanner.cpp b/src/scanner.cpp index c89b105..f4bf55e 100644 --- a/src/scanner.cpp +++ b/src/scanner.cpp @@ -98,7 +98,7 @@ namespace YAML VerifySimpleKey(); // maybe need to end some blocks - PopIndentTo(INPUT.column); + PopIndentTo(INPUT.column()); // ***** // And now branch based on the next few characters! @@ -108,14 +108,14 @@ namespace YAML if(!INPUT) return EndStream(); - if(INPUT.column == 0 && INPUT.peek() == Keys::Directive) + if(INPUT.column() == 0 && INPUT.peek() == Keys::Directive) return ScanDirective(); // document token - if(INPUT.column == 0 && Exp::DocStart.Matches(INPUT)) + if(INPUT.column() == 0 && Exp::DocStart.Matches(INPUT)) return ScanDocStart(); - if(INPUT.column == 0 && Exp::DocEnd.Matches(INPUT)) + if(INPUT.column() == 0 && Exp::DocEnd.Matches(INPUT)) return ScanDocEnd(); // flow start/end/entry @@ -158,7 +158,7 @@ namespace YAML return ScanPlainScalar(); // don't know what it is! - throw ParserException(INPUT.line, INPUT.column, ErrorMsg::UNKNOWN_TOKEN); + throw ParserException(INPUT.mark(), ErrorMsg::UNKNOWN_TOKEN); } // ScanToNextToken @@ -230,8 +230,8 @@ namespace YAML void Scanner::EndStream() { // force newline - if(INPUT.column > 0) - INPUT.column = 0; + if(INPUT.column() > 0) + INPUT.ResetColumn(); PopIndentTo(-1); VerifyAllSimpleKeys(); @@ -257,9 +257,9 @@ namespace YAML // now push m_indents.push(column); if(sequence) - m_tokens.push(Token(TT_BLOCK_SEQ_START, INPUT.line, INPUT.column)); + m_tokens.push(Token(TT_BLOCK_SEQ_START, INPUT.mark())); else - m_tokens.push(Token(TT_BLOCK_MAP_START, INPUT.line, INPUT.column)); + m_tokens.push(Token(TT_BLOCK_MAP_START, INPUT.mark())); return &m_tokens.back(); } @@ -276,7 +276,7 @@ namespace YAML // now pop away while(!m_indents.empty() && m_indents.top() > column) { m_indents.pop(); - m_tokens.push(Token(TT_BLOCK_END, INPUT.line, INPUT.column)); + m_tokens.push(Token(TT_BLOCK_END, INPUT.mark())); } } @@ -309,13 +309,12 @@ namespace YAML // . Does not parse any more tokens. void Scanner::ThrowParserException(const std::string& msg) const { - int line = -1, column = -1; + Mark mark = Mark::null(); if(!m_tokens.empty()) { const Token& token = m_tokens.front(); - line = token.line; - column = token.column; + mark = token.mark; } - throw ParserException(line, column, msg); + throw ParserException(mark, msg); } void Scanner::ClearAnchors() diff --git a/src/scanner.h b/src/scanner.h index f2f7df2..ffe1d5e 100644 --- a/src/scanner.h +++ b/src/scanner.h @@ -48,12 +48,13 @@ namespace YAML bool IsWhitespaceToBeEaten(char ch); struct SimpleKey { - SimpleKey(int pos_, int line_, int column_, int flowLevel_); + SimpleKey(const Mark& mark_, int flowLevel_); void Validate(); void Invalidate(); - - int pos, line, column, flowLevel; + + Mark mark; + int flowLevel; Token *pMapStart, *pKey; }; diff --git a/src/scanscalar.cpp b/src/scanscalar.cpp index 4649237..b4e33f7 100644 --- a/src/scanscalar.cpp +++ b/src/scanscalar.cpp @@ -32,11 +32,11 @@ namespace YAML break; // document indicator? - if(INPUT.column == 0 && Exp::DocIndicator.Matches(INPUT)) { + if(INPUT.column() == 0 && Exp::DocIndicator.Matches(INPUT)) { if(params.onDocIndicator == BREAK) break; else if(params.onDocIndicator == THROW) - throw ParserException(INPUT.line, INPUT.column, ErrorMsg::DOC_IN_SCALAR); + throw ParserException(INPUT.mark(), ErrorMsg::DOC_IN_SCALAR); } foundNonEmptyLine = true; @@ -62,12 +62,12 @@ namespace YAML // eof? if we're looking to eat something, then we throw if(!INPUT) { if(params.eatEnd) - throw ParserException(INPUT.line, INPUT.column, ErrorMsg::EOF_IN_SCALAR); + throw ParserException(INPUT.mark(), ErrorMsg::EOF_IN_SCALAR); break; } // doc indicator? - if(params.onDocIndicator == BREAK && INPUT.column == 0 && Exp::DocIndicator.Matches(INPUT)) + if(params.onDocIndicator == BREAK && INPUT.column() == 0 && Exp::DocIndicator.Matches(INPUT)) break; // are we done via character match? @@ -87,18 +87,18 @@ namespace YAML // Phase #3: scan initial spaces // first the required indentation - while(INPUT.peek() == ' ' && (INPUT.column < params.indent || (params.detectIndent && !foundNonEmptyLine))) + while(INPUT.peek() == ' ' && (INPUT.column() < params.indent || (params.detectIndent && !foundNonEmptyLine))) INPUT.eat(1); // update indent if we're auto-detecting if(params.detectIndent && !foundNonEmptyLine) - params.indent = std::max(params.indent, INPUT.column); + params.indent = std::max(params.indent, INPUT.column()); // and then the rest of the whitespace while(Exp::Blank.Matches(INPUT)) { // we check for tabs that masquerade as indentation - if(INPUT.peek() == '\t'&& INPUT.column < params.indent && params.onTabInIndentation == THROW) - throw ParserException(INPUT.line, INPUT.column, ErrorMsg::TAB_IN_INDENTATION); + if(INPUT.peek() == '\t'&& INPUT.column() < params.indent && params.onTabInIndentation == THROW) + throw ParserException(INPUT.mark(), ErrorMsg::TAB_IN_INDENTATION); if(!params.eatLeadingWhitespace) break; @@ -113,7 +113,7 @@ namespace YAML // for block scalars, we always start with a newline, so we should ignore it (not fold or keep) bool useNewLine = pastOpeningBreak; // and for folded scalars, we don't fold the very last newline to a space - if(params.fold && !emptyLine && INPUT.column < params.indent) + if(params.fold && !emptyLine && INPUT.column() < params.indent) useNewLine = false; if(useNewLine) { @@ -128,7 +128,7 @@ namespace YAML pastOpeningBreak = true; // are we done via indentation? - if(!emptyLine && INPUT.column < params.indent) { + if(!emptyLine && INPUT.column() < params.indent) { params.leadingSpaces = true; break; } diff --git a/src/scantoken.cpp b/src/scantoken.cpp index bb8373a..3699b4d 100644 --- a/src/scantoken.cpp +++ b/src/scantoken.cpp @@ -25,7 +25,7 @@ namespace YAML m_simpleKeyAllowed = false; // store pos and eat indicator - int line = INPUT.line, column = INPUT.column; + Mark mark = INPUT.mark(); INPUT.eat(1); // read name @@ -50,7 +50,7 @@ namespace YAML params.push_back(param); } - Token token(TT_DIRECTIVE, line, column); + Token token(TT_DIRECTIVE, mark); token.value = name; token.params = params; m_tokens.push(token); @@ -64,9 +64,9 @@ namespace YAML m_simpleKeyAllowed = false; // eat - int line = INPUT.line, column = INPUT.column; + Mark mark = INPUT.mark(); INPUT.eat(3); - m_tokens.push(Token(TT_DOC_START, line, column)); + m_tokens.push(Token(TT_DOC_START, mark)); } // DocEnd @@ -77,9 +77,9 @@ namespace YAML m_simpleKeyAllowed = false; // eat - int line = INPUT.line, column = INPUT.column; + Mark mark = INPUT.mark(); INPUT.eat(3); - m_tokens.push(Token(TT_DOC_END, line, column)); + m_tokens.push(Token(TT_DOC_END, mark)); } // FlowStart @@ -91,26 +91,26 @@ namespace YAML m_simpleKeyAllowed = true; // eat - int line = INPUT.line, column = INPUT.column; + Mark mark = INPUT.mark(); char ch = INPUT.get(); TOKEN_TYPE type = (ch == Keys::FlowSeqStart ? TT_FLOW_SEQ_START : TT_FLOW_MAP_START); - m_tokens.push(Token(type, line, column)); + m_tokens.push(Token(type, mark)); } // FlowEnd void Scanner::ScanFlowEnd() { if(m_flowLevel == 0) - throw ParserException(INPUT.line, INPUT.column, ErrorMsg::FLOW_END); + throw ParserException(INPUT.mark(), ErrorMsg::FLOW_END); m_flowLevel--; m_simpleKeyAllowed = false; // eat - int line = INPUT.line, column = INPUT.column; + Mark mark = INPUT.mark(); char ch = INPUT.get(); TOKEN_TYPE type = (ch == Keys::FlowSeqEnd ? TT_FLOW_SEQ_END : TT_FLOW_MAP_END); - m_tokens.push(Token(type, line, column)); + m_tokens.push(Token(type, mark)); } // FlowEntry @@ -119,9 +119,9 @@ namespace YAML m_simpleKeyAllowed = true; // eat - int line = INPUT.line, column = INPUT.column; + Mark mark = INPUT.mark(); INPUT.eat(1); - m_tokens.push(Token(TT_FLOW_ENTRY, line, column)); + m_tokens.push(Token(TT_FLOW_ENTRY, mark)); } // BlockEntry @@ -129,19 +129,19 @@ namespace YAML { // we better be in the block context! if(m_flowLevel > 0) - throw ParserException(INPUT.line, INPUT.column, ErrorMsg::BLOCK_ENTRY); + throw ParserException(INPUT.mark(), ErrorMsg::BLOCK_ENTRY); // can we put it here? if(!m_simpleKeyAllowed) - throw ParserException(INPUT.line, INPUT.column, ErrorMsg::BLOCK_ENTRY); + throw ParserException(INPUT.mark(), ErrorMsg::BLOCK_ENTRY); - PushIndentTo(INPUT.column, true); + PushIndentTo(INPUT.column(), true); m_simpleKeyAllowed = true; // eat - int line = INPUT.line, column = INPUT.column; + Mark mark = INPUT.mark(); INPUT.eat(1); - m_tokens.push(Token(TT_BLOCK_ENTRY, line, column)); + m_tokens.push(Token(TT_BLOCK_ENTRY, mark)); } // Key @@ -150,9 +150,9 @@ namespace YAML // handle keys diffently in the block context (and manage indents) if(m_flowLevel == 0) { if(!m_simpleKeyAllowed) - throw ParserException(INPUT.line, INPUT.column, ErrorMsg::MAP_KEY); + throw ParserException(INPUT.mark(), ErrorMsg::MAP_KEY); - PushIndentTo(INPUT.column, false); + PushIndentTo(INPUT.column(), false); } // can only put a simple key here if we're in block context @@ -162,9 +162,9 @@ namespace YAML m_simpleKeyAllowed = false; // eat - int line = INPUT.line, column = INPUT.column; + Mark mark = INPUT.mark(); INPUT.eat(1); - m_tokens.push(Token(TT_KEY, line, column)); + m_tokens.push(Token(TT_KEY, mark)); } // Value @@ -178,9 +178,9 @@ namespace YAML // handle values diffently in the block context (and manage indents) if(m_flowLevel == 0) { if(!m_simpleKeyAllowed) - throw ParserException(INPUT.line, INPUT.column, ErrorMsg::MAP_VALUE); + throw ParserException(INPUT.mark(), ErrorMsg::MAP_VALUE); - PushIndentTo(INPUT.column, false); + PushIndentTo(INPUT.column(), false); } // can only put a simple key here if we're in block context @@ -191,9 +191,9 @@ namespace YAML } // eat - int line = INPUT.line, column = INPUT.column; + Mark mark = INPUT.mark(); INPUT.eat(1); - m_tokens.push(Token(TT_VALUE, line, column)); + m_tokens.push(Token(TT_VALUE, mark)); } // AnchorOrAlias @@ -208,7 +208,7 @@ namespace YAML m_simpleKeyAllowed = false; // eat the indicator - int line = INPUT.line, column = INPUT.column; + Mark mark = INPUT.mark(); char indicator = INPUT.get(); alias = (indicator == Keys::Alias); @@ -218,14 +218,14 @@ namespace YAML // we need to have read SOMETHING! if(name.empty()) - throw ParserException(INPUT.line, INPUT.column, alias ? ErrorMsg::ALIAS_NOT_FOUND : ErrorMsg::ANCHOR_NOT_FOUND); + throw ParserException(INPUT.mark(), alias ? ErrorMsg::ALIAS_NOT_FOUND : ErrorMsg::ANCHOR_NOT_FOUND); // and needs to end correctly if(INPUT && !Exp::AnchorEnd.Matches(INPUT)) - throw ParserException(INPUT.line, INPUT.column, alias ? ErrorMsg::CHAR_IN_ALIAS : ErrorMsg::CHAR_IN_ANCHOR); + throw ParserException(INPUT.mark(), alias ? ErrorMsg::CHAR_IN_ALIAS : ErrorMsg::CHAR_IN_ANCHOR); // and we're done - Token token(alias ? TT_ALIAS : TT_ANCHOR, line, column); + Token token(alias ? TT_ALIAS : TT_ANCHOR, mark); token.value = name; m_tokens.push(token); } @@ -241,7 +241,7 @@ namespace YAML m_simpleKeyAllowed = false; // eat the indicator - int line = INPUT.line, column = INPUT.column; + Mark mark = INPUT.mark(); handle += INPUT.get(); // read the handle @@ -262,7 +262,7 @@ namespace YAML handle = "!"; } - Token token(TT_TAG, line, column); + Token token(TT_TAG, mark); token.value = handle; token.params.push_back(suffix); m_tokens.push(token); @@ -289,7 +289,7 @@ namespace YAML if(m_simpleKeyAllowed) InsertSimpleKey(); - int line = INPUT.line, column = INPUT.column; + Mark mark = INPUT.mark(); scalar = ScanScalar(INPUT, params); // can have a simple key only if we ended the scalar by starting a new line @@ -297,9 +297,9 @@ namespace YAML // finally, check and see if we ended on an illegal character //if(Exp::IllegalCharInScalar.Matches(INPUT)) - // throw ParserException(INPUT.line, INPUT.column, ErrorMsg::CHAR_IN_SCALAR); + // throw ParserException(INPUT.mark(), ErrorMsg::CHAR_IN_SCALAR); - Token token(TT_SCALAR, line, column); + Token token(TT_SCALAR, mark); token.value = scalar; m_tokens.push(token); } @@ -329,7 +329,7 @@ namespace YAML if(m_simpleKeyAllowed) InsertSimpleKey(); - int line = INPUT.line, column = INPUT.column; + Mark mark = INPUT.mark(); // now eat that opening quote INPUT.get(); @@ -338,7 +338,7 @@ namespace YAML scalar = ScanScalar(INPUT, params); m_simpleKeyAllowed = false; - Token token(TT_SCALAR, line, column); + Token token(TT_SCALAR, mark); token.value = scalar; m_tokens.push(token); } @@ -356,7 +356,7 @@ namespace YAML params.detectIndent = true; // eat block indicator ('|' or '>') - int line = INPUT.line, column = INPUT.column; + Mark mark = INPUT.mark(); char indicator = INPUT.get(); params.fold = (indicator == Keys::FoldedScalar); @@ -370,7 +370,7 @@ namespace YAML params.chomp = STRIP; else if(Exp::Digit.Matches(ch)) { if(ch == '0') - throw ParserException(INPUT.line, INPUT.column, ErrorMsg::ZERO_INDENT_IN_BLOCK); + throw ParserException(INPUT.mark(), ErrorMsg::ZERO_INDENT_IN_BLOCK); params.indent = ch - '0'; params.detectIndent = false; @@ -388,7 +388,7 @@ namespace YAML // if it's not a line break, then we ran into a bad character inline if(INPUT && !Exp::Break.Matches(INPUT)) - throw ParserException(INPUT.line, INPUT.column, ErrorMsg::CHAR_IN_BLOCK); + throw ParserException(INPUT.mark(), ErrorMsg::CHAR_IN_BLOCK); // set the initial indentation if(m_indents.top() >= 0) @@ -403,7 +403,7 @@ namespace YAML // simple keys always ok after block scalars (since we're gonna start a new line anyways) m_simpleKeyAllowed = true; - Token token(TT_SCALAR, line, column); + Token token(TT_SCALAR, mark); token.value = scalar; m_tokens.push(token); } diff --git a/src/sequence.cpp b/src/sequence.cpp index 30f6c99..65788fd 100644 --- a/src/sequence.cpp +++ b/src/sequence.cpp @@ -68,11 +68,11 @@ namespace YAML while(1) { if(pScanner->empty()) - throw ParserException(-1, -1, ErrorMsg::END_OF_SEQ); + throw ParserException(Mark::null(), ErrorMsg::END_OF_SEQ); Token token = pScanner->peek(); if(token.type != TT_BLOCK_ENTRY && token.type != TT_BLOCK_END) - throw ParserException(token.line, token.column, ErrorMsg::END_OF_SEQ); + throw ParserException(token.mark, ErrorMsg::END_OF_SEQ); pScanner->pop(); if(token.type == TT_BLOCK_END) @@ -111,7 +111,7 @@ namespace YAML while(1) { if(pScanner->empty()) - throw ParserException(-1, -1, ErrorMsg::END_OF_SEQ_FLOW); + throw ParserException(Mark::null(), ErrorMsg::END_OF_SEQ_FLOW); // first check for end if(pScanner->peek().type == TT_FLOW_SEQ_END) { @@ -129,7 +129,7 @@ namespace YAML if(token.type == TT_FLOW_ENTRY) pScanner->pop(); else if(token.type != TT_FLOW_SEQ_END) - throw ParserException(token.line, token.column, ErrorMsg::END_OF_SEQ_FLOW); + throw ParserException(token.mark, ErrorMsg::END_OF_SEQ_FLOW); } } diff --git a/src/simplekey.cpp b/src/simplekey.cpp index 667d683..f1c0a2b 100644 --- a/src/simplekey.cpp +++ b/src/simplekey.cpp @@ -6,8 +6,8 @@ namespace YAML { - Scanner::SimpleKey::SimpleKey(int pos_, int line_, int column_, int flowLevel_) - : pos(pos_), line(line_), column(column_), flowLevel(flowLevel_), pMapStart(0), pKey(0) + Scanner::SimpleKey::SimpleKey(const Mark& mark_, int flowLevel_) + : mark(mark_), flowLevel(flowLevel_), pMapStart(0), pKey(0) { } @@ -32,15 +32,15 @@ namespace YAML // and saves it on a stack. void Scanner::InsertSimpleKey() { - SimpleKey key(INPUT.pos, INPUT.line, INPUT.column, m_flowLevel); + SimpleKey key(INPUT.mark(), m_flowLevel); // first add a map start, if necessary - key.pMapStart = PushIndentTo(INPUT.column, false); + key.pMapStart = PushIndentTo(INPUT.column(), false); if(key.pMapStart) key.pMapStart->status = TS_UNVERIFIED; // then add the (now unverified) key - m_tokens.push(Token(TT_KEY, INPUT.line, INPUT.column)); + m_tokens.push(Token(TT_KEY, INPUT.mark())); key.pKey = &m_tokens.back(); key.pKey->status = TS_UNVERIFIED; @@ -78,7 +78,7 @@ namespace YAML isValid = false; // also needs to be less than 1024 characters and inline - if(INPUT.line != key.line || INPUT.pos - key.pos > 1024) + if(INPUT.line() != key.mark.line || INPUT.pos() - key.mark.pos > 1024) isValid = false; // invalidate key diff --git a/src/stream.cpp b/src/stream.cpp index 1041654..5cc9ea9 100644 --- a/src/stream.cpp +++ b/src/stream.cpp @@ -179,7 +179,7 @@ namespace YAML } Stream::Stream(std::istream& input) - : pos(0), line(0), column(0), m_input(input), m_nPushedBack(0), + : m_input(input), m_nPushedBack(0), m_pPrefetched(new unsigned char[YAML_PREFETCH_SIZE]), m_nPrefetchedAvailable(0), m_nPrefetchedUsed(0) { @@ -248,11 +248,11 @@ namespace YAML { char ch = peek(); AdvanceCurrent(); - column++; + m_mark.column++; if(ch == '\n') { - column = 0; - line++; + m_mark.column = 0; + m_mark.line++; } return ch; @@ -282,7 +282,7 @@ namespace YAML if (!m_readahead.empty()) { m_readahead.pop_front(); - ++pos; + m_mark.pos++; } ReadAheadTo(0); diff --git a/src/stream.h b/src/stream.h index 697e1b9..dd5add9 100644 --- a/src/stream.h +++ b/src/stream.h @@ -1,6 +1,7 @@ #pragma once #include "noncopyable.h" +#include "mark.h" #include #include #include @@ -28,13 +29,19 @@ namespace YAML void eat(int n = 1); static char eof() { return 0x04; } + + const Mark mark() const { return m_mark; } + int pos() const { return m_mark.pos; } + int line() const { return m_mark.line; } + int column() const { return m_mark.column; } + void ResetColumn() { m_mark.column = 0; } - int pos, line, column; - private: enum CharacterSet {utf8, utf16le, utf16be, utf32le, utf32be}; std::istream& m_input; + Mark m_mark; + CharacterSet m_charSet; unsigned char m_bufPushback[MAX_PARSER_PUSHBACK]; mutable size_t m_nPushedBack; diff --git a/src/token.h b/src/token.h index 8aec243..6fae451 100644 --- a/src/token.h +++ b/src/token.h @@ -1,5 +1,6 @@ #pragma once +#include "mark.h" #include #include #include @@ -50,7 +51,7 @@ namespace YAML }; struct Token { - Token(TOKEN_TYPE type_, int line_, int column_): status(TS_VALID), type(type_), line(line_), column(column_) {} + Token(TOKEN_TYPE type_, const Mark& mark_): status(TS_VALID), type(type_), mark(mark_) {} friend std::ostream& operator << (std::ostream& out, const Token& token) { out << TokenNames[token.type] << std::string(": ") << token.value; @@ -61,7 +62,7 @@ namespace YAML TOKEN_STATUS status; TOKEN_TYPE type; - int line, column; + Mark mark; std::string value; std::vector params; }; diff --git a/yaml-reader/emittertests.cpp b/yaml-reader/emittertests.cpp index 8836c58..1b8e786 100644 --- a/yaml-reader/emittertests.cpp +++ b/yaml-reader/emittertests.cpp @@ -217,7 +217,7 @@ namespace Test out << YAML::Literal << "literal scalar\nthat may span\nmany, many\nlines and have \"whatever\" crazy\tsymbols that we like"; out << YAML::EndSeq; - desiredOutput = "- simple scalar\n- 'explicit single-quoted scalar'\n- \"explicit double-quoted scalar\"\n- \"auto-detected\\xadouble-quoted scalar\"\n- a non-\"auto-detected\" double-quoted scalar\n- |\n literal scalar\n that may span\n many, many\n lines and have \"whatever\" crazy\tsymbols that we like"; + desiredOutput = "- simple scalar\n- 'explicit single-quoted scalar'\n- \"explicit double-quoted scalar\"\n- \"auto-detected\\x0adouble-quoted scalar\"\n- a non-\"auto-detected\" double-quoted scalar\n- |\n literal scalar\n that may span\n many, many\n lines and have \"whatever\" crazy\tsymbols that we like"; } void AutoLongKeyScalar(YAML::Emitter& out, std::string& desiredOutput)