/* * 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.h,v 1.40 2004-11-28 12:20:10 pixel Exp $ */ #ifndef __EXCEPTIONS_H__ #define __EXCEPTIONS_H__ #include #include #include #include #include #include #include #if !defined pid_t && !defined _SYS_TYPES_H typedef int pid_t; #endif #ifdef _MSC_VER #pragma warning (disable:4290) #endif class String; struct ugly_string; void xfree(unsigned char *&); //! The Base class, that everybody should use. /*! This base class should be derivated for every single class you create. That way, common functions will be overloaded and safe to use (like malloc)12~ */ class Base { public: virtual ~Base() {}; static char * strdup(const char * s); static void * malloc(ssize_t s); static void * realloc(void * p, size_t s); static void * calloc(size_t n, size_t s); void * operator new(size_t s); void * operator new(size_t s, void * p); void operator delete(void * p); template static void free(T *& p) { unsigned char * t = (unsigned char *) p; xfree(t); p = 0; } static int pipe(int * p, int flag = 0); static pid_t fork(); //! This wrapper will call the xexit function. static void exit(int); static void printm(int level, const ugly_string &, ...); static void printm(int level, const char *, ...); static void exception(const String &); static void pushcontext(const String &); static void popcontext(void); static void flushcontext(void); private: static std::vector context; }; //! Every exception class should inherit from this one. /*! This generic class should be handled from the main, so that the software can exit nicely if an exception is thrown, with a built-in message. */ class GeneralException : public Base { public: //! The constructor has to provide a string describing the exception. GeneralException(String); GeneralException(const GeneralException &); ~GeneralException(); //! This should only be used by the exception manager in order to display what went wrong. const char * GetMsg() const; protected: GeneralException(); char * msg; static char t[BUFSIZ]; }; char * xstrdup(const char *); void * xmalloc(size_t) throw (GeneralException); void * xrealloc(void *, size_t); int xpipe(int *, int = 0) throw (GeneralException); pid_t xfork() throw (GeneralException); //! This will simply throw the Exit exception. void xexit(int) throw (GeneralException); void xexception(const String &) throw (GeneralException); class MemoryException : public GeneralException { public: MemoryException(ssize_t); }; class TaskNotFound : public GeneralException { public: TaskNotFound(); }; enum op_t { IO_WRITE = 1, IO_READ }; class IOGeneral : public GeneralException { public: IOGeneral(String); protected: IOGeneral(); }; class IOException : public IOGeneral { public: IOException(String, op_t, ssize_t); }; class IOAgain : public IOGeneral { public: IOAgain(); }; class TaskSwitch : public GeneralException { public: TaskSwitch(); }; //! This exception can be thrown anyway, in order to exit nicely the software. /*! My suggestion when using this exception, is to add a special manager, in order to handle clean up, in the same manner as the atexit function. */ class Exit : public GeneralException { public: //! The provided code should be the exit code. Exit(int code); //! Fetches the exit code out of the Exit exception. int GetCode(); private: int code; }; class printer_t : public Base { public: virtual bool printm(int, const char *, va_list) = 0; }; extern printer_t * printer; class locker_t : public Base { public: virtual void lock() = 0; virtual void unlock() = 0; }; extern locker_t * locker; #define LOCK if (locker) locker->lock() #define UNLOCK if (locker) locker->unlock(); #include #endif