/* * Baltisot * Copyright (C) 1999-2003 Nicolas "Pixel" Noble * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* $Id: Exceptions.cc,v 1.41 2006-11-14 10:10:10 pixel Exp $ */ #include #include #include #ifdef HAVE_CONFIG_H #include "config.h" #ifdef HAVE_MALLOC_H #include #endif #else #ifndef __APPLE__ #include #endif #endif #ifdef DEBUG #include #endif #ifdef HAVE_PIPE #include #endif #ifdef HAVE_FORK #include #include #endif #include "BString.h" #include "Exceptions.h" #include "generic.h" #include "gettext.h" char GeneralException::t[BUFSIZ]; std::vector Base::context; GeneralException::GeneralException(String emsg) : msg(emsg.strdup()) { UNLOCK; #ifdef DEBUG printm(M_BARE, String(_("Generating a General Exception error: '")) + msg + "'.\n"); #endif } GeneralException::GeneralException() : msg(0) { UNLOCK; #ifdef DEBUG printm(M_BARE, String(_("Generating a General Exception error: '")) + msg + "'.\n"); #endif } GeneralException::GeneralException(const GeneralException & e) : msg(strdup(e.msg)) { UNLOCK; #ifdef DEBUG printm(M_BARE, String(_("Generating a General Exception error: '")) + msg + "'.\n"); #endif } GeneralException::~GeneralException() { free(msg); } TaskNotFound::TaskNotFound() : GeneralException(_("Task not found")) { } const char * GeneralException::GetMsg() const { return msg; } MemoryException::MemoryException(ssize_t s) { sprintf(t, _("Failed allocating %u bytes."), s); msg = strdup(t); } IOException::IOException(String fn, op_t op, ssize_t s) { sprintf(t, _("An error has occured while %s %u bytes on %s: %s"), op == IO_WRITE ? _("writing") : _("reading"), s, fn.to_charp(), strerror(errno)); msg = strdup(t); } IOGeneral::IOGeneral(String fn) : GeneralException(fn) { } IOGeneral::IOGeneral() { } IOAgain::IOAgain() : IOGeneral(_("No more bytes for reading or writing.")) { #ifdef DEBUG printm(M_BARE, String(_("Generating an IOAgain exception: '")) + GetMsg() + "'.\n"); #endif } TaskSwitch::TaskSwitch() : GeneralException(_("Switching task in a non-tasked environnement")) { #ifdef DEBUG printm(M_BARE, String(_("Generating a TaskSwitch exception: '")) + GetMsg() + "'.\n"); #endif } Exit::Exit(int a_code) : GeneralException(_("Exitting with code " + a_code)), code(a_code) { #ifdef DEBUG printm(M_BARE, String(_("Generating an Exit exception: '")) + GetMsg() + "'.\n"); #endif } int Exit::GetCode() { return code; } char * xstrdup(const char * s) { char * r; if (!s) { return xstrdup(""); } r = (char *) xmalloc(strlen(s) + 1); strcpy(r, s); return r; } void * xmalloc(size_t s) throw (GeneralException) { char * r; if (s == 0) { return 0; } if (!(r = (char *) ::malloc(s))) { throw MemoryException(s); } #ifdef DEBUG // Base::printm(M_BARE, String(_("Allocating %i bytes of memory, got it at %p\n")), s, r); #endif memset(r, 0, s); return (void *)(r); } void * xrealloc(void * ptr, size_t s) { #ifdef DEBUG void * r = realloc(ptr, s); Base::printm(M_BARE, String(_("Reallocating pointer at %p for %i bytes, now at %p\n")), ptr, s, r); return r; #else return realloc(ptr, s); #endif } void xfree(unsigned char *& p) { #ifdef DEBUG // Base::printm(M_BARE, String(_("Freeing pointer at %p\n")), p); #endif if (p) { ::free(p); p = 0; } } #ifdef HAVE_PIPE int xpipe(int * p, int flag) throw (GeneralException) { if (pipe(p)) { throw GeneralException(String(_("Error creating pipe: ")) + strerror(errno)); } return p[flag]; } #else int xpipe(int *, int) throw (GeneralException) { throw GeneralException(_("Function pipe() not supported by this system.\n")); } #endif #ifdef _WIN32 #include #endif int xdup(int h) throw(GeneralException) { #ifdef __MIPSEL__ throw GeneralException(_("Dup isn't supported on PlayStation2 yet")); #else return dup(h); #endif } #ifdef HAVE_FORK pid_t xfork() throw (GeneralException) { pid_t p; p = fork(); if (p == -1) { throw GeneralException(_("Was not able to fork().\n")); } return p; } #else pid_t xfork() throw (GeneralException) { throw GeneralException(_("Function fork() not supported by this system.\n")); } #endif #ifdef HAVE_FORK pid_t xwait(int * s) throw (GeneralException) { return ::wait(s); } #else pid_t xwait(int *) throw (GeneralException) { throw GeneralException(_("Function wait() not supported by this system.\n")); } #endif void xexit(int status) throw (GeneralException) { throw Exit(status); } void xexception(const String & err) throw (GeneralException) { throw GeneralException(err); } char * Base::strdup(const char * s) { return xstrdup(s); } void * Base::malloc(ssize_t s) { return xmalloc(s); } void * Base::realloc(void * p, size_t s) { return xrealloc(p, s); } void * Base::calloc(size_t n, size_t s) { return xmalloc(n * s); } int Base::dup(int h) { return xdup(h); } void * Base::operator new(size_t s) { #ifdef DEBUG printm(M_BARE, _("Operator new(s) called. Allocating memory.\n")); #endif return xmalloc(s); } void * Base::operator new(size_t s, void * p) { #ifdef DEBUG printm(M_BARE, String(_("Operator new(s, p) called with p = %p and s = %i. Erasing memory.\n")), p, s); #endif return memset(p, 0, s); } void Base::operator delete(void * p) { #ifdef DEBUG printm(M_BARE, _("Operator delete(p) called. Freeing memory.\n")); #endif free(p); } int Base::pipe(int * p, int flag) { return xpipe(p, flag); } pid_t Base::fork() { return xfork(); } pid_t Base::wait(int * s) { return xwait(s); } void Base::exit(int status) { xexit(status); } void Base::flushcontext() { context.clear(); } void Base::pushcontext(const String & c) { context.push_back(c); } void Base::popcontext() { context.pop_back(); } void Base::exception(const String & err) { int c; std::vector::iterator i; printm(M_ERROR, "Error detected, showing context.\n"); for (i = context.begin(), c = 0; i != context.end(); i++, c++) { printm(M_ERROR, " (%i) - " + *i + "\n", c); } printm(M_ERROR, " Error description: " + err); xexception(err); }