/* $Id$
This file is part of libmspdatafile
-Copyright © 2007 Mikko Rasa, Mikkosoft Productions
+Copyright © 2007-2008 Mikko Rasa, Mikkosoft Productions
Distributed under the LGPL
*/
if(st.keyword=="__kwd")
{
if(st.args.size()!=3)
- throw TypeError(src+": Keyword definition must have three arguments");
+ throw_at(TypeError("Keyword definition must have three arguments"), src);
const unsigned id=st.args[0].get<unsigned>();
const string &kw=st.args[1].get<const string &>();
else if(st.keyword=="__str")
{
if(st.args.size()!=2)
- throw TypeError(src+": String definition must have two arguments");
+ throw_at(TypeError("String definition must have two arguments"), src);
const unsigned id=st.args[0].get<unsigned>();
strings[id]=st.args[1].get<const string &>();
Dictionary::const_iterator i=dict.find(id);
if(i==dict.end())
- throw ParseError(format("%s: Unknown statement ID %d", src, id), src, 0);
+ throw_at(KeyError("Unknown statement ID", lexical_cast(id)), src);
const DictEntry &de=i->second;
Statement result;
{
StringMap::const_iterator i=strings.find(id);
if(i==strings.end())
- throw KeyError("Unknown string", lexical_cast(id));
+ throw_at(KeyError("Unknown string", lexical_cast(id)), src);
return i->second;
}
/* $Id$
This file is part of libmspdatafile
-Copyright © 2006 Mikko Rasa, Mikkosoft Productions
+Copyright © 2006-2008 Mikko Rasa, Mikkosoft Productions
Distributed under the LGPL
*/
#ifndef MSP_DATAFILE_COLLECTION_H_
#define MSP_DATAFILE_COLLECTION_H_
+#include <msp/core/meta.h>
#include <msp/core/refptr.h>
#include "loader.h"
enum { result=(sizeof(f<T>(0))==sizeof(Yes)) };
};
-template<typename T>
-struct RemoveConst
-{ typedef T Type; };
-
-template<typename T>
-struct RemoveConst<const T>
-{ typedef T Type; };
-
/**
A collection of objects that can be loaded from a datafile. Each object is
identified by a name, which must be unique across the entire collection.
/* $Id$
This file is part of libmspdatafile
-Copyright © 2006 Mikko Rasa, Mikkosoft Productions
+Copyright © 2008 Mikko Rasa, Mikkosoft Productions
Distributed under the LGPL
*/
-#ifndef MSP_DATAFILE_ERROR_H_
-#define MSP_DATAFILE_ERROR_H_
+
+#ifndef MSP_DATAFILE_EXCEPT_H_
+#define MSP_DATAFILE_EXCEPT_H_
#include <msp/core/except.h>
class TypeError: public Exception
{
public:
- TypeError(const std::string &w_): Exception(w_) { }
+ TypeError(const std::string &w): Exception(w) { }
};
class ParseError: public Exception
{
public:
- ParseError(const std::string &w_, const std::string &s, unsigned l): Exception(w_), source(s), line(l) { }
- const std::string &get_source() const { return source; }
- unsigned get_line() const { return line; }
- ~ParseError() throw() { }
-private:
- std::string source;
- unsigned line;
+ ParseError(const std::string &w): Exception(w) { }
};
} // namespace DataFile
/* $Id$
This file is part of libmspdatafile
-Copyright © 2006 Mikko Rasa, Mikkosoft Productions
+Copyright © 2006-2008 Mikko Rasa, Mikkosoft Productions
Distributed under the LGPL
*/
cur_st=&st;
ActionMap::iterator j=actions.find(st.keyword);
if(j==actions.end())
- throw KeyError(st.get_location()+": Unknown keyword", st.keyword);
+ throw_at(KeyError("Unknown keyword", st.keyword), st.get_location());
if(j->second)
- j->second->execute(*this, st);
+ {
+ try
+ {
+ j->second->execute(*this, st);
+ }
+ catch(Exception &e)
+ {
+ if(!e.where()[0])
+ e.at(st.get_location());
+ throw;
+ }
+ }
cur_st=0;
}
/* $Id$
This file is part of libmspdatafile
-Copyright © 2006 Mikko Rasa, Mikkosoft Productions
+Copyright © 2006-2008 Mikko Rasa, Mikkosoft Productions
Distributed under the LGPL
*/
LoaderFunc0(FuncType f): func(f) { }
void execute(Loader &l, const Statement &st) const
{
- if(st.args.size()!=0) throw TypeError(st.get_location()+": Wrong number of arguments");
+ if(st.args.size()!=0) throw TypeError("Wrong number of arguments");
(dynamic_cast<L &>(l).*func)();
};
private:
LoaderFunc1(FuncType f): func(f) { }
void execute(Loader &l, const Statement &st) const
{
- if(st.args.size()!=1) throw TypeError(st.get_location()+": Wrong number of arguments");
+ if(st.args.size()!=1) throw TypeError("Wrong number of arguments");
(dynamic_cast<L &>(l).*func)(st.args[0].get<A0>());
}
private:
LoaderFunc2(FuncType f): func(f) { }
void execute(Loader &l, const Statement &st) const
{
- if(st.args.size()!=2) throw TypeError(st.get_location()+": Wrong number of arguments");
+ if(st.args.size()!=2) throw TypeError("Wrong number of arguments");
(dynamic_cast<L &>(l).*func)(st.args[0].get<A0>(), st.args[1].get<A1>());
}
private:
LoaderFunc3(FuncType f): func(f) { }
void execute(Loader &l, const Statement &st) const
{
- if(st.args.size()!=3) throw TypeError(st.get_location()+": Wrong number of arguments");
+ if(st.args.size()!=3) throw TypeError("Wrong number of arguments");
(dynamic_cast<L &>(l).*func)(st.args[0].get<A0>(), st.args[1].get<A1>(), st.args[2].get<A2>());
}
private:
LoaderFunc4(FuncType f): func(f) { }
void execute(Loader &l, const Statement &st) const
{
- if(st.args.size()!=4) throw TypeError(st.get_location()+": Wrong number of arguments");
+ if(st.args.size()!=4) throw TypeError("Wrong number of arguments");
(dynamic_cast<L &>(l).*func)(st.args[0].get<A0>(), st.args[1].get<A1>(), st.args[2].get<A2>(), st.args[3].get<A3>());
}
private:
LoaderFunc5(FuncType f): func(f) { }
void execute(Loader &l, const Statement &st) const
{
- if(st.args.size()!=5) throw TypeError(st.get_location()+": Wrong number of arguments");
+ if(st.args.size()!=5) throw TypeError("Wrong number of arguments");
(dynamic_cast<L &>(l).*func)(st.args[0].get<A0>(), st.args[1].get<A1>(), st.args[2].get<A2>(), st.args[3].get<A3>(), st.args[4].get<A4>());
}
private:
LoadValue1(Pointer0Type p0): ptr0(p0) { }
void execute(Loader &l, const Statement &st) const
{
- if(st.args.size()!=1) throw TypeError(st.get_location()+": Wrong number of arguments");
+ if(st.args.size()!=1) throw TypeError("Wrong number of arguments");
dynamic_cast<typename L::Loader &>(l).get_object().*ptr0=st.args[0].get<T0>();
}
private:
LoadValue1(Pointer0Type p0): ptr0(p0) { }
void execute(Loader &l, const Statement &st) const
{
- if(st.args.size()!=1) throw TypeError(st.get_location()+": Wrong number of arguments");
+ if(st.args.size()!=1) throw TypeError("Wrong number of arguments");
typename L::Loader &ldr=dynamic_cast<typename L::Loader &>(l);
ldr.get_object().*ptr0=ldr.get_collection().template get<T0>(st.args[0].get<std::string>());
}
LoadValue2(Pointer0Type p0, Pointer1Type p1): ptr0(p0), ptr1(p1) { }
void execute(Loader &l, const Statement &st) const
{
- if(st.args.size()!=2) throw TypeError(st.get_location()+": Wrong number of arguments");
+ if(st.args.size()!=2) throw TypeError("Wrong number of arguments");
dynamic_cast<typename L::Loader &>(l).get_object().*ptr0=st.args[0].get<T0>();
dynamic_cast<typename L::Loader &>(l).get_object().*ptr1=st.args[1].get<T1>();
}
/* $Id$
This file is part of libmspdatafile
-Copyright © 2007 Mikko Rasa, Mikkosoft Productions
+Copyright © 2007-2008 Mikko Rasa, Mikkosoft Productions
Distributed under the LGPL
*/
if(token.str.empty())
break;
else if(token.type!=Token::IDENTIFIER)
- throw ParseError(format("%s: Syntax error at token '%s' (expected an identifier)", get_location(), token.str), src, in.get_line_number());
+ throw_at(ParseError(format("Syntax error at token '%s' (expected an identifier)", token.str)), get_location());
result.keyword=token.str;
result.valid=true;
result.source=src;
else if(finish)
{
if(token.str!=";")
- throw ParseError(format("%s: Syntax error at token '%s' (Expected a ';')", get_location(), token.str), src, in.get_line_number());
+ throw_at(ParseError(format("Syntax error at token '%s' (Expected a ';')", token.str)), get_location());
break;
}
else if(token.str=="{")
//result.args.push_back(resolve_identifiertoken.str);
}
else if(token.str=="")
- throw ParseError(src+": Unexcepted end of input", src, in.get_line_number());
+ throw_at(ParseError("Unexcepted end of input"), get_location());
else
- throw ParseError(get_location()+": Syntax error", src, in.get_line_number());
+ throw_at(ParseError("Syntax error"), get_location());
}
return result;
}
if(comment>0) // EOF while in comment
- throw ParseError(src+": Unfinished comment at end of input", src, in.get_line_number());
+ throw_at(ParseError("Unfinished comment at end of input"), get_location());
else if(comment==0) // Didn't hit any non-whitespace
return Token(Token::SPECIAL, "");
else if(isalpha(c) || c=='_')
state=IDENTIFIER;
else
- parse_error(c, state);
+ parse_error(c, "0-9A-Za-z_.\"{};+-");
break;
case SIGN:
else if(c=='.')
state=FLOAT;
else
- parse_error(c, state);
+ parse_error(c, "0-9.");
break;
case ZERO:
else if(c=='.')
state=FLOAT;
else
- parse_error(c, state);
+ parse_error(c, "0-9A-Fa-f.");
break;
case DECIMAL:
if(c=='.')
state=FLOAT;
else if(!isdigit(c))
- parse_error(c, state);
+ parse_error(c, "0-9.");
break;
case HEXADECIMAL:
if(!isxdigit(c))
- parse_error(c, state);
+ parse_error(c, "0-9A-Fa-f");
break;
case OCTAL:
if(!isodigit(c))
- parse_error(c, state);
+ parse_error(c, "0-7");
break;
case FLOAT:
if(c=='e' || c=='E')
state=FLOATEXPINIT;
else if(!isdigit(c))
- parse_error(c, state);
+ parse_error(c, "0-9Ee");
break;
case FLOATEXPINIT:
else if(isdigit(c))
state=FLOATEXP;
else
- parse_error(c, state);
+ parse_error(c, "0-9+-");
break;
case FLOATEXPSIGN:
if(isdigit(c))
state=FLOATEXP;
else
- parse_error(c, state);
+ parse_error(c, "0-9");
break;
case FLOATEXP:
if(!isdigit(c))
- parse_error(c, state);
+ parse_error(c, "0-9");
break;
case STRING:
{
return Token(Token::STRING, c_unescape(buf.substr(1, buf.size()-2)));
}
- catch(const Exception &e)
+ catch(Exception &e)
{
- throw ParseError(format("%s: %s", get_location(), e.what()), src, in.get_line_number());
+ e.at(get_location());
+ throw;
}
}
else
case IDENTIFIER:
if(!isalpha(c) && !isdigit(c) && c!='_')
- parse_error(c, state);
+ parse_error(c, "0-9A-Za-z_");
break;
default:
- throw Exception(get_location()+": Internal error (bad state)");
+ throw_at(InvalidState("Internal error (bad state)"), get_location());
}
if(is_delimiter(next) && state>=ACCEPT)
return ss.str();
}
-void TextParser::parse_error(int c, int state)
+void TextParser::parse_error(int c, const char *e)
{
- throw ParseError(format("%s: Parse error at '%c' (state %d)", get_location(), static_cast<char>(c), state), src, in.get_line_number());
+ throw_at(ParseError(format("Parse error at '%c', expected one of \"%s\"", static_cast<char>(c), e)), get_location());
}
} // namespace DataFile
/* $Id$
This file is part of libmspdatafile
-Copyright © 2007 Mikko Rasa, Mikkosoft Productions
+Copyright © 2007-2008 Mikko Rasa, Mikkosoft Productions
Distributed under the LGPL
*/
bool is_delimiter(int);
bool isodigit(int);
std::string get_location();
- void parse_error(int, int);
+ void parse_error(int, const char *);
};
} // namespace DataFile