Enlightenment CVS committal

Author  : mej
Project : eterm
Module  : libast

Dir     : eterm/libast/src


Modified Files:
        array.c dlinked_list.c linked_list.c obj.c objpair.c tok.c 


Log Message:
Fri Jan 30 17:55:47 2004                        Michael Jennings (mej)

Working on adding assertions/requires for NULL object checks.

Also making sure list elements can be NULL so insert_at() can resize
a list.

===================================================================
RCS file: /cvsroot/enlightenment/eterm/libast/src/array.c,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -3 -r1.13 -r1.14
--- array.c     24 Jan 2004 19:55:02 -0000      1.13
+++ array.c     30 Jan 2004 22:55:18 -0000      1.14
@@ -21,7 +21,7 @@
  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  */
 
-static const char cvs_ident[] = "$Id: array.c,v 1.13 2004/01/24 19:55:02 mej Exp $";
+static const char cvs_ident[] = "$Id: array.c,v 1.14 2004/01/30 22:55:18 mej Exp $";
 
 #ifdef HAVE_CONFIG_H
 # include <config.h>
@@ -151,15 +151,22 @@
     spif_array_t self;
 
     self = SPIF_ALLOC(array);
-    spif_array_list_init(self);
+    if (!spif_array_list_init(self)) {
+        SPIF_DEALLOC(self);
+        self = SPIF_NULL_TYPE(array);
+    }
     return self;
 }
 
 static spif_bool_t
 spif_array_list_init(spif_array_t self)
 {
-    spif_obj_init(SPIF_OBJ(self));
-    spif_obj_set_class(SPIF_OBJ(self), SPIF_CLASS(SPIF_LISTCLASS_VAR(array)));
+    ASSERT_RVAL(!SPIF_ARRAY_ISNULL(self), FALSE);
+    if (!spif_obj_init(SPIF_OBJ(self))) {
+        return FALSE;
+    } else if (!spif_obj_set_class(SPIF_OBJ(self), 
SPIF_CLASS(SPIF_LISTCLASS_VAR(array)))) {
+        return FALSE;
+    }
     self->len = 0;
     self->items = SPIF_NULL_TYPE_C(spif_obj_t *);
     return TRUE;
@@ -171,15 +178,22 @@
     spif_array_t self;
 
     self = SPIF_ALLOC(array);
-    spif_array_vector_init(self);
+    if (!spif_array_vector_init(self)) {
+        SPIF_DEALLOC(self);
+        self = SPIF_NULL_TYPE(array);
+    }
     return self;
 }
 
 static spif_bool_t
 spif_array_vector_init(spif_array_t self)
 {
-    spif_obj_init(SPIF_OBJ(self));
-    spif_obj_set_class(SPIF_OBJ(self), SPIF_CLASS(SPIF_VECTORCLASS_VAR(array)));
+    ASSERT_RVAL(!SPIF_ARRAY_ISNULL(self), FALSE);
+    if (!spif_obj_init(SPIF_OBJ(self))) {
+        return FALSE;
+    } else if (!spif_obj_set_class(SPIF_OBJ(self), 
SPIF_CLASS(SPIF_VECTORCLASS_VAR(array)))) {
+        return FALSE;
+    }
     self->len = 0;
     self->items = SPIF_NULL_TYPE_C(spif_obj_t *);
     return TRUE;
@@ -190,6 +204,7 @@
 {
     spif_listidx_t i;
 
+    ASSERT_RVAL(!SPIF_ARRAY_ISNULL(self), FALSE);
     for (i = 0; i < self->len; i++) {
         if (!SPIF_OBJ_ISNULL(self->items[i])) {
             SPIF_OBJ_DEL(self->items[i]);
@@ -203,9 +218,12 @@
 static spif_bool_t
 spif_array_del(spif_array_t self)
 {
-    spif_array_done(self);
+    spif_bool_t t;
+
+    ASSERT_RVAL(!SPIF_ARRAY_ISNULL(self), FALSE);
+    t = spif_array_done(self);
     SPIF_DEALLOC(self);
-    return TRUE;
+    return t;
 }
 
 static spif_str_t
@@ -233,7 +251,13 @@
         for (i = 0; i < self->len; i++) {
             spif_obj_t o = self->items[i];
             sprintf(tmp, "item %d", i);
-            buff = SPIF_OBJ_CALL_METHOD(o, show)(o, tmp, buff, indent + 2);
+            if (SPIF_OBJ_ISNULL(o)) {
+                char tmp2[4096];
+
+                SPIF_OBJ_SHOW_NULL(obj, tmp, buff, indent + 2, tmp2);
+            } else {
+                buff = SPIF_OBJ_CALL_METHOD(o, show)(o, tmp, buff, indent + 2);
+            }
         }
     }
 
@@ -248,12 +272,29 @@
 {
     spif_listidx_t i;
 
+    if (SPIF_ARRAY_ISNULL(self) && SPIF_ARRAY_ISNULL(other)) {
+        return SPIF_CMP_EQUAL;
+    } else if (SPIF_ARRAY_ISNULL(self)) {
+        return SPIF_CMP_LESS;
+    } else if (SPIF_ARRAY_ISNULL(other)) {
+        return SPIF_CMP_GREATER;
+    }
     for (i = 0; i < self->len; i++) {
-        if (!SPIF_CMP_IS_EQUAL(SPIF_OBJ_COMP(self->items[i], other->items[i]))) {
-            return FALSE;
+        spif_cmp_t c;
+
+        if (SPIF_OBJ_ISNULL(self->items[i]) && SPIF_OBJ_ISNULL(other->items[i])) {
+            continue;
+        } else if (SPIF_OBJ_ISNULL(self->items[i])) {
+            return SPIF_CMP_LESS;
+        } else if (SPIF_OBJ_ISNULL(other->items[i])) {
+            return SPIF_CMP_GREATER;
+        } 
+        c = SPIF_OBJ_COMP(self->items[i], other->items[i]);
+        if (!SPIF_CMP_IS_EQUAL(c)) {
+            return c;
         }
     }
-    return TRUE;
+    return SPIF_CMP_EQUAL;
 }
 
 static spif_array_t
@@ -262,7 +303,10 @@
     spif_array_t tmp;
     spif_listidx_t i;
 
+    ASSERT_RVAL(!SPIF_ARRAY_ISNULL(self), SPIF_NULL_TYPE(array));
+
     tmp = spif_array_list_new();
+    REQUIRE_RVAL(!SPIF_ARRAY_ISNULL(tmp), SPIF_NULL_TYPE(array));
     memcpy(tmp, self, SPIF_SIZEOF_TYPE(array));
     tmp->items = SPIF_CAST_C(spif_obj_t *) MALLOC(SPIF_SIZEOF_TYPE(obj) * self->len);
     for (i = 0; i < self->len; i++) {
@@ -277,7 +321,10 @@
     spif_array_t tmp;
     spif_listidx_t i;
 
+    ASSERT_RVAL(!SPIF_ARRAY_ISNULL(self), SPIF_NULL_TYPE(array));
+
     tmp = spif_array_vector_new();
+    REQUIRE_RVAL(!SPIF_ARRAY_ISNULL(tmp), SPIF_NULL_TYPE(array));
     memcpy(tmp, self, SPIF_SIZEOF_TYPE(array));
     tmp->items = SPIF_CAST_C(spif_obj_t *) MALLOC(SPIF_SIZEOF_TYPE(obj) * self->len);
     for (i = 0; i < self->len; i++) {
@@ -289,12 +336,14 @@
 static spif_classname_t
 spif_array_type(spif_array_t self)
 {
+    ASSERT_RVAL(!SPIF_ARRAY_ISNULL(self), SPIF_NULL_TYPE(classname));
     return SPIF_OBJ_CLASSNAME(self);
 }
 
 static spif_bool_t
 spif_array_append(spif_array_t self, spif_obj_t obj)
 {
+    ASSERT_RVAL(!SPIF_ARRAY_ISNULL(self), FALSE);
     self->len++;
     if (self->items) {
         self->items = SPIF_CAST_C(spif_obj_t *) REALLOC(self->items, 
SPIF_SIZEOF_TYPE(obj) * self->len);
@@ -308,18 +357,21 @@
 static spif_bool_t
 spif_array_list_contains(spif_array_t self, spif_obj_t obj)
 {
+    ASSERT_RVAL(!SPIF_ARRAY_ISNULL(self), FALSE);
     return ((SPIF_LIST_ISNULL(spif_array_list_find(self, obj))) ? (FALSE) : (TRUE));
 }
 
 static spif_bool_t
 spif_array_vector_contains(spif_array_t self, spif_obj_t obj)
 {
+    ASSERT_RVAL(!SPIF_ARRAY_ISNULL(self), FALSE);
     return ((SPIF_VECTOR_ISNULL(spif_array_vector_find(self, obj))) ? (FALSE) : 
(TRUE));
 }
 
 static spif_listidx_t
 spif_array_count(spif_array_t self)
 {
+    ASSERT_RVAL(!SPIF_ARRAY_ISNULL(self), SPIF_NULL_TYPE(listidx));
     return self->len;
 }
 
@@ -328,7 +380,12 @@
 {
     spif_listidx_t i;
 
+    ASSERT_RVAL(!SPIF_ARRAY_ISNULL(self), SPIF_NULL_TYPE(obj));
+    REQUIRE_RVAL(!SPIF_OBJ_ISNULL(obj), SPIF_NULL_TYPE(obj));
     for (i = 0; i < self->len; i++) {
+        if (SPIF_OBJ_ISNULL(self->items[i])) {
+            continue;
+        }
         if (SPIF_CMP_IS_EQUAL(SPIF_OBJ_COMP(self->items[i], obj))) {
             return self->items[i];
         }
@@ -342,9 +399,10 @@
     spif_listidx_t start, end, mid;
     spif_cmp_t diff;
 
-    if (self->len == 0) {
-        return SPIF_NULL_TYPE(obj);
-    }
+    ASSERT_RVAL(!SPIF_ARRAY_ISNULL(self), SPIF_NULL_TYPE(obj));
+    REQUIRE_RVAL(!SPIF_OBJ_ISNULL(obj), SPIF_NULL_TYPE(obj));
+    REQUIRE_RVAL(self->len > 0, SPIF_NULL_TYPE(obj));
+
     for (start = 0, end = self->len - 1; start <= end; ) {
         mid = (end - start) / 2 + start;
         diff = SPIF_OBJ_COMP(self->items[mid], obj);
@@ -354,7 +412,7 @@
             start = mid + 1;
         } else {
             end = mid - 1;
-            if (end == (spif_listidx_t) -1) {
+            if (end == SPIF_CAST(listidx) -1) {
                 break;
             }
         }
@@ -365,7 +423,11 @@
 static spif_obj_t
 spif_array_get(spif_array_t self, spif_listidx_t idx)
 {
-    return ((idx < self->len) ? (self->items[idx]) : (SPIF_NULL_TYPE(obj)));
+    ASSERT_RVAL(!SPIF_ARRAY_ISNULL(self), SPIF_NULL_TYPE(obj));
+    if (idx < 0) {
+        idx += self->len;
+    }
+    return (((idx > 0) && (idx < self->len)) ? (self->items[idx]) : 
(SPIF_NULL_TYPE(obj)));
 }
 
 static spif_listidx_t
@@ -373,12 +435,19 @@
 {
     spif_listidx_t i;
 
+    ASSERT_RVAL(!SPIF_ARRAY_ISNULL(self), SPIF_CAST(listidx) -1);
     for (i = 0; i < self->len; i++) {
+        if (SPIF_OBJ_ISNULL(self->items[i])) {
+            if (SPIF_OBJ_ISNULL(obj)) {
+                return i;
+            }
+            continue;
+        }
         if (SPIF_CMP_IS_EQUAL(SPIF_OBJ_COMP(self->items[i], obj))) {
             return i;
         }
     }
-    return SPIF_CAST_C(spif_listidx_t) (-1);
+    return SPIF_CAST(listidx) (-1);
 }
 
 static spif_bool_t
@@ -386,6 +455,8 @@
 {
     spif_listidx_t i, left;
 
+    ASSERT_RVAL(!SPIF_ARRAY_ISNULL(self), FALSE);
+    REQUIRE_RVAL(!SPIF_OBJ_ISNULL(obj), FALSE);
     if (self->items) {
         self->items = SPIF_CAST_C(spif_obj_t *) REALLOC(self->items, 
SPIF_SIZEOF_TYPE(obj) * (self->len + 1));
     } else {
@@ -407,7 +478,21 @@
 {
     spif_listidx_t left;
 
-    left = self->len - idx;
+    ASSERT_RVAL(!SPIF_ARRAY_ISNULL(self), FALSE);
+    REQUIRE_RVAL(!SPIF_OBJ_ISNULL(obj), FALSE);
+    if (idx < 0) {
+        /* Negative indexes go backward from the end of the list. */
+        idx += self->len;
+    }
+    REQUIRE_RVAL((idx + 1) >= 0, FALSE);
+
+    if (idx > self->len) {
+        /* The array is going to grow by more than 1; we'll need to pad with NULL's. 
*/
+        left = -(idx - self->len);
+        self->len = idx;
+    } else {
+        left = self->len - idx;
+    }
 
     if (self->items) {
         self->items = SPIF_CAST_C(spif_obj_t *) REALLOC(self->items, 
SPIF_SIZEOF_TYPE(obj) * (self->len + 1));
@@ -415,8 +500,13 @@
         self->items = SPIF_CAST_C(spif_obj_t *) MALLOC(SPIF_SIZEOF_TYPE(obj) * 
(self->len + 1));
     }
 
-    if (left) {
+    if (left > 0) {
+        /* Move the stuff to the right of idx over one. */
         memmove(self->items + idx + 1, self->items + idx, SPIF_SIZEOF_TYPE(obj) * 
left);
+    } else if (left < 0) {
+        /* NULL out the new gap in the list. */
+        left = -left;
+        MEMSET(self->items + (idx - left), 0, SPIF_SIZEOF_TYPE(obj) * left);
     }
     self->items[idx] = obj;
     self->len++;
@@ -426,12 +516,15 @@
 static spif_iterator_t
 spif_array_iterator(spif_array_t self)
 {
+    ASSERT_RVAL(!SPIF_ARRAY_ISNULL(self), SPIF_NULL_TYPE(iterator));
     return SPIF_CAST(iterator) spif_array_iterator_new(self);
 }
 
 static spif_bool_t
 spif_array_prepend(spif_array_t self, spif_obj_t obj)
 {
+    ASSERT_RVAL(!SPIF_ARRAY_ISNULL(self), FALSE);
+    REQUIRE_RVAL(!SPIF_OBJ_ISNULL(obj), FALSE);
     if (self->items) {
         self->items = SPIF_CAST_C(spif_obj_t *) REALLOC(self->items, 
SPIF_SIZEOF_TYPE(obj) * (self->len + 1));
     } else {
@@ -450,6 +543,8 @@
     spif_obj_t tmp;
     spif_listidx_t i, left;
 
+    ASSERT_RVAL(!SPIF_ARRAY_ISNULL(self), SPIF_NULL_TYPE(obj));
+    REQUIRE_RVAL(!SPIF_OBJ_ISNULL(item), SPIF_NULL_TYPE(obj));
     for (i = 0; i < self->len && !SPIF_CMP_IS_EQUAL(SPIF_OBJ_COMP(item, 
self->items[i])); i++);
     if (i == self->len) {
         return SPIF_NULL_TYPE(obj);
@@ -469,7 +564,12 @@
     spif_obj_t tmp;
     spif_listidx_t left;
 
-    if (idx >= self->len) {
+    ASSERT_RVAL(!SPIF_ARRAY_ISNULL(self), SPIF_NULL_TYPE(obj));
+    if (idx < 0) {
+        /* Negative indexes go backward from the end of the list. */
+        idx += self->len;
+    }
+    if ((idx < 0) || (idx >= self->len)) {
         return SPIF_NULL_TYPE(obj);
     }
 
@@ -486,6 +586,7 @@
 {
     spif_listidx_t i, j;
 
+    ASSERT_RVAL(!SPIF_ARRAY_ISNULL(self), FALSE);
     for (i = 0, j = self->len - 1; i < j; i++, j--) {
         BINSWAP(self->items[i], self->items[j]);
     }
@@ -498,9 +599,10 @@
     spif_obj_t *tmp;
     spif_listidx_t i;
 
-    tmp = SPIF_CAST_C(spif_obj_t *) MALLOC(SPIF_SIZEOF_TYPE(obj) * self->len);
+    ASSERT_RVAL(!SPIF_ARRAY_ISNULL(self), SPIF_NULL_TYPE_PTR(obj));
+    tmp = SPIF_CAST_PTR(obj) MALLOC(SPIF_SIZEOF_TYPE(obj) * self->len);
     for (i = 0; i < self->len; i++) {
-        tmp[i] = SPIF_CAST(obj) SPIF_OBJ(self->items[i]);
+        tmp[i] = SPIF_OBJ(self->items[i]);
     }
     return tmp;
 }
@@ -511,15 +613,22 @@
     spif_array_iterator_t self;
 
     self = SPIF_ALLOC(array_iterator);
-    spif_array_iterator_init(self, subject);
+    if (!spif_array_iterator_init(self, subject)) {
+        SPIF_DEALLOC(self);
+        self = SPIF_NULL_TYPE(array_iterator);
+    }
     return self;
 }
 
 static spif_bool_t
 spif_array_iterator_init(spif_array_iterator_t self, spif_array_t subject)
 {
-    spif_obj_init(SPIF_OBJ(self));
-    spif_obj_set_class(SPIF_OBJ(self), SPIF_CLASS(SPIF_ITERATORCLASS_VAR(array)));
+    ASSERT_RVAL(!SPIF_ITERATOR_ISNULL(self), FALSE);
+    if (!spif_obj_init(SPIF_OBJ(self))) {
+        return FALSE;
+    } else if (!spif_obj_set_class(SPIF_OBJ(self), 
SPIF_CLASS(SPIF_ITERATORCLASS_VAR(array)))) {
+        return FALSE;
+    }
     self->subject = subject;
     self->current_index = 0;
     return TRUE;
@@ -528,6 +637,7 @@
 static spif_bool_t
 spif_array_iterator_done(spif_array_iterator_t self)
 {
+    ASSERT_RVAL(!SPIF_ITERATOR_ISNULL(self), FALSE);
     self->subject = SPIF_NULL_TYPE(array);
     self->current_index = 0;
     return TRUE;
@@ -536,9 +646,12 @@
 static spif_bool_t
 spif_array_iterator_del(spif_array_iterator_t self)
 {
-    spif_array_iterator_done(self);
+    spif_bool_t t;
+
+    ASSERT_RVAL(!SPIF_ITERATOR_ISNULL(self), FALSE);
+    t = spif_array_iterator_done(self);
     SPIF_DEALLOC(self);
-    return TRUE;
+    return t;
 }
 
 static spif_str_t
@@ -574,7 +687,21 @@
 static spif_cmp_t
 spif_array_iterator_comp(spif_array_iterator_t self, spif_array_iterator_t other)
 {
-    return SPIF_CMP_FROM_INT((int) (self->current_index - other->current_index));
+    spif_cmp_t c;
+
+    if (SPIF_ITERATOR_ISNULL(self) && SPIF_ITERATOR_ISNULL(other)) {
+        return SPIF_CMP_EQUAL;
+    } else if (SPIF_ITERATOR_ISNULL(self)) {
+        return SPIF_CMP_LESS;
+    } else if (SPIF_ITERATOR_ISNULL(other)) {
+        return SPIF_CMP_GREATER;
+    }
+    c = spif_array_comp(self->subject, other->subject);
+    if (SPIF_CMP_IS_EQUAL(c)) {
+        return SPIF_CMP_FROM_INT((int) (self->current_index - other->current_index));
+    } else {
+        return c;
+    }
 }
 
 static spif_array_iterator_t
@@ -582,6 +709,7 @@
 {
     spif_array_iterator_t tmp;
 
+    ASSERT_RVAL(!SPIF_ITERATOR_ISNULL(self), SPIF_NULL_TYPE(array_iterator));
     tmp = spif_array_iterator_new(self->subject);
     tmp->current_index = self->current_index;
     return tmp;
@@ -590,6 +718,7 @@
 static spif_classname_t
 spif_array_iterator_type(spif_array_iterator_t self)
 {
+    ASSERT_RVAL(!SPIF_ITERATOR_ISNULL(self), SPIF_NULL_TYPE(classname));
     return SPIF_OBJ_CLASSNAME(self);
 }
 
===================================================================
RCS file: /cvsroot/enlightenment/eterm/libast/src/dlinked_list.c,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -3 -r1.15 -r1.16
--- dlinked_list.c      24 Jan 2004 19:55:23 -0000      1.15
+++ dlinked_list.c      30 Jan 2004 22:55:18 -0000      1.16
@@ -21,7 +21,7 @@
  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  */
 
-static const char cvs_ident[] = "$Id: dlinked_list.c,v 1.15 2004/01/24 19:55:23 mej 
Exp $";
+static const char cvs_ident[] = "$Id: dlinked_list.c,v 1.16 2004/01/30 22:55:18 mej 
Exp $";
 
 #ifdef HAVE_CONFIG_H
 # include <config.h>
@@ -495,9 +495,14 @@
     spif_listidx_t i;
     spif_dlinked_list_item_t current;
 
-    if (idx >= self->len) {
-        return SPIF_NULL_TYPE(obj);
-    } else if (idx > (self->len / 2)) {
+    if (idx < 0) {
+        /* Negative indexes go backward from the end of the list. */
+        idx += self->len;
+    }
+    REQUIRE_RVAL(idx >= 0, SPIF_NULL_TYPE(obj));
+    REQUIRE_RVAL(idx < self->len, SPIF_NULL_TYPE(obj));
+
+    if (idx > (self->len / 2)) {
         for (current = self->tail, i = self->len - 1; current && i > idx; i--, 
current = current->prev);
         return (current ? (current->data) : SPIF_NULL_TYPE(obj));
     } else {
@@ -553,10 +558,21 @@
     spif_listidx_t i;
     spif_dlinked_list_item_t item, current;
 
+    if (idx < 0) {
+        /* Negative indexes go backward from the end of the list. */
+        idx += self->len;
+    }
+    REQUIRE_RVAL((idx + 1) >= 0, FALSE);
+
     if (idx == 0 || SPIF_DLINKED_LIST_ITEM_ISNULL(self->head)) {
         return spif_dlinked_list_prepend(self, obj);
     } else if (idx == (self->len - 1) || SPIF_DLINKED_LIST_ITEM_ISNULL(self->tail)) {
         return spif_dlinked_list_append(self, obj);
+    } else if (idx > self->len) {
+        for (i = self->len; i < idx; i++) {
+            spif_dlinked_list_append(self, SPIF_NULL_TYPE(obj));
+        }
+        return spif_dlinked_list_append(self, obj);
     } else if (idx > (self->len / 2)) {
         for (current = self->tail, i = self->len - 1; current->prev && i > idx; i--, 
current = current->prev);
         if (i != idx) {
@@ -652,6 +668,13 @@
         return SPIF_NULL_TYPE(obj);
     }
 
+    if (idx < 0) {
+        /* Negative indexes go backward from the end of the list. */
+        idx += self->len;
+    }
+    REQUIRE_RVAL(idx >= 0, SPIF_NULL_TYPE(obj));
+    REQUIRE_RVAL(idx < self->len, SPIF_NULL_TYPE(obj));
+
     if (idx > (self->len / 2)) {
         for (current = self->tail, i = self->len - 1; current && i > idx; i--, 
current = current->prev);
     } else {
===================================================================
RCS file: /cvsroot/enlightenment/eterm/libast/src/linked_list.c,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -3 -r1.18 -r1.19
--- linked_list.c       24 Jan 2004 19:55:40 -0000      1.18
+++ linked_list.c       30 Jan 2004 22:55:19 -0000      1.19
@@ -21,7 +21,7 @@
  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  */
 
-static const char cvs_ident[] = "$Id: linked_list.c,v 1.18 2004/01/24 19:55:40 mej 
Exp $";
+static const char cvs_ident[] = "$Id: linked_list.c,v 1.19 2004/01/30 22:55:19 mej 
Exp $";
 
 #ifdef HAVE_CONFIG_H
 # include <config.h>
@@ -483,6 +483,12 @@
     spif_listidx_t i;
     spif_linked_list_item_t current;
 
+    if (idx < 0) {
+        /* Negative indexes go backward from the end of the list. */
+        idx += self->len;
+    }
+    REQUIRE_RVAL(idx >= 0, SPIF_NULL_TYPE(obj));
+    REQUIRE_RVAL(idx < self->len, SPIF_NULL_TYPE(obj));
     for (current = self->head, i = 0; current && i < idx; i++, current = 
current->next);
     return (current ? (current->data) : SPIF_NULL_TYPE(obj));
 }
@@ -527,21 +533,28 @@
     spif_listidx_t i;
     spif_linked_list_item_t item, current;
 
+    if (idx < 0) {
+        /* Negative indexes go backward from the end of the list. */
+        idx += self->len;
+    }
+    REQUIRE_RVAL((idx + 1) >= 0, FALSE);
+
     if (idx == 0 || SPIF_LINKED_LIST_ITEM_ISNULL(self->head)) {
         return spif_linked_list_prepend(self, obj);
     }
     for (current = self->head, i = 1; current->next && i < idx; i++, current = 
current->next);
-    if (i == idx) {
-        item = spif_linked_list_item_new();
-        spif_linked_list_item_set_data(item, obj);
-
-        item->next = current->next;
-        current->next = item;
+    for (; i < idx; i++, current = current->next) {
+        current->next = spif_linked_list_item_new();
         self->len++;
-        return TRUE;
-    } else {
-        return FALSE;
     }
+
+    item = spif_linked_list_item_new();
+    spif_linked_list_item_set_data(item, obj);
+
+    item->next = current->next;
+    current->next = item;
+    self->len++;
+    return TRUE;
 }
 
 static spif_iterator_t
@@ -602,6 +615,13 @@
     spif_linked_list_item_t item, current;
     spif_obj_t tmp;
 
+    if (idx < 0) {
+        /* Negative indexes go backward from the end of the list. */
+        idx += self->len;
+    }
+    REQUIRE_RVAL(idx >= 0, SPIF_NULL_TYPE(obj));
+    REQUIRE_RVAL(idx < self->len, SPIF_NULL_TYPE(obj));
+
     if (SPIF_LINKED_LIST_ITEM_ISNULL(self->head)) {
         return SPIF_NULL_TYPE(obj);
     } else if (idx == 0) {
===================================================================
RCS file: /cvsroot/enlightenment/eterm/libast/src/obj.c,v
retrieving revision 1.22
retrieving revision 1.23
diff -u -3 -r1.22 -r1.23
--- obj.c       10 Jan 2004 21:15:17 -0000      1.22
+++ obj.c       30 Jan 2004 22:55:19 -0000      1.23
@@ -28,11 +28,11 @@
  * This file contains the basic object class.
  *
  * @author Michael Jennings <[EMAIL PROTECTED]>
- * $Revision: 1.22 $
- * $Date: 2004/01/10 21:15:17 $
+ * $Revision: 1.23 $
+ * $Date: 2004/01/30 22:55:19 $
  */
 
-static const char cvs_ident[] = "$Id: obj.c,v 1.22 2004/01/10 21:15:17 mej Exp $";
+static const char cvs_ident[] = "$Id: obj.c,v 1.23 2004/01/30 22:55:19 mej Exp $";
 
 #ifdef HAVE_CONFIG_H
 # include <config.h>
@@ -119,7 +119,10 @@
     spif_obj_t self;
 
     self = SPIF_ALLOC(obj);
-    spif_obj_init(self);
+    if (!spif_obj_init(self)) {
+        SPIF_DEALLOC(self);
+        self = SPIF_NULL_TYPE(obj);
+    }
     return self;
 }
 
@@ -139,10 +142,13 @@
 spif_bool_t
 spif_obj_del(spif_obj_t self)
 {
-    D_OBJ(("Deleting object %010p\n", self));
-    spif_obj_done(self);
+    spif_bool_t t;
+
+    ASSERT_RVAL(!SPIF_OBJ_ISNULL(self), FALSE);
+
+    t = spif_obj_done(self);
     SPIF_DEALLOC(self);
-    return TRUE;
+    return t;
 }
 
 /**
@@ -170,6 +176,7 @@
 spif_bool_t
 spif_obj_init(spif_obj_t self)
 {
+    ASSERT_RVAL(!SPIF_OBJ_ISNULL(self), FALSE);
     spif_obj_set_class(self, SPIF_CLASS_VAR(obj));
     return TRUE;
 }
@@ -189,7 +196,7 @@
 spif_bool_t
 spif_obj_done(spif_obj_t self)
 {
-    USE_VAR(self);
+    ASSERT_RVAL(!SPIF_OBJ_ISNULL(self), FALSE);
     return TRUE;
 }
 
@@ -301,6 +308,7 @@
 {
     spif_obj_t tmp;
 
+    ASSERT_RVAL(!SPIF_OBJ_ISNULL(self), SPIF_NULL_TYPE(obj));
     tmp = spif_obj_new();
     memcpy(tmp, self, SPIF_SIZEOF_TYPE(obj));
     return tmp;
@@ -323,6 +331,7 @@
 spif_classname_t
 spif_obj_type(spif_obj_t self)
 {
+    ASSERT_RVAL(!SPIF_OBJ_ISNULL(self), SPIF_NULL_TYPE(classname));
     return SPIF_OBJ_CLASSNAME(self);
 }
 
@@ -349,7 +358,8 @@
 spif_class_t
 spif_obj_get_class(spif_obj_t self)
 {
-    return ((self) ? SPIF_OBJ_CLASS(self) : SPIF_NULL_TYPE(class));
+    ASSERT_RVAL(!SPIF_OBJ_ISNULL(self), SPIF_NULL_TYPE(class));
+    return SPIF_OBJ_CLASS(self);
 }
 
 /**
@@ -376,9 +386,7 @@
 spif_bool_t
 spif_obj_set_class(spif_obj_t self, spif_class_t cls)
 {
-    if (SPIF_OBJ_ISNULL(self)) {
-        return FALSE;
-    }
+    ASSERT_RVAL(!SPIF_OBJ_ISNULL(self), FALSE);
     SPIF_OBJ_CLASS(self) = cls;
     return TRUE;
 }
===================================================================
RCS file: /cvsroot/enlightenment/eterm/libast/src/objpair.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -3 -r1.1 -r1.2
--- objpair.c   24 Jan 2004 19:56:23 -0000      1.1
+++ objpair.c   30 Jan 2004 22:55:19 -0000      1.2
@@ -28,11 +28,11 @@
  * This file contains the objpair class.
  *
  * @author Michael Jennings <[EMAIL PROTECTED]>
- * $Revision: 1.1 $
- * $Date: 2004/01/24 19:56:23 $
+ * $Revision: 1.2 $
+ * $Date: 2004/01/30 22:55:19 $
  */
 
-static const char cvs_ident[] = "$Id: objpair.c,v 1.1 2004/01/24 19:56:23 mej Exp $";
+static const char cvs_ident[] = "$Id: objpair.c,v 1.2 2004/01/30 22:55:19 mej Exp $";
 
 #ifdef HAVE_CONFIG_H
 # include <config.h>
@@ -124,6 +124,71 @@
 }
 
 /**
+ * Create a new @c objpair instance with a left object.
+ *
+ * This function creates and returns a new instance of an @c objpair
+ * with a given left object.
+ *
+ * @param left The left object for the pair.
+ * @return     A new @c objpair instance whose left object is @a left.
+ *
+ * @see @link DOXGRP_OBJPAIR Paired Objects @endlink
+ */
+spif_objpair_t
+spif_objpair_new_from_left(spif_obj_t left)
+{
+    spif_objpair_t self;
+
+    self = SPIF_ALLOC(objpair);
+    spif_objpair_init_from_left(self, left);
+    return self;
+}
+
+/**
+ * Create a new @c objpair instance with a right object.
+ *
+ * This function creates and returns a new instance of an @c objpair
+ * with a given right object.
+ *
+ * @param right The right object for the pair.
+ * @return      A new @c objpair instance whose right object is @a right.
+ *
+ * @see @link DOXGRP_OBJPAIR Paired Objects @endlink
+ */
+spif_objpair_t
+spif_objpair_new_from_right(spif_obj_t right)
+{
+    spif_objpair_t self;
+
+    self = SPIF_ALLOC(objpair);
+    spif_objpair_init_from_right(self, right);
+    return self;
+}
+
+/**
+ * Create a new @c objpair instance with both left and right objects.
+ *
+ * This function creates and returns a new instance of an @c objpair
+ * with given left and right objects.
+ *
+ * @param left  The left object for the pair.
+ * @param right The right object for the pair.
+ * @return      A new @c objpair instance whose left and right objects
+ *              are @a left and @a right, respectively.
+ *
+ * @see @link DOXGRP_OBJPAIR Paired Objects @endlink
+ */
+spif_objpair_t
+spif_objpair_new_from_both(spif_obj_t left, spif_obj_t right)
+{
+    spif_objpair_t self;
+
+    self = SPIF_ALLOC(objpair);
+    spif_objpair_init_from_both(self, left, right);
+    return self;
+}
+
+/**
  * Delete an @c objpair instance.
  *
  * This function deletes an instance of an @c objpair.  The done method,
@@ -164,6 +229,84 @@
 }
 
 /**
+ * Initialize an @c objpair instance with a given left object.
+ *
+ * This function initializes the member variables of the @c objpair
+ * instance to their appropriate "bootstrap" values, assigning @a left
+ * to the left property of @a self.
+ *
+ * @param self The @c objpair instance to be initialized.
+ * @param left The left object for the pair.
+ * @return     #TRUE if successful, #FALSE otherwise.
+ *
+ * @see @link DOXGRP_OBJPAIR Paired Objects @endlink
+ * @ingroup DOXGRP_OBJPAIR
+ */
+spif_bool_t
+spif_objpair_init_from_left(spif_objpair_t self, spif_obj_t left)
+{
+    ASSERT_RVAL(!SPIF_OBJPAIR_ISNULL(self), FALSE);
+    ASSERT_RVAL(!SPIF_OBJ_ISNULL(left), FALSE);
+    spif_obj_set_class(SPIF_OBJ(self), SPIF_CLASS_VAR(objpair));
+    self->left = SPIF_OBJ_DUP(SPIF_OBJ(left));
+    self->right = SPIF_NULL_TYPE(obj);
+    return TRUE;
+}
+
+/**
+ * Initialize an @c objpair instance with a given right object.
+ *
+ * This function initializes the member variables of the @c objpair
+ * instance to their appropriate "bootstrap" values, assigning @a right
+ * to the right property of @a self.
+ *
+ * @param self  The @c objpair instance to be initialized.
+ * @param right The right object for the pair.
+ * @return      #TRUE if successful, #FALSE otherwise.
+ *
+ * @see @link DOXGRP_OBJPAIR Paired Objects @endlink
+ * @ingroup DOXGRP_OBJPAIR
+ */
+spif_bool_t
+spif_objpair_init_from_right(spif_objpair_t self, spif_obj_t right)
+{
+    ASSERT_RVAL(!SPIF_OBJPAIR_ISNULL(self), FALSE);
+    ASSERT_RVAL(!SPIF_OBJ_ISNULL(right), FALSE);
+    spif_obj_set_class(SPIF_OBJ(self), SPIF_CLASS_VAR(objpair));
+    self->left = SPIF_NULL_TYPE(obj);
+    self->right = SPIF_OBJ_DUP(SPIF_OBJ(right));
+    return TRUE;
+}
+
+/**
+ * Initialize an @c objpair instance with both left and right
+ * objects.
+ *
+ * This function initializes the member variables of the @c objpair
+ * instance to their appropriate "bootstrap" values, assigning @a left
+ * to the left property of @self and @a right to the right property.
+ *
+ * @param self  The @c objpair instance to be initialized.
+ * @param left  The left object for the pair.
+ * @param right The right object for the pair.
+ * @return      #TRUE if successful, #FALSE otherwise.
+ *
+ * @see @link DOXGRP_OBJPAIR Paired Objects @endlink
+ * @ingroup DOXGRP_OBJPAIR
+ */
+spif_bool_t
+spif_objpair_init_from_both(spif_objpair_t self, spif_obj_t left, spif_obj_t right)
+{
+    ASSERT_RVAL(!SPIF_OBJPAIR_ISNULL(self), FALSE);
+    ASSERT_RVAL(!SPIF_OBJ_ISNULL(left), FALSE);
+    ASSERT_RVAL(!SPIF_OBJ_ISNULL(right), FALSE);
+    spif_obj_set_class(SPIF_OBJ(self), SPIF_CLASS_VAR(objpair));
+    self->left = SPIF_OBJ_DUP(SPIF_OBJ(left));
+    self->right = SPIF_OBJ_DUP(SPIF_OBJ(right));
+    return TRUE;
+}
+
+/**
  * Deallocate and reinitialize @c objpair resources.
  *
  * This function frees up any object resources and re-initializes them
@@ -178,7 +321,16 @@
 spif_bool_t
 spif_objpair_done(spif_objpair_t self)
 {
-    USE_VAR(self);
+    ASSERT_RVAL(!SPIF_OBJPAIR_ISNULL(self), FALSE);
+    if (!SPIF_OBJ_ISNULL(SPIF_OBJ(self->left))) {
+        SPIF_OBJ_DEL(SPIF_OBJ(self->left));
+    }
+    self->left = SPIF_NULL_TYPE(obj);
+    if (!SPIF_OBJ_ISNULL(SPIF_OBJ(self->right))) {
+        SPIF_OBJ_DEL(SPIF_OBJ(self->right));
+    }
+    self->right = SPIF_NULL_TYPE(obj);
+
     return TRUE;
 }
 
@@ -234,7 +386,13 @@
 spif_cmp_t
 spif_objpair_comp(spif_objpair_t self, spif_objpair_t other)
 {
-    return (self == other);
+    spif_cmp_t c;
+
+    c = SPIF_OBJ_COMP(self->left, other->left);
+    if (SPIF_CMP_IS_EQUAL(c)) {
+        c = SPIF_OBJ_COMP(self->right, other->right);
+    }
+    return c;
 }
 
 /**
@@ -253,11 +411,7 @@
 spif_objpair_t
 spif_objpair_dup(spif_objpair_t self)
 {
-    spif_objpair_t tmp;
-
-    tmp = spif_objpair_new();
-    memcpy(tmp, self, SPIF_SIZEOF_TYPE(objpair));
-    return tmp;
+    return spif_objpair_new_from_both(self->left, self->right);
 }
 
 /**
@@ -275,7 +429,7 @@
 spif_classname_t
 spif_objpair_type(spif_objpair_t self)
 {
-    return SPIF_OBJ_CLASSNAME(self);
+    return SPIF_OBJ_CLASSNAME(SPIF_OBJ(self));
 }
 
 SPIF_DEFINE_PROPERTY_FUNC(objpair, obj, left);
===================================================================
RCS file: /cvsroot/enlightenment/eterm/libast/src/tok.c,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -3 -r1.18 -r1.19
--- tok.c       10 Jan 2004 21:15:17 -0000      1.18
+++ tok.c       30 Jan 2004 22:55:19 -0000      1.19
@@ -21,7 +21,7 @@
  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  */
 
-static const char cvs_ident[] = "$Id: tok.c,v 1.18 2004/01/10 21:15:17 mej Exp $";
+static const char cvs_ident[] = "$Id: tok.c,v 1.19 2004/01/30 22:55:19 mej Exp $";
 
 #ifdef HAVE_CONFIG_H
 # include <config.h>
@@ -50,7 +50,10 @@
     spif_tok_t self;
 
     self = SPIF_ALLOC(tok);
-    spif_tok_init(self);
+    if (!spif_tok_init(self)) {
+        SPIF_DEALLOC(self);
+        self = SPIF_NULL_TYPE(tok);
+    }
     return self;
 }
 
@@ -60,7 +63,10 @@
     spif_tok_t self;
 
     self = SPIF_ALLOC(tok);
-    spif_tok_init_from_ptr(self, old);
+    if (!spif_tok_init_from_ptr(self, old)) {
+        SPIF_DEALLOC(self);
+        self = SPIF_NULL_TYPE(tok);
+    }
     return self;
 }
 
@@ -70,7 +76,10 @@
     spif_tok_t self;
 
     self = SPIF_ALLOC(tok);
-    spif_tok_init_from_fp(self, fp);
+    if (!spif_tok_init_from_fp(self, fp)) {
+        SPIF_DEALLOC(self);
+        self = SPIF_NULL_TYPE(tok);
+    }
     return self;
 }
 
@@ -80,23 +89,33 @@
     spif_tok_t self;
 
     self = SPIF_ALLOC(tok);
-    spif_tok_init_from_fd(self, fd);
+    if (!spif_tok_init_from_fd(self, fd)) {
+        SPIF_DEALLOC(self);
+        self = SPIF_NULL_TYPE(tok);
+    }
     return self;
 }
 
 spif_bool_t
 spif_tok_del(spif_tok_t self)
 {
-    spif_tok_done(self);
+    spif_bool_t t;
+
+    ASSERT_RVAL(!SPIF_TOK_ISNULL(self), FALSE);
+    t = spif_tok_done(self);
     SPIF_DEALLOC(self);
-    return TRUE;
+    return t;
 }
 
 spif_bool_t
 spif_tok_init(spif_tok_t self)
 {
-    spif_obj_init(SPIF_OBJ(self));
-    spif_obj_set_class(SPIF_OBJ(self), SPIF_CLASS_VAR(tok));
+    ASSERT_RVAL(!SPIF_TOK_ISNULL(self), FALSE);
+    if (!spif_obj_init(SPIF_OBJ(self))) {
+        return FALSE;
+    } else if (!spif_obj_set_class(SPIF_OBJ(self), SPIF_CLASS_VAR(tok))) {
+        return FALSE;
+    }
     self->src = SPIF_NULL_TYPE(str);
     self->quote = '\'';
     self->dquote = '\"';
@@ -109,48 +128,61 @@
 spif_bool_t
 spif_tok_init_from_ptr(spif_tok_t self, spif_charptr_t old)
 {
-    spif_obj_init(SPIF_OBJ(self));
-    spif_obj_set_class(SPIF_OBJ(self), SPIF_CLASS_VAR(tok));
+    ASSERT_RVAL(!SPIF_TOK_ISNULL(self), FALSE);
+    if (!spif_obj_init(SPIF_OBJ(self))) {
+        return FALSE;
+    } else if (!spif_obj_set_class(SPIF_OBJ(self), SPIF_CLASS_VAR(tok))) {
+        return FALSE;
+    }
     self->src = spif_str_new_from_ptr(old);
     self->quote = '\'';
     self->dquote = '\"';
     self->escape = '\\';
     self->tokens = SPIF_NULL_TYPE(list);
     self->sep = SPIF_NULL_TYPE(str);
-    return TRUE;
+    return ((SPIF_STR_ISNULL(self->src)) ? (FALSE) : (TRUE));
 }
 
 spif_bool_t
 spif_tok_init_from_fp(spif_tok_t self, FILE * fp)
 {
-    spif_obj_init(SPIF_OBJ(self));
-    spif_obj_set_class(SPIF_OBJ(self), SPIF_CLASS_VAR(tok));
+    ASSERT_RVAL(!SPIF_TOK_ISNULL(self), FALSE);
+    if (!spif_obj_init(SPIF_OBJ(self))) {
+        return FALSE;
+    } else if (!spif_obj_set_class(SPIF_OBJ(self), SPIF_CLASS_VAR(tok))) {
+        return FALSE;
+    }
     self->src = spif_str_new_from_fp(fp);
     self->quote = '\'';
     self->dquote = '\"';
     self->escape = '\\';
     self->tokens = SPIF_NULL_TYPE(list);
     self->sep = SPIF_NULL_TYPE(str);
-    return TRUE;
+    return ((SPIF_STR_ISNULL(self->src)) ? (FALSE) : (TRUE));
 }
 
 spif_bool_t
 spif_tok_init_from_fd(spif_tok_t self, int fd)
 {
-    spif_obj_init(SPIF_OBJ(self));
-    spif_obj_set_class(SPIF_OBJ(self), SPIF_CLASS_VAR(tok));
+    ASSERT_RVAL(!SPIF_TOK_ISNULL(self), FALSE);
+    if (!spif_obj_init(SPIF_OBJ(self))) {
+        return FALSE;
+    } else if (!spif_obj_set_class(SPIF_OBJ(self), SPIF_CLASS_VAR(tok))) {
+        return FALSE;
+    }
     self->src = spif_str_new_from_fd(fd);
     self->quote = '\'';
     self->dquote = '\"';
     self->escape = '\\';
     self->tokens = SPIF_NULL_TYPE(list);
     self->sep = SPIF_NULL_TYPE(str);
-    return TRUE;
+    return ((SPIF_STR_ISNULL(self->src)) ? (FALSE) : (TRUE));
 }
 
 spif_bool_t
 spif_tok_done(spif_tok_t self)
 {
+    ASSERT_RVAL(!SPIF_TOK_ISNULL(self), FALSE);
     if (!SPIF_LIST_ISNULL(self->tokens)) {
         SPIF_LIST_DEL(self->tokens);
         self->tokens = SPIF_NULL_TYPE(list);
@@ -169,80 +201,6 @@
     return TRUE;
 }
 
-#define IS_DELIM(c)  ((delim != NULL) ? (strchr(delim, (c)) != NULL) : (isspace(c)))
-#define IS_QUOTE(c)  (quote && quote == (c))
-
-spif_bool_t
-spif_tok_eval(spif_tok_t self)
-{
-    const char *pstr, *delim = NULL;
-    spif_str_t tmp;
-    char quote;
-    size_t len;
-
-    if (SPIF_STR_ISNULL(self->src)) {
-        return FALSE;
-    }
-    pstr = SPIF_CAST_C(const char *) SPIF_STR_STR(SPIF_STR(self->src));
-    len = spif_str_get_len(SPIF_STR(self->src));
-
-    if (!SPIF_STR_ISNULL(self->sep)) {
-        delim = SPIF_CAST_C(const char *) SPIF_STR_STR(SPIF_STR(self->sep));
-    }
-
-    if (!SPIF_LIST_ISNULL(self->tokens)) {
-        SPIF_LIST_DEL(self->tokens);
-    }
-    self->tokens = SPIF_LIST_NEW(dlinked_list);
-
-    /* Before we do anything, skip leading "whitespace." */
-    for (; *pstr && IS_DELIM(*pstr); pstr++);
-
-    /* The outermost for loop is where we traverse the string.  Each new
-       word brings us back to the top where we resize our string list. */
-    for (quote = 0; *pstr; ) {
-        tmp = spif_str_new_from_buff("", len);
-        spif_str_clear(tmp, 0);
-
-        /* This for loop is where we process each character. */
-        for (; *pstr && (quote || !IS_DELIM(*pstr));) {
-            if (*pstr == self->dquote || *pstr == self->quote) {
-                /* It's a quote character, so set or reset the quote variable. */
-                if (quote) {
-                    if (quote == *pstr) {
-                        quote = 0;
-                    } else {
-                        /* It's a single quote inside double quotes, or vice versa.  
Leave it alone. */
-                        spif_str_append_char(tmp, *pstr);
-                    }
-                } else {
-                    quote = *pstr;
-                }
-                pstr++;
-            } else {
-                /* Handle any backslashes that are escaping delimiters or quotes. */
-                if ((*pstr == self->escape) && (IS_DELIM(*(pstr + 1)) || 
IS_QUOTE(*(pstr + 1)))) {
-                    /* Incrementing pstr here moves us past the backslash so that the 
line
-                       below will copy the next character to the new token, no 
questions asked. */
-                    pstr++;
-                }
-                spif_str_append_char(tmp, *pstr++);
-            }
-        }
-
-        /* Reallocate the new string to be just the right size. */
-        spif_str_trim(tmp);
-        len -= spif_str_get_len(tmp);
-
-        /* Add it to the list */
-        SPIF_LIST_APPEND(self->tokens, tmp);
-
-        /* Move past any trailing "whitespace." */
-        for (; *pstr && IS_DELIM(*pstr); pstr++);
-    }
-    return TRUE;
-}
-
 spif_str_t
 spif_tok_show(spif_tok_t self, spif_charptr_t name, spif_str_t buff, size_t indent)
 {
@@ -286,7 +244,14 @@
 spif_cmp_t
 spif_tok_comp(spif_tok_t self, spif_tok_t other)
 {
-    return spif_str_cmp(SPIF_STR(self), SPIF_STR(other));
+    if (SPIF_TOK_ISNULL(self) && SPIF_TOK_ISNULL(other)) {
+        return SPIF_CMP_EQUAL;
+    } else if (SPIF_TOK_ISNULL(self)) {
+        return SPIF_CMP_LESS;
+    } else if (SPIF_TOK_ISNULL(other)) {
+        return SPIF_CMP_GREATER;
+    }
+    return spif_str_cmp(self->src, other->src);
 }
 
 spif_tok_t
@@ -294,6 +259,7 @@
 {
     spif_tok_t tmp;
 
+    ASSERT_RVAL(!SPIF_TOK_ISNULL(self), SPIF_NULL_TYPE(tok));
     tmp = spif_tok_new();
     tmp->src = spif_str_dup(SPIF_STR(self->src));
     tmp->quote = self->quote;
@@ -308,108 +274,87 @@
 spif_classname_t
 spif_tok_type(spif_tok_t self)
 {
+    ASSERT_RVAL(!SPIF_TOK_ISNULL(self), SPIF_NULL_TYPE(classname));
     return SPIF_OBJ_CLASSNAME(self);
 }
 
-spif_str_t
-spif_tok_get_src(spif_tok_t self)
-{
-    return ((SPIF_OBJ_IS_TOK(self)) ? (SPIF_STR(self->src)) : (SPIF_NULL_TYPE(str)));
-}
+#define IS_DELIM(c)  ((delim != NULL) ? (strchr(delim, (c)) != NULL) : (isspace(c)))
+#define IS_QUOTE(c)  (quote && quote == (c))
 
 spif_bool_t
-spif_tok_set_src(spif_tok_t self, spif_str_t new_src)
-{
-    if (SPIF_OBJ_IS_TOK(self) && SPIF_OBJ_IS_STR(new_src)) {
-        if (!SPIF_STR_ISNULL(self->src)) {
-            spif_str_done(self->src);
-        }
-        self->src = spif_str_dup(new_src);
-        return TRUE;
-    } else {
-        return FALSE;
-    }
-}
-
-spif_char_t
-spif_tok_get_quote(spif_tok_t self)
+spif_tok_eval(spif_tok_t self)
 {
-    return ((SPIF_OBJ_IS_TOK(self)) ? (SPIF_CAST(char) self->quote) : 
(SPIF_CAST(char) 0));
-}
+    const char *pstr, *delim = NULL;
+    spif_str_t tmp;
+    char quote;
+    size_t len;
 
-spif_bool_t
-spif_tok_set_quote(spif_tok_t self, spif_char_t c)
-{
-    if (SPIF_OBJ_IS_TOK(self)) {
-        self->quote = c;
-        return TRUE;
-    } else {
-        return FALSE;
-    }
-}
+    ASSERT_RVAL(!SPIF_TOK_ISNULL(self), FALSE);
+    REQUIRE_RVAL(!SPIF_STR_ISNULL(self->src), FALSE);
 
-spif_char_t
-spif_tok_get_dquote(spif_tok_t self)
-{
-    return ((SPIF_OBJ_IS_TOK(self)) ? (SPIF_CAST(char) self->dquote) : 
(SPIF_CAST(char) 0));
-}
+    pstr = SPIF_CAST_C(const char *) SPIF_STR_STR(SPIF_STR(self->src));
+    len = spif_str_get_len(SPIF_STR(self->src));
 
-spif_bool_t
-spif_tok_set_dquote(spif_tok_t self, spif_char_t c)
-{
-    if (SPIF_OBJ_IS_TOK(self)) {
-        self->dquote = c;
-        return TRUE;
-    } else {
-        return FALSE;
+    if (!SPIF_STR_ISNULL(self->sep)) {
+        delim = SPIF_CAST_C(const char *) SPIF_STR_STR(SPIF_STR(self->sep));
     }
-}
-
-spif_char_t
-spif_tok_get_escape(spif_tok_t self)
-{
-    return ((SPIF_OBJ_IS_TOK(self)) ? (SPIF_CAST(char) self->escape) : 
(SPIF_CAST(char) 0));
-}
 
-spif_bool_t
-spif_tok_set_escape(spif_tok_t self, spif_char_t c)
-{
-    if (SPIF_OBJ_IS_TOK(self)) {
-        self->escape = c;
-        return TRUE;
-    } else {
-        return FALSE;
+    if (!SPIF_LIST_ISNULL(self->tokens)) {
+        SPIF_LIST_DEL(self->tokens);
     }
-}
+    self->tokens = SPIF_LIST_NEW(dlinked_list);
 
-spif_str_t
-spif_tok_get_sep(spif_tok_t self)
-{
-    return ((SPIF_OBJ_IS_TOK(self)) ? (SPIF_STR(self->sep)) : (SPIF_NULL_TYPE(str)));
-}
+    /* Before we do anything, skip leading "whitespace." */
+    for (; *pstr && IS_DELIM(*pstr); pstr++);
 
-spif_bool_t
-spif_tok_set_sep(spif_tok_t self, spif_str_t new_sep)
-{
-    if (SPIF_OBJ_IS_TOK(self) && SPIF_OBJ_IS_STR(new_sep)) {
-        if (!SPIF_STR_ISNULL(self->sep)) {
-            spif_str_done(self->sep);
+    /* The outermost for loop is where we traverse the string.  Each new
+       word brings us back to the top where we resize our string list. */
+    for (quote = 0; *pstr; ) {
+        tmp = spif_str_new_from_buff("", len);
+        spif_str_clear(tmp, 0);
+
+        /* This for loop is where we process each character. */
+        for (; *pstr && (quote || !IS_DELIM(*pstr));) {
+            if (*pstr == self->dquote || *pstr == self->quote) {
+                /* It's a quote character, so set or reset the quote variable. */
+                if (quote) {
+                    if (quote == *pstr) {
+                        quote = 0;
+                    } else {
+                        /* It's a single quote inside double quotes, or vice versa.  
Leave it alone. */
+                        spif_str_append_char(tmp, *pstr);
+                    }
+                } else {
+                    quote = *pstr;
+                }
+                pstr++;
+            } else {
+                /* Handle any backslashes that are escaping delimiters or quotes. */
+                if ((*pstr == self->escape) && (IS_DELIM(*(pstr + 1)) || 
IS_QUOTE(*(pstr + 1)))) {
+                    /* Incrementing pstr here moves us past the backslash so that the 
line
+                       below will copy the next character to the new token, no 
questions asked. */
+                    pstr++;
+                }
+                spif_str_append_char(tmp, *pstr++);
+            }
         }
-        self->sep = spif_str_dup(new_sep);
-        return TRUE;
-    } else {
-        return FALSE;
-    }
-}
 
-spif_list_t
-spif_tok_get_tokens(spif_tok_t self)
-{
-    if (!SPIF_OBJ_IS_TOK(self)) {
-        return SPIF_NULL_TYPE(list);
-    }
-    if (SPIF_LIST_ISNULL(self->tokens)) {
-        spif_tok_eval(self);
+        /* Reallocate the new string to be just the right size. */
+        spif_str_trim(tmp);
+        len -= spif_str_get_len(tmp);
+
+        /* Add it to the list */
+        SPIF_LIST_APPEND(self->tokens, tmp);
+
+        /* Move past any trailing "whitespace." */
+        for (; *pstr && IS_DELIM(*pstr); pstr++);
     }
-    return self->tokens;
+    return TRUE;
 }
+
+SPIF_DEFINE_PROPERTY_FUNC(tok, str, src);
+SPIF_DEFINE_PROPERTY_FUNC_NONOBJ(tok, char, quote);
+SPIF_DEFINE_PROPERTY_FUNC_NONOBJ(tok, char, dquote);
+SPIF_DEFINE_PROPERTY_FUNC_NONOBJ(tok, char, escape);
+SPIF_DEFINE_PROPERTY_FUNC(tok, str, sep);
+SPIF_DEFINE_PROPERTY_FUNC(tok, list, tokens);




-------------------------------------------------------
The SF.Net email is sponsored by EclipseCon 2004
Premiere Conference on Open Tools Development and Integration
See the breadth of Eclipse activity. February 3-5 in Anaheim, CA.
http://www.eclipsecon.org/osdn
_______________________________________________
enlightenment-cvs mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/enlightenment-cvs

Reply via email to