summaryrefslogtreecommitdiff
path: root/graphics/sam2p/error.hpp
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /graphics/sam2p/error.hpp
Initial commit
Diffstat (limited to 'graphics/sam2p/error.hpp')
-rw-r--r--graphics/sam2p/error.hpp170
1 files changed, 170 insertions, 0 deletions
diff --git a/graphics/sam2p/error.hpp b/graphics/sam2p/error.hpp
new file mode 100644
index 0000000000..af9a58ed20
--- /dev/null
+++ b/graphics/sam2p/error.hpp
@@ -0,0 +1,170 @@
+/* error.hpp -- handling errors/warnings etc.
+ * by pts@fazekas.hu at Fri Mar 1 11:32:36 CET 2002
+ */
+
+#ifdef __GNUC__
+#ifndef __clang__
+#pragma interface
+#endif
+#endif
+
+#ifndef ERROR_HPP
+#define ERROR_HPP 1
+
+#include "config2.h"
+#include "gensi.hpp"
+
+/** This may be usafe if an error happens inside an error. Usage:
+ * Error::sev(Error::WARNING) << "Zero-length image." << (Error*)0;
+ */
+class Error {
+ public:
+ static char const* banner0;
+ static char const* argv0;
+ static char const* tmpargv0;
+ static char const* long_argv0;
+ /** Error types. */
+ BEGIN_STATIC_ENUM(int,level_t)
+ ASSERT=4, FATAL=3,
+ EERROR=2, /* ERROR conflicts with the Win32 API :-( */
+ ERROR_CONT=-2, /* error, but continue running program */
+ WARNING=-3,
+ WARNING_DEFER=-4, /* warning, but defer (and later possibly omit) displaying it */
+ NOTICE=-5,
+ NOTICE_DEFER=-6, INFO=-111, DEBUG=-222
+ END_STATIC_ENUM()
+ /** Standard error stream (stderr) of the current process. */
+ static GenBuffer::Writable * serr;
+ /** Returns address to statically allocated buffer. */
+ static char const*level2str(level_t level);
+ /** This is the (carefully hidden :-)) method of raising errors (i.e
+ * displaying error messages and terminating the program).
+ * Example usage:
+ * Error::sev(Error::WARNING_DEFER) << "check_rule: /BMP requires "
+ * "/Predictor " << 1 << (Error*)0;
+ * The error is interpreted according to the current policy. The policy
+ * divides errors into three categories:
+ *
+ * -- secret: nothing happens (even the error message is _not_ printed)
+ * -- recorded: nothing happens (even the error message is _not_ printed),
+ * but the message is remembered for further processing.
+ * -- printed: the error message is printed, and program execution continues
+ * Before printing this message, all recorded errors on the policy stack
+ * are also printed (deepest first).
+ * -- killer: like `printed', but runs cleanup handlers and terminates the
+ * program immediately.
+ *
+ * @param level is one of the constants mentioned above (FATAL, EERROR,
+ * WARNING, NOTICE etc). Can be positive, zero or negative. The larger
+ * the `level', the more severe the error is. The default policy is:
+ * level>=0 errors are killer, -99<=level<=-1 errors are printed,
+ * -199<=level<=-100 are recorded and level<=-200 errors are secret.
+ */
+ static GenBuffer::Writable& sev(level_t level);
+
+ public:
+ /** The field order is important in this struct, because of the initializers. */
+ struct Policy {
+ /** All recorded messages. Default: NULL. This means empty. */
+ SimBuffer::B *record;
+ /** The highest level of Secret category encountered so far. Default: -9999 */
+ level_t topSecret;
+ /** The highest level of Recorded category encountered so far. Default: -9999 */
+ level_t topRecorded;
+ /** Lower bound of these categories in this policy. */
+ level_t killer, printed, recorded;
+ /** Error stream to print printed and killer messages. */
+ GenBuffer::Writable *err;
+ /** NULL for top policy */
+ Policy *prev, *next;
+ /** Level of the current error being raised. */
+ level_t curlev;
+ };
+ protected:
+ /** Boundaries of the policy stack. */
+ static Policy *policy_top, *policy_bottom;
+ public:
+ friend GenBuffer::Writable& operator <<(GenBuffer::Writable&,Error*);
+ /** Creates a new policy and makes it active by pushing it onto the top of
+ * the policy stack.
+ */
+ static void pushPolicy(level_t killer_, level_t printed_, level_t recorded_, GenBuffer::Writable *err=(GenBuffer::Writable*)NULLP);
+ /** @return the messages already recorded, and clears the `record' entry
+ * of the current policy. The caller is responsible for deleting the
+ * pointer returned. May return NULLP for empty records. Typical example:
+ * delete Error::getRecorded();
+ */
+ static SimBuffer::B *getRecorded();
+ /** Prints all recorded error messages, and removes the topmost element of
+ * the policy stack. Typical example:
+ * delete Error::getRecorded(); popPolicy();
+ */
+ static void popPolicy();
+
+ /** @example Error::setTopPrinted(Error::ERROR_CONT); suppress anything
+ * below error, such as warnings.
+ */
+ static void setTopPrinted(level_t printed_);
+
+ static level_t getTopPrinted();
+
+ /** The Cleanup mechanism is similar to atexit(3) and on_exit(3). This is
+ * just a simple struct with no destructors, virtual methods or inheritance.
+ *
+ * Additional data (char[] buffer) can be allocated and stored right
+ * after the object (this+1), it can be retrieved with getBuf(), and it will
+ * be deleted when the object is deleted by runCleanups().
+ */
+ struct Cleanup {
+ /** Must _not_ cause any Errors.
+ * @return an exit code. If larger than the current one, replaces it
+ */
+ typedef int (*handler_t)(Cleanup*);
+ /** Owned externally. */
+ handler_t handler;
+ /** size of extra data allocated at getBuf(). */
+ slen_t bufSize;
+ /** Arbitrary data, owned by `handler': handler' must delete `data'
+ * when called.
+ */
+ void *data;
+ /** NULLP: no next, end of chain */
+ Cleanup *next;
+ inline char *getBuf() { return (char*)(this+1); }
+ inline slen_t getSize() { return bufSize; }
+ };
+ /** Creates and returns a new Cleanup, and registers it in front of the
+ * existing ones. Copies `handler' and `data' to it. Also allocates `bufSize' bytes
+ * of char[] buffer (at result->getBuf()) owned by the cleanup, but doesn't
+ * initialize the buffer.
+ *
+ * Doesn't take ownership of `handler', takes ownership of `data'.
+ * `handler' must delete `data' or pass on ownership when called,
+ * typically by runCleanups().
+ */
+ static Cleanup* newCleanup(Cleanup::handler_t handler, void *data, slen_t bufSize);
+ /** Creates and returns a new Cleanup, and registers it in front of the
+ * existing ones. Copies `handler' and `data' to it. Also allocates
+ * strlen(bufCstr)+1 bytes of char[] buffer (at result->getBuf()) owned by
+ * the cleanup, and initializes it from bufCstr.
+ *
+ * Doesn't take ownership of `handler', takes ownership of `data'.
+ * `handler' must delete `data' or pass on ownership when called,
+ * typically by runCleanups().
+ */
+ static Cleanup* newCleanup(Cleanup::handler_t handler, void *data, char const*bufCstr);
+ /** Reverts to the default logging policy,
+ * executes the cleanup handlers (in reverse-registration order),
+ * unregisters and deletes all the cleanups, and returns the
+ * new exit code, which is at least exitCode.
+ */
+ static int runCleanups(int exitCode);
+ /* Exits from the process with the specified exit code. */
+ static void cexit(int exitCode);
+ protected:
+ static Cleanup *first_cleanup;
+};
+
+GenBuffer::Writable& operator <<(GenBuffer::Writable&,Error*);
+
+#endif