Exception classes to allow hierarchical catching and to work reasonably nicely with the crash log

This was SVN commit r759.
This commit is contained in:
Ykkrosh 2004-07-15 19:10:33 +00:00
parent 3da6540b49
commit f2cc629ca9
7 changed files with 152 additions and 15 deletions

80
source/errorlist.pl Executable file
View File

@ -0,0 +1,80 @@
#!perl -w
use strict;
use warnings;
my (%groups, %types);
my @files = cpp_files('.');
for (@files) {
open my $f, $_ or die "Error opening file '$_' ($!)";
while (<$f>) {
if (/^ERROR_/) {
if (/^ERROR_GROUP\((.+?)\)/) {
$groups{join '~', split /,\s*/, $1} = 1;
} elsif (/^ERROR_TYPE\((.+?)\)/) {
$types{join '~', split /,\s*/, $1} = 1;
}
}
}
}
open my $out, '>', 'ps/Errors.cpp' or die "Error opening ps/Errors.cpp ($!)";
print $out <<'.';
// Auto-generated by errorlist.pl - do not edit
#include "precompiled.h"
#include "Errors.h"
// Slightly hacky section to redeclare things that are declared
// elsewhere - trust the compiler to handle them identically
.
for (sort keys %groups) {
my ($base, $name) = split /~/;
print $out "class ${base}_$name : public $base {};\n";
}
for (sort keys %types) {
my ($base, $name) = split /~/;
print $out "class ${base}_$name : public $base { public: ${base}_$name(); };\n";
}
print $out "\n// The relevant bits of this file:\n";
@types{sort keys %types} = 0 .. keys(%types)-1;
for (sort keys %types) {
my ($base, $name) = split /~/;
print $out "${base}_${name}::${base}_${name}() { magic=0x50534552; code=$types{$_}; }\n";
}
print $out <<".";
const wchar_t* GetErrorString(int code)
{
\tswitch (code)
\t{
.
for (sort keys %types) {
(my $name = $_) =~ s/~/_/;
$name =~ s/.*?_//;
print $out qq{\tcase $types{$_}: return L"$name"; break;\n};
}
print $out <<".";
\t}
\treturn L"Unrecognised error";
}
.
sub cpp_files {
opendir my $d, $_[0] or die "Error opening directory '$_[0]' ($!)";
my @f = readdir $d;
my @files = map "$_[0]/$_", grep /\.(?:cpp|h)$/, @f;
push @files, cpp_files($_) for grep { /^[a-z]+$/ and -d } @f;
return @files;
}

View File

@ -376,12 +376,25 @@ void CGUI::DrawSprite(const CStr& SpriteName,
{
if (cit->m_Texture)
{
// TODO: Handle the GL state in a nicer way
glEnable(GL_TEXTURE_2D);
glDisable(GL_COLOR);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
int fmt;
tex_info(cit->m_Texture, NULL, NULL, &fmt, NULL, NULL);
if (fmt == GL_RGBA || fmt == GL_BGRA)
{
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
}
else
{
glDisable(GL_BLEND);
}
tex_bind(cit->m_Texture);
//glColor3f(1.0f, 1.0f, 1.0f);
CRect real = cit->m_Size.GetClientArea(Rect);
@ -891,8 +904,9 @@ void CGUI::LoadXMLFile(const string &Filename)
{
XeroFile.Load(Filename.c_str());
}
catch (...) {
// Failed
catch (PSERROR_Xeromyces& err) {
UNUSED(err);
// Fail silently
return;
}

View File

@ -53,3 +53,6 @@
#endif // HAVE_DEBUGALLOC
#endif // #ifdef HAVE_PCH
// Macros for declaring new exception groups/types
#include "ps/Errors.h"

24
source/ps/Errors.cpp Executable file
View File

@ -0,0 +1,24 @@
// Auto-generated by errorlist.pl - do not edit
#include "precompiled.h"
#include "Errors.h"
// Slightly hacky section to redeclare things that are declared
// elsewhere - trust the compiler to handle them identically
class PSERROR_Xeromyces : public PSERROR {};
class PSERROR_Xeromyces_XMLOpenFailed : public PSERROR_Xeromyces { public: PSERROR_Xeromyces_XMLOpenFailed(); };
class PSERROR_Xeromyces_XMLParseError : public PSERROR_Xeromyces { public: PSERROR_Xeromyces_XMLParseError(); };
// The relevant bits of this file:
PSERROR_Xeromyces_XMLOpenFailed::PSERROR_Xeromyces_XMLOpenFailed() { magic=0x50534552; code=0; }
PSERROR_Xeromyces_XMLParseError::PSERROR_Xeromyces_XMLParseError() { magic=0x50534552; code=1; }
const wchar_t* GetErrorString(int code)
{
switch (code)
{
case 0: return L"Xeromyces_XMLOpenFailed"; break;
case 1: return L"Xeromyces_XMLParseError"; break;
}
return L"Unrecognised error";
}

18
source/ps/Errors.h Executable file
View File

@ -0,0 +1,18 @@
#ifndef _ERRORS_H_
#define _ERRORS_H_
#include <stdlib.h> // for wchar_t
class PSERROR
{
public:
int magic; // = 0x50534552, so the exception handler can recognise that it's a PSERROR
int code;
};
#define ERROR_GROUP(a,b) class a##_##b : public a {}
#define ERROR_TYPE(a,b) class a##_##b : public a { public: a##_##b(); }
const wchar_t* GetErrorString(int code);
#endif

View File

@ -1,4 +1,4 @@
// $Id: Xeromyces.cpp,v 1.7 2004/07/12 15:49:31 philip Exp $
// $Id: Xeromyces.cpp,v 1.8 2004/07/15 19:08:28 philip Exp $
#include "precompiled.h"
@ -10,7 +10,7 @@
#include "ps/Xeromyces.h"
#include "ps/CLogger.h"
#include "lib/res/file.h"
#include "lib/res/vfs.h"
// Because I (and Xerces) don't like these being redefined by wposix.h:
#ifdef HAVE_PCH
@ -175,8 +175,6 @@ void CXeromyces::Terminate()
}
}
void CXeromyces::Load(const char* filename)
{
// HACK: This is only done so early because CVFSInputSource
@ -193,7 +191,7 @@ void CXeromyces::Load(const char* filename)
if (source.OpenFile(filename))
{
LOG(ERROR, "CXeromyces: Failed to load XML file '%s'", filename);
throw "Failed to load XML file";
throw PSERROR_Xeromyces_XMLOpenFailed();
}
// Start the checksum with a particular seed value, so the XMBs will
@ -250,7 +248,7 @@ void CXeromyces::Load(const char* filename)
if (errorHandler.getSawErrors())
{
LOG(ERROR, "CXeromyces: Errors in XML file '%s'", filename);
throw "Failed";
throw PSERROR_Xeromyces_XMLParseError();
}

View File

@ -1,4 +1,4 @@
/* $Id: Xeromyces.h,v 1.2 2004/07/10 18:57:13 olsner Exp $
/* $Id: Xeromyces.h,v 1.3 2004/07/15 19:08:28 philip Exp $
Xeromyces file-loading interface.
Automatically creates and caches relatively
@ -11,9 +11,12 @@
#ifndef _XEROMYCES_H_
#define _XEROMYCES_H_
#include "ps/XeroXMB.h"
ERROR_GROUP(PSERROR, Xeromyces);
ERROR_TYPE(PSERROR_Xeromyces, XMLOpenFailed);
ERROR_TYPE(PSERROR_Xeromyces, XMLParseError);
#include "lib/res/vfs.h"
#include "ps/XeroXMB.h"
#include "lib/res/h_mgr.h"
class CXeromyces : public XMBFile
{
@ -28,9 +31,6 @@ public:
// Call once when shutting down the program.
static void Terminate();
// Get the XMBFile after having called Load
// XMBFile* GetXMB() { assert(XMB); return XMB; }
private:
bool ReadXMBFile(const char* filename, bool CheckCRC, unsigned long CRC);