forked from mia/Aegisub
Silence a pile of prefast warnings in cajun
Originally committed to SVN as r6003.
This commit is contained in:
parent
2439381c33
commit
c601351a50
3 changed files with 49 additions and 96 deletions
|
@ -116,14 +116,10 @@ private:
|
||||||
class Imp_T;
|
class Imp_T;
|
||||||
|
|
||||||
class CastVisitor;
|
class CastVisitor;
|
||||||
class ConstCastVisitor;
|
|
||||||
|
|
||||||
template <typename ElementTypeT>
|
template <typename ElementTypeT>
|
||||||
class CastVisitor_T;
|
class CastVisitor_T;
|
||||||
|
|
||||||
template <typename ElementTypeT>
|
|
||||||
class ConstCastVisitor_T;
|
|
||||||
|
|
||||||
template <typename ElementTypeT>
|
template <typename ElementTypeT>
|
||||||
const ElementTypeT& CastTo() const;
|
const ElementTypeT& CastTo() const;
|
||||||
|
|
||||||
|
|
|
@ -42,18 +42,16 @@ public:
|
||||||
|
|
||||||
virtual bool Compare(const Imp& imp) const
|
virtual bool Compare(const Imp& imp) const
|
||||||
{
|
{
|
||||||
ConstCastVisitor_T<ElementTypeT> castVisitor;
|
CastVisitor_T<ElementTypeT> castVisitor;
|
||||||
imp.Accept(castVisitor);
|
imp.Accept(castVisitor);
|
||||||
return castVisitor.m_pElement &&
|
return castVisitor.element && m_Element == *castVisitor.element;
|
||||||
m_Element == *castVisitor.m_pElement;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ElementTypeT m_Element;
|
ElementTypeT m_Element;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class UnknownElement::CastVisitor : public ConstVisitor
|
||||||
class UnknownElement::ConstCastVisitor : public ConstVisitor
|
|
||||||
{
|
{
|
||||||
virtual void Visit(const Array&) {}
|
virtual void Visit(const Array&) {}
|
||||||
virtual void Visit(const Object&) {}
|
virtual void Visit(const Object&) {}
|
||||||
|
@ -63,38 +61,17 @@ class UnknownElement::ConstCastVisitor : public ConstVisitor
|
||||||
virtual void Visit(const Null&) {}
|
virtual void Visit(const Null&) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename ElementTypeT>
|
|
||||||
class UnknownElement::ConstCastVisitor_T : public ConstCastVisitor
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
ConstCastVisitor_T() : m_pElement(0) {}
|
|
||||||
virtual void Visit(const ElementTypeT& element) { m_pElement = &element; } // we don't know what this is, but it overrides one of the base's no-op functions
|
|
||||||
const ElementTypeT* m_pElement;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class UnknownElement::CastVisitor : public Visitor
|
|
||||||
{
|
|
||||||
virtual void Visit(Array&) {}
|
|
||||||
virtual void Visit(Object&) {}
|
|
||||||
virtual void Visit(Number&) {}
|
|
||||||
virtual void Visit(String&) {}
|
|
||||||
virtual void Visit(Boolean&) {}
|
|
||||||
virtual void Visit(Null&) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename ElementTypeT>
|
template <typename ElementTypeT>
|
||||||
class UnknownElement::CastVisitor_T : public CastVisitor
|
class UnknownElement::CastVisitor_T : public CastVisitor
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CastVisitor_T() : m_pElement(0) {}
|
const ElementTypeT *element;
|
||||||
virtual void Visit(ElementTypeT& element) { m_pElement = &element; } // we don't know what this is, but it overrides one of the base's no-op functions
|
CastVisitor_T() : element(0) { }
|
||||||
ElementTypeT* m_pElement;
|
|
||||||
|
// we don't know what this is, but it overrides one of the base's no-op functions
|
||||||
|
void Visit(const ElementTypeT& element) { this->element = &element; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
inline UnknownElement::UnknownElement() : m_pImp( new Imp_T<Null>( Null() ) ) {}
|
inline UnknownElement::UnknownElement() : m_pImp( new Imp_T<Null>( Null() ) ) {}
|
||||||
inline UnknownElement::UnknownElement(const UnknownElement& unknown) : m_pImp( unknown.m_pImp->Clone()) {}
|
inline UnknownElement::UnknownElement(const UnknownElement& unknown) : m_pImp( unknown.m_pImp->Clone()) {}
|
||||||
inline UnknownElement::UnknownElement(const Object& object) : m_pImp( new Imp_T<Object>(object) ) {}
|
inline UnknownElement::UnknownElement(const Object& object) : m_pImp( new Imp_T<Object>(object) ) {}
|
||||||
|
@ -162,31 +139,27 @@ inline const UnknownElement& UnknownElement::operator[] (size_t index) const
|
||||||
template <typename ElementTypeT>
|
template <typename ElementTypeT>
|
||||||
const ElementTypeT& UnknownElement::CastTo() const
|
const ElementTypeT& UnknownElement::CastTo() const
|
||||||
{
|
{
|
||||||
ConstCastVisitor_T<ElementTypeT> castVisitor;
|
CastVisitor_T<ElementTypeT> castVisitor;
|
||||||
m_pImp->Accept(castVisitor);
|
m_pImp->Accept(castVisitor);
|
||||||
if (castVisitor.m_pElement == 0)
|
if (!castVisitor.element)
|
||||||
throw Exception("Bad cast");
|
throw Exception("Bad cast");
|
||||||
return *castVisitor.m_pElement;
|
return *castVisitor.element;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
template <typename ElementTypeT>
|
template <typename ElementTypeT>
|
||||||
ElementTypeT& UnknownElement::ConvertTo()
|
ElementTypeT& UnknownElement::ConvertTo()
|
||||||
{
|
{
|
||||||
CastVisitor_T<ElementTypeT> castVisitor;
|
CastVisitor_T<ElementTypeT> castVisitor;
|
||||||
m_pImp->Accept(castVisitor);
|
Accept(castVisitor);
|
||||||
if (castVisitor.m_pElement == 0)
|
if (!castVisitor.element)
|
||||||
{
|
{
|
||||||
// we're not the right type. fix it & try again
|
// we're not the right type. fix it & try again
|
||||||
*this = ElementTypeT();
|
*this = ElementTypeT();
|
||||||
m_pImp->Accept(castVisitor);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return *castVisitor.m_pElement;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline void UnknownElement::Accept(ConstVisitor& visitor) const { m_pImp->Accept(visitor); }
|
inline void UnknownElement::Accept(ConstVisitor& visitor) const { m_pImp->Accept(visitor); }
|
||||||
inline void UnknownElement::Accept(Visitor& visitor) { m_pImp->Accept(visitor); }
|
inline void UnknownElement::Accept(Visitor& visitor) { m_pImp->Accept(visitor); }
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ Author: Terry Caton
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
TODO:
|
TODO:
|
||||||
* better documentation
|
* better documentation
|
||||||
|
@ -37,16 +37,31 @@ inline Reader::Location::Location() :
|
||||||
//////////////////////
|
//////////////////////
|
||||||
// Reader::InputStream
|
// Reader::InputStream
|
||||||
|
|
||||||
class Reader::InputStream // would be cool if we could inherit from std::istream & override "get"
|
// wrapper around istream to keep track of document/line offsets
|
||||||
|
class Reader::InputStream
|
||||||
{
|
{
|
||||||
|
std::istream& m_iStr;
|
||||||
|
Location m_Location;
|
||||||
public:
|
public:
|
||||||
InputStream(std::istream& iStr) :
|
InputStream(std::istream& iStr) : m_iStr(iStr) { }
|
||||||
m_iStr(iStr) {}
|
|
||||||
|
|
||||||
// protect access to the input stream, so we can keeep track of document/line offsets
|
int Get() {
|
||||||
char Get(); // big, define outside
|
assert(!m_iStr.eof());
|
||||||
char Peek() {
|
int c = m_iStr.get();
|
||||||
assert(m_iStr.eof() == false); // enforce reading of only valid stream data
|
|
||||||
|
++m_Location.m_nDocOffset;
|
||||||
|
if (c == '\n') {
|
||||||
|
++m_Location.m_nLine;
|
||||||
|
m_Location.m_nLineOffset = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
++m_Location.m_nLineOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
int Peek() {
|
||||||
|
assert(!m_iStr.eof());
|
||||||
return m_iStr.peek();
|
return m_iStr.peek();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,32 +71,8 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
const Location& GetLocation() const { return m_Location; }
|
const Location& GetLocation() const { return m_Location; }
|
||||||
|
|
||||||
private:
|
|
||||||
std::istream& m_iStr;
|
|
||||||
Location m_Location;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
inline char Reader::InputStream::Get()
|
|
||||||
{
|
|
||||||
assert(m_iStr.eof() == false); // enforce reading of only valid stream data
|
|
||||||
char c = m_iStr.get();
|
|
||||||
|
|
||||||
++m_Location.m_nDocOffset;
|
|
||||||
if (c == '\n') {
|
|
||||||
++m_Location.m_nLine;
|
|
||||||
m_Location.m_nLineOffset = 0;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
++m_Location.m_nLineOffset;
|
|
||||||
}
|
|
||||||
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//////////////////////
|
//////////////////////
|
||||||
// Reader::TokenStream
|
// Reader::TokenStream
|
||||||
|
|
||||||
|
@ -96,23 +87,21 @@ public:
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
const Token& Peek() {
|
const Token& Peek() {
|
||||||
assert(m_itCurrent != m_Tokens.end());
|
assert(!EOS());
|
||||||
return *(m_itCurrent);
|
return *m_itCurrent;
|
||||||
}
|
}
|
||||||
const Token& Get() {
|
const Token& Get() {
|
||||||
assert(m_itCurrent != m_Tokens.end());
|
assert(!EOS());
|
||||||
return *(m_itCurrent++);
|
return *m_itCurrent++;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EOS() const {
|
bool EOS() const {
|
||||||
return m_itCurrent == m_Tokens.end();
|
return m_itCurrent == m_Tokens.end();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
///////////////////
|
///////////////////
|
||||||
// Reader (finally)
|
// Reader (finally)
|
||||||
|
|
||||||
|
|
||||||
inline void Reader::Read(Object& object, std::istream& istr) { Read_i(object, istr); }
|
inline void Reader::Read(Object& object, std::istream& istr) { Read_i(object, istr); }
|
||||||
inline void Reader::Read(Array& array, std::istream& istr) { Read_i(array, istr); }
|
inline void Reader::Read(Array& array, std::istream& istr) { Read_i(array, istr); }
|
||||||
inline void Reader::Read(String& string, std::istream& istr) { Read_i(string, istr); }
|
inline void Reader::Read(String& string, std::istream& istr) { Read_i(string, istr); }
|
||||||
|
@ -121,8 +110,7 @@ inline void Reader::Read(Boolean& boolean, std::istream& istr) { Re
|
||||||
inline void Reader::Read(Null& null, std::istream& istr) { Read_i(null, istr); }
|
inline void Reader::Read(Null& null, std::istream& istr) { Read_i(null, istr); }
|
||||||
inline void Reader::Read(UnknownElement& unknown, std::istream& istr) { Read_i(unknown, istr); }
|
inline void Reader::Read(UnknownElement& unknown, std::istream& istr) { Read_i(unknown, istr); }
|
||||||
|
|
||||||
|
template <typename ElementTypeT>
|
||||||
template <typename ElementTypeT>
|
|
||||||
void Reader::Read_i(ElementTypeT& element, std::istream& istr)
|
void Reader::Read_i(ElementTypeT& element, std::istream& istr)
|
||||||
{
|
{
|
||||||
Reader reader;
|
Reader reader;
|
||||||
|
@ -134,18 +122,16 @@ void Reader::Read_i(ElementTypeT& element, std::istream& istr)
|
||||||
TokenStream tokenStream(tokens);
|
TokenStream tokenStream(tokens);
|
||||||
reader.Parse(element, tokenStream);
|
reader.Parse(element, tokenStream);
|
||||||
|
|
||||||
if (tokenStream.EOS() == false)
|
if (!tokenStream.EOS())
|
||||||
{
|
{
|
||||||
const Token& token = tokenStream.Peek();
|
const Token& token = tokenStream.Peek();
|
||||||
throw ParseException("Expected End of token stream; found " + token.sValue, token.locBegin, token.locEnd);
|
throw ParseException("Expected End of token stream; found " + token.sValue, token.locBegin, token.locEnd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline void Reader::Scan(Tokens& tokens, InputStream& inputStream)
|
inline void Reader::Scan(Tokens& tokens, InputStream& inputStream)
|
||||||
{
|
{
|
||||||
while (EatWhiteSpace(inputStream), // ignore any leading white space...
|
while (EatWhiteSpace(inputStream), !inputStream.EOS())
|
||||||
inputStream.EOS() == false) // ...before checking for EOS
|
|
||||||
{
|
{
|
||||||
// if all goes well, we'll create a token each pass
|
// if all goes well, we'll create a token each pass
|
||||||
Token token;
|
Token token;
|
||||||
|
@ -231,9 +217,8 @@ inline void Reader::Scan(Tokens& tokens, InputStream& inputStream)
|
||||||
token.nType = Token::TOKEN_NULL;
|
token.nType = Token::TOKEN_NULL;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default: {
|
default:
|
||||||
throw ScanException("Unexpected character in stream: " + sChar, inputStream.GetLocation());
|
throw ScanException("Unexpected character in stream: " + sChar, inputStream.GetLocation());
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
token.locEnd = inputStream.GetLocation();
|
token.locEnd = inputStream.GetLocation();
|
||||||
|
@ -244,8 +229,7 @@ inline void Reader::Scan(Tokens& tokens, InputStream& inputStream)
|
||||||
|
|
||||||
inline void Reader::EatWhiteSpace(InputStream& inputStream)
|
inline void Reader::EatWhiteSpace(InputStream& inputStream)
|
||||||
{
|
{
|
||||||
while (inputStream.EOS() == false &&
|
while (!inputStream.EOS() && ::isspace(inputStream.Peek()))
|
||||||
::isspace(inputStream.Peek()))
|
|
||||||
inputStream.Get();
|
inputStream.Get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -268,7 +252,7 @@ inline void Reader::MatchExpectedString(const std::string& sExpected, InputStrea
|
||||||
inline void Reader::MatchString(std::string& string, InputStream& inputStream)
|
inline void Reader::MatchString(std::string& string, InputStream& inputStream)
|
||||||
{
|
{
|
||||||
MatchExpectedString("\"", inputStream);
|
MatchExpectedString("\"", inputStream);
|
||||||
|
|
||||||
while (inputStream.EOS() == false &&
|
while (inputStream.EOS() == false &&
|
||||||
inputStream.Peek() != '"')
|
inputStream.Peek() != '"')
|
||||||
{
|
{
|
||||||
|
@ -317,7 +301,7 @@ inline void Reader::MatchNumber(std::string& sNumber, InputStream& inputStream)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline void Reader::Parse(UnknownElement& element, Reader::TokenStream& tokenStream)
|
inline void Reader::Parse(UnknownElement& element, Reader::TokenStream& tokenStream)
|
||||||
{
|
{
|
||||||
if (tokenStream.EOS()) {
|
if (tokenStream.EOS()) {
|
||||||
throw ParseException("Unexpected end of token stream", Location(), Location()); // nowhere to point to
|
throw ParseException("Unexpected end of token stream", Location(), Location()); // nowhere to point to
|
||||||
|
|
Loading…
Reference in a new issue