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