Clownfish

 view release on metacpan or  search on metacpan

cfcore/Clownfish/Err.cfh  view on Meta::CPAN

    throw_mess(Class *klass, decremented String *message);

    /** Invoke host exception handling.
     */
    inert void
    do_throw(decremented Err *self);

    /** Invoke host warning mechanism.  Clean up the supplied message by
     * decrementing its refcount.
     *
     * @param message Error message, to be output verbatim.
     */
    inert void
    warn_mess(decremented String *message);

    /** Create a formatted error message.  Ususally invoked via the MAKE_MESS
     * macro.
     */
    inert String*
    make_mess(const char *file, int line, const char *func,
              const char *pattern, ...);

    /** Verify that an object belongs to a subclass and not an abstract class.
     */
    inert inline void
    abstract_class_check(Obj *obj, Class *klass);

    /** Throw an error after abstract method `method_name` was called on
     * object `obj` of class `klass`.
     */
    inert void
    abstract_method_call(Obj *obj, Class *klass, const char *method_name);

    /** Throw an error after an invalid callback was called.
     */
    inert void
    invalid_callback(const char *method_name);

    /** On Windows, return a newly allocated buffer containing the string
     * description for the the last error in the thread.
     */
    inert char*
    win_error();
}

__C__
#ifdef CFISH_HAS_FUNC_MACRO
 #define CFISH_ERR_FUNC_MACRO CFISH_FUNC_MACRO
#else
 #define CFISH_ERR_FUNC_MACRO NULL
#endif

#define CFISH_ERR_ADD_FRAME(_error) \
    CFISH_Err_Add_Frame(_error, __FILE__, __LINE__, \
                        CFISH_ERR_FUNC_MACRO)

#define CFISH_RETHROW(_error) \
    cfish_Err_rethrow((cfish_Err*)_error, __FILE__, __LINE__, \
                      CFISH_ERR_FUNC_MACRO)

/** Macro version of cfish_Err_throw_at which inserts contextual information
 * automatically, provided that the compiler supports the necessary features.
 */
#ifdef CFISH_HAS_VARIADIC_MACROS
 #ifdef CFISH_HAS_ISO_VARIADIC_MACROS
  #define CFISH_THROW(_class, ...) \
    cfish_Err_throw_at(_class, __FILE__, __LINE__, CFISH_ERR_FUNC_MACRO, \
                       __VA_ARGS__)
  #define CFISH_WARN(...) \
    cfish_Err_warn_at(__FILE__, __LINE__, CFISH_ERR_FUNC_MACRO, __VA_ARGS__)
  #define CFISH_MAKE_MESS(...) \
    cfish_Err_make_mess(__FILE__, __LINE__, CFISH_ERR_FUNC_MACRO, \
                        __VA_ARGS__)
 #elif defined(CFISH_HAS_GNUC_VARIADIC_MACROS)
  #define CFISH_THROW(_class, args...) \
    cfish_Err_throw_at(_class, __FILE__, __LINE__, \
                       CFISH_ERR_FUNC_MACRO, ##args)
  #define CFISH_WARN(args...) \
    cfish_Err_warn_at(__FILE__, __LINE__, CFISH_ERR_FUNC_MACRO, ##args)
  #define CFISH_MAKE_MESS(args...) \
    cfish_Err_make_mess(__FILE__, __LINE__, CFISH_ERR_FUNC_MACRO, ##args)
 #endif
#else
  void
  CFISH_THROW(cfish_Class *klass, char* format, ...);
  void
  CFISH_WARN(char* format, ...);
  cfish_String*
  CFISH_MAKE_MESS(char* format, ...);
#endif

static CFISH_INLINE void
cfish_Err_abstract_class_check(cfish_Obj *obj, cfish_Class *klass) {
    cfish_Class *const my_class = (cfish_Class*)((cfish_Dummy*)obj)->klass;
    if (my_class == klass) {
        cfish_String *mess = CFISH_MAKE_MESS("%o is an abstract class",
                                              cfish_Obj_get_class_name(obj));
        CFISH_DECREF_NN(obj);
        cfish_Err_throw_mess(CFISH_ERR, mess);
    }
}

#define CFISH_ABSTRACT_CLASS_CHECK(_obj, _class) \
    cfish_Err_abstract_class_check(((cfish_Obj*)_obj), _class)

#ifdef CFISH_USE_SHORT_NAMES
  #define THROW                 CFISH_THROW
  #define RETHROW               CFISH_RETHROW
  #define WARN                  CFISH_WARN
  #define MAKE_MESS             CFISH_MAKE_MESS
  #define ERR_ADD_FRAME         CFISH_ERR_ADD_FRAME
  #define ERR_FUNC_MACRO        CFISH_ERR_FUNC_MACRO
  #define ABSTRACT_CLASS_CHECK  CFISH_ABSTRACT_CLASS_CHECK
#endif
__END_C__




( run in 1.179 second using v1.01-cache-2.11-cpan-5c0b1e786e0 )