Skip to content

Commit

Permalink
Fixed several bugs from the new file i/o setup.
Browse files Browse the repository at this point in the history
In particular:
1. Windows CR/LF weren't read properly (issue jbeder#11)
2. Scanning wasn't reading EOF properly
3. Documents may be empty (this was old, I think)
Also fixed some VS2008 warnings on /W4.
  • Loading branch information
jbeder committed Feb 7, 2009
1 parent f9c0725 commit 9d0e0c6
Show file tree
Hide file tree
Showing 13 changed files with 85 additions and 63 deletions.
34 changes: 17 additions & 17 deletions src/content.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,31 +25,31 @@ namespace YAML
virtual void Parse(Scanner *pScanner, const ParserState& state) = 0;
virtual void Write(std::ostream& out, int indent, bool startedLine, bool onlyOneCharOnLine) = 0;

virtual bool GetBegin(std::vector <Node *>::const_iterator& it) const { return false; }
virtual bool GetBegin(std::map <Node *, Node *, ltnode>::const_iterator& it) const { return false; }
virtual bool GetEnd(std::vector <Node *>::const_iterator& it) const { return false; }
virtual bool GetEnd(std::map <Node *, Node *, ltnode>::const_iterator& it) const { return false; }
virtual Node *GetNode(unsigned i) const { return 0; }
virtual bool GetBegin(std::vector <Node *>::const_iterator&) const { return false; }
virtual bool GetBegin(std::map <Node *, Node *, ltnode>::const_iterator&) const { return false; }
virtual bool GetEnd(std::vector <Node *>::const_iterator&) const { return false; }
virtual bool GetEnd(std::map <Node *, Node *, ltnode>::const_iterator&) const { return false; }
virtual Node *GetNode(unsigned) const { return 0; }
virtual unsigned GetSize() const { return 0; }
virtual bool IsScalar() const { return false; }
virtual bool IsMap() const { return false; }
virtual bool IsSequence() const { return false; }

// extraction
virtual bool Read(std::string& s) const { return false; }
virtual bool Read(int& i) const { return false; }
virtual bool Read(unsigned& u) const { return false; }
virtual bool Read(long& l) const { return false; }
virtual bool Read(float& f) const { return false; }
virtual bool Read(double& d) const { return false; }
virtual bool Read(char& c) const { return false; }
virtual bool Read(bool& b) const { return false; }
virtual bool Read(std::string&) const { return false; }
virtual bool Read(int&) const { return false; }
virtual bool Read(unsigned&) const { return false; }
virtual bool Read(long&) const { return false; }
virtual bool Read(float&) const { return false; }
virtual bool Read(double&) const { return false; }
virtual bool Read(char&) const { return false; }
virtual bool Read(bool&) const { return false; }

// ordering
virtual int Compare(Content *pContent) { return 0; }
virtual int Compare(Scalar *pScalar) { return 0; }
virtual int Compare(Sequence *pSeq) { return 0; }
virtual int Compare(Map *pMap) { return 0; }
virtual int Compare(Content *) { return 0; }
virtual int Compare(Scalar *) { return 0; }
virtual int Compare(Sequence *) { return 0; }
virtual int Compare(Map *) { return 0; }

protected:
};
Expand Down
4 changes: 2 additions & 2 deletions src/map.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ namespace YAML

// ordering
virtual int Compare(Content *pContent);
virtual int Compare(Scalar *pScalar) { return 1; }
virtual int Compare(Sequence *pSeq) { return 1; }
virtual int Compare(Scalar *) { return 1; }
virtual int Compare(Sequence *) { return 1; }
virtual int Compare(Map *pMap);

private:
Expand Down
4 changes: 4 additions & 0 deletions src/node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ namespace YAML
{
Clear();

// an empty node *is* a possibility
if(pScanner->empty())
return;

// save location
m_line = pScanner->peek().line;
m_column = pScanner->peek().column;
Expand Down
31 changes: 14 additions & 17 deletions src/regex.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ namespace YAML
return Match(str) >= 0;
}

bool RegEx::Matches(const char *buffer) const
bool RegEx::Matches(const Buffer& buffer) const
{
return Match(buffer) >= 0;
}
Expand All @@ -109,7 +109,7 @@ namespace YAML
int RegEx::Match(const std::string& str) const
{
if(!m_pOp)
return 0;
return str.empty() ? 0 : -1; // the empty regex only is successful on the empty string

return m_pOp->Match(str, *this);
}
Expand All @@ -121,15 +121,12 @@ namespace YAML
}

// Match
// . The stream version does the same thing as the string version;
// REMEMBER that we only match from the start of the stream!
// . Note: the istream is not a const reference, but we guarantee
// that the pointer will be in the same spot, and we'll clear its
// flags before we end.
int RegEx::Match(const char *buffer) const
// . The buffer version does the same thing as the string version;
// REMEMBER that we only match from the start of the buffer!
int RegEx::Match(const Buffer& buffer) const
{
if(!m_pOp)
return -1;
return !buffer ? 0 : -1; // see above

return m_pOp->Match(buffer, *this);
}
Expand Down Expand Up @@ -177,9 +174,9 @@ namespace YAML
}


int RegEx::MatchOperator::Match(const char *buffer, const RegEx& regex) const
int RegEx::MatchOperator::Match(const Buffer& buffer, const RegEx& regex) const
{
if(buffer[0] != regex.m_a)
if(!buffer || buffer[0] != regex.m_a)
return -1;
return 1;
}
Expand All @@ -192,9 +189,9 @@ namespace YAML
return 1;
}

int RegEx::RangeOperator::Match(const char *buffer, const RegEx& regex) const
int RegEx::RangeOperator::Match(const Buffer& buffer, const RegEx& regex) const
{
if(regex.m_a > buffer[0] || regex.m_z < buffer[0])
if(!buffer || regex.m_a > buffer[0] || regex.m_z < buffer[0])
return -1;
return 1;
}
Expand All @@ -210,7 +207,7 @@ namespace YAML
return -1;
}

int RegEx::OrOperator::Match(const char *buffer, const RegEx& regex) const
int RegEx::OrOperator::Match(const Buffer& buffer, const RegEx& regex) const
{
for(unsigned i=0;i<regex.m_params.size();i++) {
int n = regex.m_params[i].Match(buffer);
Expand All @@ -237,7 +234,7 @@ namespace YAML
return first;
}

int RegEx::AndOperator::Match(const char *buffer, const RegEx& regex) const
int RegEx::AndOperator::Match(const Buffer& buffer, const RegEx& regex) const
{
int first = -1;
for(unsigned i=0;i<regex.m_params.size();i++) {
Expand All @@ -260,7 +257,7 @@ namespace YAML
return 1;
}

int RegEx::NotOperator::Match(const char *buffer, const RegEx& regex) const
int RegEx::NotOperator::Match(const Buffer& buffer, const RegEx& regex) const
{
if(regex.m_params.empty())
return -1;
Expand All @@ -282,7 +279,7 @@ namespace YAML
return offset;
}

int RegEx::SeqOperator::Match(const char *buffer, const RegEx& regex) const
int RegEx::SeqOperator::Match(const Buffer& buffer, const RegEx& regex) const
{
int offset = 0;
for(unsigned i=0;i<regex.m_params.size();i++) {
Expand Down
22 changes: 12 additions & 10 deletions src/regex.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@

namespace YAML
{
struct Stream;
class Stream;
struct Buffer;

enum REGEX_OP { REGEX_EMPTY, REGEX_MATCH, REGEX_RANGE, REGEX_OR, REGEX_AND, REGEX_NOT, REGEX_SEQ };

Expand All @@ -15,40 +16,41 @@ namespace YAML
class RegEx
{
private:
// the operators
struct Operator {
virtual ~Operator() {}
virtual int Match(const std::string& str, const RegEx& regex) const = 0;
virtual int Match(const char *buffer, const RegEx& regex) const = 0;
virtual int Match(const Buffer& buffer, const RegEx& regex) const = 0;
};

struct MatchOperator: public Operator {
virtual int Match(const std::string& str, const RegEx& regex) const;
virtual int Match(const char *buffer, const RegEx& regex) const;
virtual int Match(const Buffer& buffer, const RegEx& regex) const;
};

struct RangeOperator: public Operator {
virtual int Match(const std::string& str, const RegEx& regex) const;
virtual int Match(const char *buffer, const RegEx& regex) const;
virtual int Match(const Buffer& buffer, const RegEx& regex) const;
};

struct OrOperator: public Operator {
virtual int Match(const std::string& str, const RegEx& regex) const;
virtual int Match(const char *buffer, const RegEx& regex) const;
virtual int Match(const Buffer& buffer, const RegEx& regex) const;
};

struct AndOperator: public Operator {
virtual int Match(const std::string& str, const RegEx& regex) const;
virtual int Match(const char *buffer, const RegEx& regex) const;
virtual int Match(const Buffer& buffer, const RegEx& regex) const;
};

struct NotOperator: public Operator {
virtual int Match(const std::string& str, const RegEx& regex) const;
virtual int Match(const char *buffer, const RegEx& regex) const;
virtual int Match(const Buffer& buffer, const RegEx& regex) const;
};

struct SeqOperator: public Operator {
virtual int Match(const std::string& str, const RegEx& regex) const;
virtual int Match(const char *buffer, const RegEx& regex) const;
virtual int Match(const Buffer& buffer, const RegEx& regex) const;
};

public:
Expand All @@ -65,10 +67,10 @@ namespace YAML

bool Matches(char ch) const;
bool Matches(const std::string& str) const;
bool Matches(const char *buffer) const;
bool Matches(const Buffer& buffer) const;
bool Matches(const Stream& in) const;
int Match(const std::string& str) const;
int Match(const char *buffer) const;
int Match(const Buffer& buffer) const;
int Match(const Stream& in) const;

friend RegEx operator ! (const RegEx& ex);
Expand Down
4 changes: 2 additions & 2 deletions src/scalar.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ namespace YAML
// ordering
virtual int Compare(Content *pContent);
virtual int Compare(Scalar *pScalar);
virtual int Compare(Sequence *pSeq) { return -1; }
virtual int Compare(Map *pMap) { return -1; }
virtual int Compare(Sequence *) { return -1; }
virtual int Compare(Map *) { return -1; }

protected:
std::string m_data;
Expand Down
4 changes: 2 additions & 2 deletions src/scanscalar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ namespace YAML
// ********************************
// Phase #1: scan until line ending
while(!params.end.Matches(INPUT) && !Exp::Break.Matches(INPUT)) {
if(INPUT.peek() == EOF)
if(!INPUT)
break;

// document indicator?
Expand Down Expand Up @@ -60,7 +60,7 @@ namespace YAML
}

// eof? if we're looking to eat something, then we throw
if(INPUT.peek() == EOF) {
if(!INPUT) {
if(params.eatEnd)
throw ParserException(INPUT.line, INPUT.column, ErrorMsg::EOF_IN_SCALAR);
break;
Expand Down
12 changes: 6 additions & 6 deletions src/scantoken.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ namespace YAML
INPUT.eat(1);

// read name
while(INPUT.peek() != EOF && !Exp::BlankOrBreak.Matches(INPUT))
while(INPUT && !Exp::BlankOrBreak.Matches(INPUT))
name += INPUT.get();

// read parameters
Expand All @@ -39,12 +39,12 @@ namespace YAML
INPUT.eat(1);

// break on newline or comment
if(INPUT.peek() == EOF || Exp::Break.Matches(INPUT) || Exp::Comment.Matches(INPUT))
if(!INPUT || Exp::Break.Matches(INPUT) || Exp::Comment.Matches(INPUT))
break;

// now read parameter
std::string param;
while(INPUT.peek() != EOF && !Exp::BlankOrBreak.Matches(INPUT))
while(INPUT && !Exp::BlankOrBreak.Matches(INPUT))
param += INPUT.get();

params.push_back(param);
Expand Down Expand Up @@ -221,7 +221,7 @@ namespace YAML
throw ParserException(INPUT.line, INPUT.column, alias ? ErrorMsg::ALIAS_NOT_FOUND : ErrorMsg::ANCHOR_NOT_FOUND);

// and needs to end correctly
if(INPUT.peek() != EOF && !Exp::AnchorEnd.Matches(INPUT))
if(INPUT && !Exp::AnchorEnd.Matches(INPUT))
throw ParserException(INPUT.line, INPUT.column, alias ? ErrorMsg::CHAR_IN_ALIAS : ErrorMsg::CHAR_IN_ANCHOR);

// and we're done
Expand All @@ -245,7 +245,7 @@ namespace YAML
handle += INPUT.get();

// read the handle
while(INPUT.peek() != EOF && INPUT.peek() != Keys::Tag && !Exp::BlankOrBreak.Matches(INPUT))
while(INPUT && INPUT.peek() != Keys::Tag && !Exp::BlankOrBreak.Matches(INPUT))
handle += INPUT.get();

// is there a suffix?
Expand All @@ -254,7 +254,7 @@ namespace YAML
handle += INPUT.get();

// then read it
while(INPUT.peek() != EOF && !Exp::BlankOrBreak.Matches(INPUT))
while(INPUT && !Exp::BlankOrBreak.Matches(INPUT))
suffix += INPUT.get();
} else {
// this is a bit weird: we keep just the '!' as the handle and move the rest to the suffix
Expand Down
4 changes: 2 additions & 2 deletions src/sequence.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ namespace YAML

// ordering
virtual int Compare(Content *pContent);
virtual int Compare(Scalar *pScalar) { return 1; }
virtual int Compare(Scalar *) { return 1; }
virtual int Compare(Sequence *pSeq);
virtual int Compare(Map *pMap) { return -1; }
virtual int Compare(Map *) { return -1; }

private:
void ParseBlock(Scanner *pScanner, const ParserState& state);
Expand Down
7 changes: 6 additions & 1 deletion src/stream.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,18 @@ namespace YAML
{
Stream::Stream(std::istream& input): buffer(0), pos(0), line(0), column(0), size(0)
{
if(!input)
return;

std::streambuf *pBuf = input.rdbuf();

// store entire file in buffer
size = pBuf->pubseekoff(0, std::ios::end, std::ios::in);
pBuf->pubseekpos(0, std::ios::in);
buffer = new char[size];
pBuf->sgetn(buffer, size);
size = pBuf->sgetn(buffer, size); // Note: when reading a Windows CR/LF file,
// pubseekoff() counts CR/LF as two characters,
// setgn() reads CR/LF as a single LF character!
}

Stream::~Stream()
Expand Down
15 changes: 14 additions & 1 deletion src/stream.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,19 @@

namespace YAML
{
// a simple buffer wrapper that knows how big it is
struct Buffer {
Buffer(char *b, int s): buffer(b), size(s) {}

operator bool() const { return size > 0; }
bool operator !() const { return !static_cast <bool> (*this); }
char operator [] (int i) const { return buffer[i]; }
const Buffer operator + (int offset) const { return Buffer(buffer + offset, size - offset); }

char *buffer;
int size;
};

class Stream
{
public:
Expand All @@ -14,7 +27,7 @@ namespace YAML
operator bool() const;
bool operator !() const { return !static_cast <bool>(*this); }

const char *current() const { return buffer + pos; }
const Buffer current() const { return Buffer(buffer + pos, size - pos); }
char peek();
char get();
std::string get(int n);
Expand Down
3 changes: 2 additions & 1 deletion yaml-reader/tests/test.yaml
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
- test
---
...
Loading

0 comments on commit 9d0e0c6

Please sign in to comment.