diff options
Diffstat (limited to 'src/error.h')
-rw-r--r-- | src/error.h | 316 |
1 files changed, 123 insertions, 193 deletions
diff --git a/src/error.h b/src/error.h index a12a76b..16136b9 100644 --- a/src/error.h +++ b/src/error.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012-2017 Robin Haberkorn + * Copyright (C) 2012-2021 Robin Haberkorn * * 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 @@ -14,205 +14,135 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ - -#ifndef __ERROR_H -#define __ERROR_H - -#include <exception> -#include <typeinfo> +#pragma once #include <glib.h> -#include <glib/gprintf.h> #include "sciteco.h" -#include "memory.h" #include "string-utils.h" -namespace SciTECO { - -/** - * Thrown as exception to signify that program - * should be terminated. - */ -class Quit : public Object {}; - -/** - * Thrown as exception to cause a macro to - * return or a command-line termination. +/* + * FIXME: Introducing a second error quark might be useful to distinguish + * errors that can be cought by SciTECO macros from errors that must always + * propagate (TECO_ERROR_QUIT, TECO_ERROR_RETURN). + * On the other hand, these error codes will probably soon become obsolete + * when the SciTECO call stack no longer corresponds with the C callstack. */ -class Return : public Object { -public: - guint args; - - Return(guint _args = 0) : args(_args) {} -}; - -class Error : public Object { - GSList *frames; - -public: - gchar *description; - gint pos; - gint line, column; - - class Frame : public Object { - public: - gint pos; - gint line, column; - - virtual Frame *copy() const = 0; - virtual ~Frame() {} - - virtual void display(gint nr) = 0; - }; - - class QRegFrame : public Frame { - gchar *name; - - public: - QRegFrame(const gchar *_name) - : name(g_strdup(_name)) {} - - Frame *copy() const; - - ~QRegFrame() - { - g_free(name); - } - - void display(gint nr); - }; - - class FileFrame : public Frame { - gchar *name; - - public: - FileFrame(const gchar *_name) - : name(g_strdup(_name)) {} - - Frame *copy() const; - - ~FileFrame() - { - g_free(name); - } - - void display(gint nr); - }; - - class EDHookFrame : public Frame { - gchar *type; - - public: - EDHookFrame(const gchar *_type) - : type(g_strdup(_type)) {} - - Frame *copy() const; - - ~EDHookFrame() - { - g_free(type); - } - - void display(gint nr); - }; - - class ToplevelFrame : public Frame { - public: - Frame *copy() const; - - void display(gint nr); - }; - - Error(const gchar *fmt, ...) G_GNUC_PRINTF(2, 3); - Error(const Error &inst); - ~Error(); - - inline void - set_coord(const gchar *str, gint _pos) - { - pos = _pos; - String::get_coord(str, pos, line, column); - } - - void add_frame(Frame *frame); - - void display_short(void); - void display_full(void); -}; +#define TECO_ERROR (g_quark_from_static_string("sciteco-error-quark")) -class StdError : public Error { -public: - StdError(const gchar *type, const std::exception &error) - : Error("%s: %s", type, error.what()) {} - StdError(const std::exception &error) - : Error("%s: %s", typeid(error).name(), error.what()) {} -}; +typedef enum { + /** Default (catch-all) error code */ + TECO_ERROR_FAILED = 0, -class GlibError : public Error { -public: - /** - * Construct error for glib's GError. - * Ownership of the error's resources is passed - * the GlibError object. + /* + * FIXME: Subsume all these errors under TECO_ERROR_SYNTAX or TECO_ERROR_FAIL? + * They will mainly be different in their error message. */ - GlibError(GError *gerror) - : Error("%s", gerror->message) - { - g_error_free(gerror); - } -}; - -class SyntaxError : public Error { -public: - SyntaxError(gchar chr) - : Error("Syntax error \"%c\" (%d)", chr, chr) {} -}; - -class ArgExpectedError : public Error { -public: - ArgExpectedError(const gchar *cmd) - : Error("Argument expected for <%s>", cmd) {} - ArgExpectedError(gchar cmd) - : Error("Argument expected for <%c>", cmd) {} -}; - -class MoveError : public Error { -public: - MoveError(const gchar *cmd) - : Error("Attempt to move pointer off page with <%s>", - cmd) {} - MoveError(gchar cmd) - : Error("Attempt to move pointer off page with <%c>", - cmd) {} -}; - -class RangeError : public Error { -public: - RangeError(const gchar *cmd) - : Error("Invalid range specified for <%s>", cmd) {} - RangeError(gchar cmd) - : Error("Invalid range specified for <%c>", cmd) {} -}; - -class InvalidQRegError : public Error { -public: - InvalidQRegError(const gchar *name, bool local = false) - : Error("Invalid Q-Register \"%s%s\"", - local ? "." : "", name) {} - InvalidQRegError(gchar name, bool local = false) - : Error("Invalid Q-Register \"%s%c\"", - local ? "." : "", name) {} -}; - -class QRegOpUnsupportedError : public Error { -public: - QRegOpUnsupportedError(const gchar *name, bool local = false) - : Error("Operation unsupported on " - "Q-Register \"%s%s\"", - local ? "." : "", name) {} -}; - -} /* namespace SciTECO */ - -#endif + TECO_ERROR_SYNTAX, + TECO_ERROR_ARGEXPECTED, + TECO_ERROR_MOVE, + TECO_ERROR_WORDS, + TECO_ERROR_RANGE, + TECO_ERROR_INVALIDQREG, + TECO_ERROR_QREGOPUNSUPPORTED, + TECO_ERROR_QREGCONTAINSNULL, + TECO_ERROR_MEMLIMIT, + + /** Interrupt current operation */ + TECO_ERROR_INTERRUPTED, + + /** Thrown to signal command line replacement */ + TECO_ERROR_CMDLINE = 0x80, + /** Thrown as exception to cause a macro to return or a command-line termination. */ + TECO_ERROR_RETURN, + /** Thrown as exception to signify that program should be terminated. */ + TECO_ERROR_QUIT +} teco_error_t; + +static inline void +teco_error_syntax_set(GError **error, gchar chr) +{ + g_set_error(error, TECO_ERROR, TECO_ERROR_SYNTAX, + "Syntax error \"%c\" (%d)", chr, chr); +} + +static inline void +teco_error_argexpected_set(GError **error, const gchar *cmd) +{ + g_set_error(error, TECO_ERROR, TECO_ERROR_ARGEXPECTED, + "Argument expected for <%s>", cmd); +} + +static inline void +teco_error_move_set(GError **error, const gchar *cmd) +{ + g_set_error(error, TECO_ERROR, TECO_ERROR_MOVE, + "Attempt to move pointer off page with <%s>", cmd); +} + +static inline void +teco_error_words_set(GError **error, const gchar *cmd) +{ + g_set_error(error, TECO_ERROR, TECO_ERROR_MOVE, + "Not enough words to delete with <%s>", cmd); +} + +static inline void +teco_error_range_set(GError **error, const gchar *cmd) +{ + g_set_error(error, TECO_ERROR, TECO_ERROR_RANGE, + "Invalid range specified for <%s>", cmd); +} + +static inline void +teco_error_invalidqreg_set(GError **error, const gchar *name, gsize len, gboolean local) +{ + g_autofree gchar *name_printable = teco_string_echo(name, len); + g_set_error(error, TECO_ERROR, TECO_ERROR_INVALIDQREG, + "Invalid %sQ-Register \"%s\"", local ? "local " : "", name_printable); +} + +static inline void +teco_error_qregopunsupported_set(GError **error, const gchar *name, gsize len, gboolean local) +{ + g_autofree gchar *name_printable = teco_string_echo(name, len); + g_set_error(error, TECO_ERROR, TECO_ERROR_QREGOPUNSUPPORTED, + "Operation unsupported on %sQ-Register \"%s\"", local ? "local " : "", name_printable); +} + +static inline void +teco_error_qregcontainsnull_set(GError **error, const gchar *name, gsize len, gboolean local) +{ + g_autofree gchar *name_printable = teco_string_echo(name, len); + g_set_error(error, TECO_ERROR, TECO_ERROR_QREGCONTAINSNULL, + "%sQ-Register \"%s\" contains null-byte", local ? "Local " : "", name_printable); +} + +static inline void +teco_error_interrupted_set(GError **error) +{ + g_set_error_literal(error, TECO_ERROR, TECO_ERROR_INTERRUPTED, "Interrupted"); +} + +extern guint teco_error_return_args; + +static inline void +teco_error_return_set(GError **error, guint args) +{ + teco_error_return_args = args; + g_set_error_literal(error, TECO_ERROR, TECO_ERROR_RETURN, ""); +} + +extern guint teco_error_pos, teco_error_line, teco_error_column; + +void teco_error_set_coord(const gchar *str, guint pos); + +void teco_error_display_short(const GError *error); +void teco_error_display_full(const GError *error); + +void teco_error_add_frame_qreg(const gchar *name, gsize len); +void teco_error_add_frame_file(const gchar *name); +void teco_error_add_frame_edhook(const gchar *type); +void teco_error_add_frame_toplevel(void); + +void teco_error_clear_frames(void); |