1 // -*- Mode: C++; tab-width:2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 // vi:tw=80:et:ts=2:sts=2
3 //
4 // -----------------------------------------------------------------------
5 //
6 // This file is part of RLVM, a RealLive virtual machine clone.
7 //
8 // -----------------------------------------------------------------------
9 //
10 // Copyright (C) 2009 Elliot Glaysher
11 //
12 // This program is free software; you can redistribute it and/or modify
13 // it under the terms of the GNU General Public License as published by
14 // the Free Software Foundation; either version 3 of the License, or
15 // (at your option) any later version.
16 //
17 // This program is distributed in the hope that it will be useful,
18 // but WITHOUT ANY WARRANTY; without even the implied warranty of
19 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 // GNU General Public License for more details.
21 //
22 // You should have received a copy of the GNU General Public License
23 // along with this program; if not, write to the Free Software
24 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
25 // -----------------------------------------------------------------------
26
27 #include "utilities/exception.h"
28
29 #include <fstream>
30 #include <sstream>
31 #include <string>
32
33 #include "libreallive/bytecode.h"
34 #include "libreallive/expression.h"
35
36 using std::ostringstream;
37
38 namespace rlvm {
39
40 // -----------------------------------------------------------------------
41 // Exception
42 // -----------------------------------------------------------------------
43
Exception(const std::string & what)44 Exception::Exception(const std::string& what)
45 : description_(what), operation_(NULL) {}
46
~Exception()47 Exception::~Exception() throw() {}
48
what() const49 const char* Exception::what() const throw() { return description_.c_str(); }
50
51 // -----------------------------------------------------------------------
52 // UserPresentableError
53 // -----------------------------------------------------------------------
UserPresentableError(const std::string & message_text,const std::string & informative_text)54 UserPresentableError::UserPresentableError(const std::string& message_text,
55 const std::string& informative_text)
56 : Exception(message_text + ": " + informative_text),
57 message_text_(message_text),
58 informative_text_(informative_text) {}
59
~UserPresentableError()60 UserPresentableError::~UserPresentableError() throw() {}
61
62 // -----------------------------------------------------------------------
63 // UnimplementedOpcode
64 // -----------------------------------------------------------------------
UnimplementedOpcode(const std::string & funName,int modtype,int module,int opcode,int overload)65 UnimplementedOpcode::UnimplementedOpcode(const std::string& funName,
66 int modtype,
67 int module,
68 int opcode,
69 int overload)
70 : Exception(""), has_parameters_(false) {
71 std::ostringstream oss;
72 oss << funName << " (opcode<" << modtype << ":" << module << ":" << opcode
73 << ", " << overload << ">)";
74 name_ = oss.str();
75 SetSimpleDescription();
76 }
77
UnimplementedOpcode(RLMachine & machine,const std::string & funName,const libreallive::CommandElement & command)78 UnimplementedOpcode::UnimplementedOpcode(
79 RLMachine& machine,
80 const std::string& funName,
81 const libreallive::CommandElement& command)
82 : Exception(""),
83 has_parameters_(true),
84 parameters_(command.GetUnparsedParameters()) {
85 std::ostringstream oss;
86 oss << funName << " [opcode<" << command.modtype() << ":" << command.module()
87 << ":" << command.opcode() << ", " << command.overload() << ">]";
88 name_ = oss.str();
89 SetFullDescription(machine);
90 }
91
UnimplementedOpcode(RLMachine & machine,const libreallive::CommandElement & command)92 UnimplementedOpcode::UnimplementedOpcode(
93 RLMachine& machine,
94 const libreallive::CommandElement& command)
95 : Exception(""),
96 has_parameters_(true),
97 parameters_(command.GetUnparsedParameters()) {
98 ostringstream oss;
99 oss << "opcode<" << command.modtype() << ":" << command.module() << ":"
100 << command.opcode() << ", " << command.overload() << ">";
101 name_ = oss.str();
102 SetFullDescription(machine);
103 }
104
~UnimplementedOpcode()105 UnimplementedOpcode::~UnimplementedOpcode() throw() {}
106
SetFullDescription(RLMachine & machine)107 void UnimplementedOpcode::SetFullDescription(RLMachine& machine) {
108 ostringstream oss;
109 oss << "Undefined: " << name_;
110
111 #ifndef NDEBUG
112 if (has_parameters_) {
113 bool first = true;
114 oss << "(";
115 for (std::vector<std::string>::const_iterator it = parameters_.begin();
116 it != parameters_.end();
117 ++it) {
118 if (!first) {
119 oss << ", ";
120 }
121 first = false;
122
123 // Take the binary stuff and try to get usefull, printable values.
124 const char* start = it->c_str();
125 try {
126 libreallive::ExpressionPiece piece(libreallive::GetData(start));
127 oss << piece.GetDebugString();
128 }
129 catch (libreallive::Error& e) {
130 // Any error throw here is a parse error.
131 oss << "{RAW : " << libreallive::ParsableToPrintableString(*it) << "}";
132 }
133 }
134 oss << ")";
135 }
136 #endif
137
138 description_ = oss.str();
139 }
140
SetSimpleDescription()141 void UnimplementedOpcode::SetSimpleDescription() {
142 ostringstream oss;
143 oss << "Undefined: " << name_;
144 description_ = oss.str();
145 }
146
147 } // namespace rlvm
148