You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucy.apache.org by ma...@apache.org on 2009/09/15 03:21:11 UTC

svn commit: r814952 - in /lucene/lucy/trunk: core/Lucy/Object/Err.bp core/Lucy/Object/Err.c perl/lib/Lucy.pm perl/lib/Lucy/Object/Err.pm perl/xs/Lucy/Object/Err.c

Author: marvin
Date: Tue Sep 15 01:21:10 2009
New Revision: 814952

URL: http://svn.apache.org/viewvc?rev=814952&view=rev
Log:
Commit LUCY-46, adding the exception class Lucy::Object::Err.

Added:
    lucene/lucy/trunk/core/Lucy/Object/Err.bp   (with props)
    lucene/lucy/trunk/core/Lucy/Object/Err.c   (with props)
    lucene/lucy/trunk/perl/lib/Lucy/Object/Err.pm   (with props)
    lucene/lucy/trunk/perl/xs/Lucy/Object/Err.c   (with props)
Modified:
    lucene/lucy/trunk/perl/lib/Lucy.pm

Added: lucene/lucy/trunk/core/Lucy/Object/Err.bp
URL: http://svn.apache.org/viewvc/lucene/lucy/trunk/core/Lucy/Object/Err.bp?rev=814952&view=auto
==============================================================================
--- lucene/lucy/trunk/core/Lucy/Object/Err.bp (added)
+++ lucene/lucy/trunk/core/Lucy/Object/Err.bp Tue Sep 15 01:21:10 2009
@@ -0,0 +1,182 @@
+parcel Lucy;
+
+/** 
+ * Exception.
+ * 
+ * Most of the time when Lucy encounters an error, it tries to raise a
+ * Lucy::Object::Err exception with an error message and context
+ * information.
+ * 
+ * At present, it is only safe to catch exceptions which are specifically
+ * documented as catchable; most times when an Err is raised, Lucy leaks
+ * memory.
+ */
+
+class Lucy::Object::Err extends Lucy::Object::Obj {
+
+    CharBuf *mess;
+
+    inert incremented Err*
+    new(decremented CharBuf *mess);
+
+    inert Err*
+    init(Err *self, decremented CharBuf *mess);
+
+    public void
+    Destroy(Err *self);
+
+    public incremented CharBuf*
+    To_String(Err *self);
+
+    void*
+    To_Host(Err *self);
+
+    /** Concatenate the supplied argument onto the internal "mess". 
+     */
+    public void
+    Cat_Mess(Err *self, const CharBuf *mess);
+
+    public CharBuf*
+    Get_Mess(Err *self);
+
+    public incremented Err*
+    Make(Err *self);
+
+    /** Print an error message to stderr with some C contextual information.
+     * Usually invoked via the WARN(pattern, ...) macro.
+     */
+    inert void
+    warn_at(const char *file, int line, const char *func, 
+            const char *pattern, ...);
+
+    /** Raise an exception. Usually invoked via the THROW macro.
+     */
+    inert void
+    throw_at(VTable *vtable, const char *file, int line, const char *func,
+               const char *pattern, ...);
+
+    /** Raise an exception.  Clean up the supplied message by decrementing its
+     * refcount.
+     *
+     * @param vtable The vtable for the Err class to throw.
+     * @param message Error message, to be output verbatim.
+     */
+    inert void
+    throw_mess(VTable *vtable, decremented CharBuf *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 CharBuf *message);
+
+    /** Create a formatted error message.  Ususally invoked via the MAKE_MESS
+     * macro.
+     */
+    inert CharBuf*
+    make_mess(const char *file, int line, const char *func,
+              const char *pattern, ...);
+
+    /** Test that <code>obj</code> belongs to the class represented by
+     * <code>vtable</code>, and throw an error if it's not.
+     * 
+     * @return the object.
+     */
+    inert Obj*
+    assert_is_a(Obj *obj, VTable *vtable, const char *file, int line, 
+                const char *func);
+
+    /** Verify that an object belongs to a subclass and not an abstract class.
+     */
+    inert inline void
+    abstract_class_check(Obj *obj, VTable *vtable);
+}
+
+__C__
+#ifdef CHY_HAS_FUNC_MACRO
+ #define LUCY_ERR_FUNC_MACRO CHY_FUNC_MACRO
+#else
+ #define LUCY_ERR_FUNC_MACRO NULL
+#endif
+
+/* Macro version of lucy_Err_throw_at which inserts contextual information
+ * automatically, provided that the compiler supports the necessary features.
+ */
+#ifdef CHY_HAS_VARIADIC_MACROS
+ #ifdef CHY_HAS_ISO_VARIADIC_MACROS
+  #define LUCY_THROW(_vtable, ...) \
+    lucy_Err_throw_at(_vtable, __FILE__, __LINE__, LUCY_ERR_FUNC_MACRO, \
+        __VA_ARGS__)
+  #define LUCY_WARN(...) \
+    lucy_Err_warn_at(__FILE__, __LINE__, LUCY_ERR_FUNC_MACRO, __VA_ARGS__)
+  #define LUCY_MAKE_MESS(...) \
+    lucy_Err_make_mess(__FILE__, __LINE__, LUCY_ERR_FUNC_MACRO, \
+        __VA_ARGS__)
+ #elif defined(CHY_HAS_GNUC_VARIADIC_MACROS)
+  #define LUCY_THROW(_vtable, args...) \
+    lucy_Err_throw_at(_vtable, __FILE__, __LINE__, \
+        LUCY_ERR_FUNC_MACRO, ##args)
+  #define LUCY_WARN(args...) \
+    lucy_Err_warn_at(__FILE__, __LINE__, LUCY_ERR_FUNC_MACRO, ##args)
+  #define LUCY_MAKE_MESS(args...) \
+    lucy_Err_make_mess(__FILE__, __LINE__, LUCY_ERR_FUNC_MACRO, ##args)
+ #endif
+#else
+  void 
+  LUCY_THROW(lucy_VTable *vtable, char* format, ...);
+  void 
+  LUCY_WARN(char* format, ...);
+  void 
+  LUCY_MAKE_MESS(char* format, ...);
+#endif
+
+#define LUCY_ASSERT_IS_A(_obj, _vtable) \
+    lucy_Err_assert_is_a((lucy_Obj*)_obj, (_vtable), \
+        __FILE__, __LINE__, LUCY_ERR_FUNC_MACRO)
+
+static CHY_INLINE void
+lucy_Err_abstract_class_check(lucy_Obj *obj, lucy_VTable *vtable)
+{
+    lucy_VTable *const my_vtable = *(lucy_VTable**)obj;
+    if (my_vtable == vtable) {
+        Lucy_Obj_Dec_RefCount(obj);
+        LUCY_THROW(LUCY_ERR, "%o is an abstract class",
+            Lucy_Obj_Get_Class_Name(obj));
+    }
+}
+
+#define LUCY_ABSTRACT_CLASS_CHECK(_obj, _vtable) \
+    lucy_Err_abstract_class_check(((lucy_Obj*)_obj), _vtable)
+
+#ifdef LUCY_USE_SHORT_NAMES
+  #define THROW                 LUCY_THROW
+  #define WARN                  LUCY_WARN
+  #define MAKE_MESS             LUCY_MAKE_MESS
+  #define ERR_FUNC_MACRO        LUCY_ERR_FUNC_MACRO
+  #define ASSERT_IS_A           LUCY_ASSERT_IS_A
+  #define ABSTRACT_CLASS_CHECK  LUCY_ABSTRACT_CLASS_CHECK
+#endif
+__END_C__
+
+/* Copyright 2009 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+

Propchange: lucene/lucy/trunk/core/Lucy/Object/Err.bp
------------------------------------------------------------------------------
    svn:eol-style = native

Added: lucene/lucy/trunk/core/Lucy/Object/Err.c
URL: http://svn.apache.org/viewvc/lucene/lucy/trunk/core/Lucy/Object/Err.c?rev=814952&view=auto
==============================================================================
--- lucene/lucy/trunk/core/Lucy/Object/Err.c (added)
+++ lucene/lucy/trunk/core/Lucy/Object/Err.c Tue Sep 15 01:21:10 2009
@@ -0,0 +1,204 @@
+#define C_LUCY_ERR
+#define C_LUCY_OBJ
+#define C_LUCY_VTABLE
+#define LUCY_USE_SHORT_NAMES
+#define CHY_USE_SHORT_NAMES
+
+#include <string.h>
+#include <stdio.h>
+#include <ctype.h>
+
+#include "Lucy/Object/Err.h"
+#include "Lucy/Object/CharBuf.h"
+#include "Lucy/Object/VTable.h"
+
+Err*
+Err_new(CharBuf *mess)
+{
+    Err *self = (Err*)VTable_Make_Obj(ERR);
+    return Err_init(self, mess);
+}
+
+Err*
+Err_init(Err *self, CharBuf *mess)
+{
+    self->mess = mess;
+    return self;
+}
+
+void
+Err_destroy(Err *self)
+{
+    DECREF(self->mess);
+    SUPER_DESTROY(self, ERR);
+}
+
+Err*
+Err_make(Err *self)
+{
+    UNUSED_VAR(self);
+    return Err_new(CB_new(0));
+}
+
+CharBuf*
+Err_to_string(Err *self)
+{
+    return (CharBuf*)INCREF(self->mess);
+}
+
+void
+Err_cat_mess(Err *self, const CharBuf *mess)
+{
+    CB_Cat(self->mess, mess);
+}
+
+/* Fallbacks in case variadic macros aren't available. */
+#ifndef CHY_HAS_VARIADIC_MACROS
+void
+THROW(VTable *vtable, char *pattern, ...)
+{
+    va_list args;
+    Err_make_t make 
+        = (Err_make_t)METHOD(ASSERT_IS_A(vtable, VTABLE), Err, Make);
+    Err *err = ASSERT_IS_A(make(NULL), ERR);
+    CharBuf *mess = Err_Get_Mess(err);
+
+    va_start(args, pattern);
+    CB_VCatF(message, pattern, args);
+    va_end(args);
+
+    Err_do_throw(err);
+}
+void
+LUCY_WARN(char *pattern, ...)
+{
+    va_list args;
+    CharBuf *const message = CB_new(strlen(pattern) + 10);
+
+    va_start(args, pattern);
+    CB_VCatF(message, pattern, args);
+    va_end(args);
+
+    Err_warn_mess(message);
+}
+CharBuf*
+LUCY_MAKE_MESS(char *pattern, ...)
+{
+    va_list args;
+    CharBuf *const message = CB_new(strlen(pattern) + 10);
+
+    va_start(args, pattern);
+    CB_VCatF(message, pattern, args);
+    va_end(args);
+
+    return message;
+}
+#endif
+
+
+static void
+S_vcat_mess(CharBuf *message, const char *file, int line, const char *func, 
+            const char *pattern, va_list args)
+{
+    size_t guess_len = strlen(file) 
+                     + func ? strlen(func) : 0 
+                     + strlen(pattern) 
+                     + 30;
+    CB_Grow(message, guess_len);
+    CB_VCatF(message, pattern, args);
+    if (func != NULL)
+        CB_catf(message, ", %s at %s line %i32\n", func, file, (i32_t)line);
+    else 
+        CB_catf(message, " at %s line %i32\n", file, (i32_t)line);
+}
+
+CharBuf*
+Err_make_mess(const char *file, int line, const char *func, 
+               const char *pattern, ...)
+{
+    va_list args;
+    size_t guess_len = strlen(pattern) + strlen(file) + 20;
+    CharBuf *message = CB_new(guess_len);
+    va_start(args, pattern);
+    S_vcat_mess(message, file, line, func, pattern, args);
+    va_end(args);
+    return message;
+}
+
+void
+Err_warn_at(const char *file, int line, const char *func, 
+             const char *pattern, ...)
+{
+    va_list args;
+    CharBuf *message = CB_new(0);
+    va_start(args, pattern);
+    S_vcat_mess(message, file, line, func, pattern, args);
+    va_end(args);
+    Err_warn_mess(message);
+}
+
+CharBuf*
+Err_get_mess(Err *self) { return self->mess; }
+
+void
+lucy_Err_throw_at(VTable *vtable, const char *file, int line,
+                  const char *func, const char *pattern, ...)
+{
+    va_list args;
+    Err_make_t make 
+        = (Err_make_t)METHOD(ASSERT_IS_A(vtable, VTABLE), Err, Make);
+    Err *err = (Err*)ASSERT_IS_A(make(NULL), ERR);
+    CharBuf *mess = Err_Get_Mess(err);
+
+    va_start(args, pattern);
+    S_vcat_mess(mess, file, line, func, pattern, args);
+    va_end(args);
+
+    Err_do_throw(err);
+}
+
+/* Inlined, slightly optimized version of Obj_is_a. */
+static INLINE bool_t
+SI_obj_is_a(Obj *obj, VTable *target_vtable)
+{
+    VTable *vtable = obj->vtable;
+
+    while (vtable != NULL) {
+        if (vtable == target_vtable)
+            return true;
+        vtable = vtable->parent;
+    }
+
+    return false;
+}
+
+Obj*
+lucy_Err_assert_is_a(Obj *obj, VTable *vtable, const char *file, int line, 
+                      const char *func)
+{
+    if (!obj) {
+        Err_throw_at(ERR, file, line, func, "Object isn't a %o, it's NULL",
+            VTable_Get_Name(vtable));
+    }
+    else if ( !SI_obj_is_a(obj, vtable) ) {
+        Err_throw_at(ERR, file, line, func, "Object isn't a %o, it's a %o",
+            VTable_Get_Name(vtable), Obj_Get_Class_Name(obj));
+    }
+    return obj;
+}
+
+/* Copyright 2009 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+

Propchange: lucene/lucy/trunk/core/Lucy/Object/Err.c
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: lucene/lucy/trunk/perl/lib/Lucy.pm
URL: http://svn.apache.org/viewvc/lucene/lucy/trunk/perl/lib/Lucy.pm?rev=814952&r1=814951&r2=814952&view=diff
==============================================================================
--- lucene/lucy/trunk/perl/lib/Lucy.pm (original)
+++ lucene/lucy/trunk/perl/lib/Lucy.pm Tue Sep 15 01:21:10 2009
@@ -13,7 +13,22 @@
 use Lucy::Autobinding;
 
 {
-    package KinoSearch::Object::VArray;
+    package Lucy::Object::Err;
+    sub do_to_string { shift->to_string }
+    use Carp qw( longmess );
+    use overload
+        '""'     => \&do_to_string,
+        fallback => 1;
+
+    sub do_throw {
+        my $err = shift;
+        $err->cat_mess( longmess() );
+        die $err;
+    }
+}
+
+{
+    package Lucy::Object::VArray;
     no warnings 'redefine';
     sub clone { CORE::shift->_clone }
 }

Added: lucene/lucy/trunk/perl/lib/Lucy/Object/Err.pm
URL: http://svn.apache.org/viewvc/lucene/lucy/trunk/perl/lib/Lucy/Object/Err.pm?rev=814952&view=auto
==============================================================================
--- lucene/lucy/trunk/perl/lib/Lucy/Object/Err.pm (added)
+++ lucene/lucy/trunk/perl/lib/Lucy/Object/Err.pm Tue Sep 15 01:21:10 2009
@@ -0,0 +1,32 @@
+use Lucy;
+
+1;
+
+__END__
+
+__BINDING__
+
+Boilerplater::Binding::Perl::Class->register(
+    parcel       => "Lucy",
+    class_name   => "Lucy::Object::Err",
+    bind_methods => [qw( Cat_Mess )],
+);
+
+__COPYRIGHT__
+
+    /**
+     * Copyright 2009 The Apache Software Foundation
+     *
+     * Licensed under the Apache License, Version 2.0 (the "License");
+     * you may not use this file except in compliance with the License.
+     * You may obtain a copy of the License at
+     *
+     *     http://www.apache.org/licenses/LICENSE-2.0
+     *
+     * Unless required by applicable law or agreed to in writing, software
+     * distributed under the License is distributed on an "AS IS" BASIS,
+     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+     * implied.  See the License for the specific language governing
+     * permissions and limitations under the License.
+     */
+

Propchange: lucene/lucy/trunk/perl/lib/Lucy/Object/Err.pm
------------------------------------------------------------------------------
    svn:eol-style = native

Added: lucene/lucy/trunk/perl/xs/Lucy/Object/Err.c
URL: http://svn.apache.org/viewvc/lucene/lucy/trunk/perl/xs/Lucy/Object/Err.c?rev=814952&view=auto
==============================================================================
--- lucene/lucy/trunk/perl/xs/Lucy/Object/Err.c (added)
+++ lucene/lucy/trunk/perl/xs/Lucy/Object/Err.c Tue Sep 15 01:21:10 2009
@@ -0,0 +1,63 @@
+#include "xs/XSBind.h"
+
+void
+lucy_Err_do_throw(lucy_Err *err)
+{
+    dSP;
+    SV *error_sv = (SV*)Lucy_Err_To_Host(err);
+    LUCY_DECREF(err);
+    ENTER;
+    SAVETMPS;
+    PUSHMARK(SP);
+    XPUSHs( sv_2mortal(error_sv) );
+    PUTBACK;
+    call_pv("Lucy::Object::Err::do_throw", G_DISCARD);
+    FREETMPS;
+    LEAVE;
+}
+
+void*
+lucy_Err_to_host(lucy_Err *self)
+{
+    lucy_Err_to_host_t super_to_host 
+        = (lucy_Err_to_host_t)LUCY_SUPER_METHOD(LUCY_ERR, Err, To_Host);
+    SV *perl_obj = super_to_host(self);
+    XSBind_enable_overload(perl_obj);
+    return perl_obj;
+}
+
+void
+lucy_Err_throw_mess(lucy_VTable *vtable, lucy_CharBuf *message) 
+{
+    lucy_Err_make_t make = (lucy_Err_make_t)LUCY_METHOD(
+        LUCY_ASSERT_IS_A(vtable, LUCY_VTABLE), Err, Make);
+    lucy_Err *err = (lucy_Err*)LUCY_ASSERT_IS_A(make(NULL), LUCY_ERR);
+    Lucy_Err_Cat_Mess(err, message);
+    LUCY_DECREF(message);
+    lucy_Err_do_throw(err);
+}
+
+void
+lucy_Err_warn_mess(lucy_CharBuf *message) 
+{
+    SV *error_sv = XSBind_cb_to_sv(message);
+    LUCY_DECREF(message);
+    warn(SvPV_nolen(error_sv));
+    SvREFCNT_dec(error_sv);
+}
+
+/* Copyright 2009 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+

Propchange: lucene/lucy/trunk/perl/xs/Lucy/Object/Err.c
------------------------------------------------------------------------------
    svn:eol-style = native