Make love::Exception safe(r).

Now allows exceptions of arbitrary length.
Now allows catching a non-reference, i.e. catch(love::Exception e).
This commit is contained in:
vrld
2011-11-12 21:11:41 +01:00
parent 03927f5207
commit 7a513e1434
4 changed files with 37 additions and 26 deletions
+27 -10
View File
@@ -20,26 +20,43 @@
#include "Exception.h"
#include <common/config.h>
#include <iostream>
using namespace std;
namespace love
{
Exception::Exception(const char * fmt, ...)
{
va_list args;
int size_buffer = 256, size_out;
char * buffer;
while (true) {
buffer = new char[size_buffer];
memset(buffer, 0, size_buffer);
va_start(args, fmt);
vsnprintf(buffer, BUFFER_SIZE, fmt, args);
size_out = vsnprintf(buffer, size_buffer, fmt, args);
va_end(args);
}
Exception::Exception(int unparsed, const char * str)
{
LOVE_UNUSED(unparsed);
strncpy(buffer, str, BUFFER_SIZE);
}
// see http://perfec.to/vsnprintf/pasprintf.c
// if size_out ...
// == -1 --> output was truncated
// == size_buffer --> output was truncated
// == size_buffer-1 --> ambiguous, /may/ have been truncated
// > size_buffer --> output was truncated, and size_out
// bytes would have been written
if (size_out == size_buffer || size_out == -1 || size_out == size_buffer-1)
size_buffer *= 2;
else if (size_out > size_buffer)
size_buffer = size_out + 2; // to avoid the ambiguous case
else
break;
const char * Exception::what() const throw()
{
return (const char *)buffer;
delete[] buffer;
}
message = std::string(buffer);
cerr << message << endl;
delete[] buffer;
}
}
+5 -11
View File
@@ -25,6 +25,7 @@
#include <cstdarg> // vararg
#include <cstdio> // vsnprintf
#include <cstring> // strncpy
#include <string>
namespace love
{
@@ -35,15 +36,7 @@ namespace love
{
private:
/**
* The vsnprintf operates on a buffer this large.
**/
static const int BUFFER_SIZE = 256;
/**
* The buffer for vsnprintf.
**/
char buffer[BUFFER_SIZE];
std::string message;
public:
@@ -55,13 +48,14 @@ namespace love
* @param fmt The format string (see printf).
**/
Exception(const char * fmt, ...);
Exception(int unparsed, const char * str);
virtual ~Exception() throw() {}
/**
* Returns a string containing reason for the exception.
* @return A description of the exception.
**/
virtual const char * what() const throw();
inline virtual const char * what() const throw()
{ return message.c_str(); }
}; // class
+2 -2
View File
@@ -177,7 +177,7 @@ namespace opengl
catch (utf8::exception & e)
{
glPopMatrix();
throw love::Exception(1, e.what());
throw love::Exception("%s", e.what());
}
glPopMatrix();
}
@@ -212,7 +212,7 @@ namespace opengl
}
catch (utf8::exception & e)
{
throw love::Exception(1, e.what());
throw love::Exception("%s", e.what());
}
return temp;
@@ -388,7 +388,7 @@ namespace opengl
const char* code = lua_tostring(L, -1);
PixelEffect * effect = instance->newPixelEffect(code);
luax_newtype(L, "PixelEffect", GRAPHICS_PIXELEFFECT_T, (void*)effect);
} catch (love::Exception& e) {
} catch (const love::Exception& e) {
// memory is freed in Graphics::newPixelEffect
luax_getfunction(L, "graphics", "_transformGLSLErrorMessages");
lua_pushstring(L, e.what());