OSSP CVS Repository

ossp - Difference in ossp-pkg/val/val.c versions 1.3 and 1.4
Not logged in
[Honeypot]  [Browse]  [Home]  [Login]  [Reports
[Search]  [Ticket]  [Timeline
  [History

ossp-pkg/val/val.c 1.3 -> 1.4

--- val.c        2002/01/16 16:10:34     1.3
+++ val.c        2002/01/16 20:24:09     1.4
@@ -67,15 +67,6 @@
 
 typedef int (*lh_cb_t)(void *ctx, const void *keyptr, int keylen, const void *datptr, int datlen);
 
-#if 0
-lh_t *lh_create (void);
-int   lh_insert (lh_t *h, const void *keyptr, int keylen, const void  *datptr, int  datlen, int override);
-int   lh_lookup (lh_t *h, const void *keyptr, int keylen,       void **datptr, int *datlen);
-int   lh_delete (lh_t *h, const void *keyptr, int keylen);
-int   lh_apply  (lh_t *h, lh_cb_t cb, void *ctx);
-int   lh_destroy(lh_t *h);
-#endif
-
 /* fixed size (number of pointers) of the directory and of each segment */
 #define INITDIRSIZE  256 /* can be an arbitrary value */
 #define SEGMENTSIZE  512 /* has to be a power of 2 for below arithmetic */
@@ -128,7 +119,7 @@
  * version doesn't provide the `level' (= previous hash) argument for
  * consistency reasons with the other hash functions (i.e. same function
  * signature). It can be definetely recommended as a good general
- * purpuse hash function.
+ * purpose hash function.
  */
 static long 
 lh_hash(
@@ -564,15 +555,21 @@
 **  ____               ____
 **  ____ VALUE LIBRARY ____
 **
+**  This part implements the actual Value library. Fortunately this
+**  is now easy because it internally is just based on the above
+**  full-featured linear hashing library.
 */
 
-/* usually val_object_t.data is a pointer val_object_t.data.p, but VAL_INLINE
- * signals val_object_t.data is actual data val_object_t.data.[csilfd]
+/* 
+ * usually val_object_t.data is a pointer val_object_t.data.p,
+ * but VAL_INLINE signals val_object_t.data is actual data
+ * val_object_t.data.[csilfd].
  */
 enum {
-    VAL_INLINE      = 1<<31
+    VAL_INLINE = 1<<31
 };
 
+/* the internal representation of a value object */
 typedef struct {
     int type;
     union {
@@ -588,86 +585,101 @@
     char *desc;
 } val_object_t;
 
+/* the val_t internally is just a hash table */
 struct val_s {
     lh_t *lh;
 };
 
+/* determine address of an object's storage */
 static void *val_storage(val_object_t *obj)
 {
     void *storage;
 
+    /* argument consistency check */
+    if (obj == NULL)
+        return NULL;
+
+    /* address determination */
     if (obj->type & VAL_INLINE) {
         switch (obj->type & ~VAL_INLINE) {
-            case VAL_TYPE_VAL:
-                storage = &obj->data.v;
-                break;
-            case VAL_TYPE_PTR:
-                storage = &obj->data.p;
-                break;
-            case VAL_TYPE_CHAR:
-                storage = &obj->data.c;
-                break;
-            case VAL_TYPE_SHORT:
-                storage = &obj->data.s;
-                break;
-            case VAL_TYPE_INT:
-                storage = &obj->data.i;
-                break;
-            case VAL_TYPE_LONG:
-                storage = &obj->data.l;
-                break;
-            case VAL_TYPE_FLOAT:
-                storage = &obj->data.f;
-                break;
-            case VAL_TYPE_DOUBLE:
-                storage = &obj->data.d;
-                break;
-            default:
-                storage = NULL;
+            case VAL_TYPE_VAL:    storage = &obj->data.v; break;
+            case VAL_TYPE_PTR:    storage = &obj->data.p; break;
+            case VAL_TYPE_CHAR:   storage = &obj->data.c; break;
+            case VAL_TYPE_SHORT:  storage = &obj->data.s; break;
+            case VAL_TYPE_INT:    storage = &obj->data.i; break;
+            case VAL_TYPE_LONG:   storage = &obj->data.l; break;
+            case VAL_TYPE_FLOAT:  storage = &obj->data.f; break;
+            case VAL_TYPE_DOUBLE: storage = &obj->data.d; break;
+            default:              storage = NULL; break; /* cannot happen */
         }
     }
     else 
         storage = obj->data.p;
+
     return storage;
 }
 
-val_rc_t val_create(val_t **valp)
+/* create object */
+val_rc_t val_create(val_t **pval)
 {
     val_t *val;
 
-    if (valp == NULL)
+    /* argument consistency check */
+    if (pval == NULL)
         return VAL_ERR_ARG;
+
+    /* create top-level structure */
     if ((val = (val_t *)malloc(sizeof(val_t))) == NULL)
         return VAL_ERR_SYS;
+
+    /* create hash table */
     if ((val->lh = lh_create()) == NULL) {
         free(val);
         return VAL_ERR_SYS;
     }
-    *valp = val;
+
+    /* pass result to caller */
+    *pval = val;
+
     return VAL_OK;
 }
 
-static int (val_destroy_cb)(void *_ctx, const void *keyptr, int keylen, const void *datptr, int datlen)
+/* internal lh_apply() callback for use with val_destroy() */
+static int val_destroy_cb(void *_ctx, 
+                          const void *keyptr, int keylen, 
+                          const void *datptr, int datlen)
 {
     val_object_t *obj;
     
-    obj = (val_object_t *)datptr;
-    if (obj->desc != NULL)
-        free(obj->desc);
+    /* free description string */
+    if ((obj = (val_object_t *)datptr) != NULL)
+        if (obj->desc != NULL)
+            free(obj->desc);
+
     return TRUE;
 }
 
+/* destroy object */
 val_rc_t val_destroy(val_t *val)
 {
+    /* argument consistency check */
     if (val == NULL)
         return VAL_ERR_ARG;
+
+    /* destroy all hash table elements */
     lh_apply(val->lh, val_destroy_cb, NULL);
+
+    /* destroy hash table */
     if (!lh_destroy(val->lh))
         return VAL_ERR_SYS;
+
+    /* destroy top-level structure */
     free(val);
+
     return VAL_OK;
 }
 
+/* register a value */
 val_rc_t val_reg(val_t *val, const char *name, int type, const char *desc, void *storage)
 {
     val_object_t *obj;
@@ -675,11 +687,11 @@
     const char *cp;
     val_t *child;
 
+    /* argument consistency check */
     if (val == NULL || name == NULL || type == 0)
         return VAL_ERR_ARG;
 
-
-
+    /* recursive step-down on structured name */
     if ((cp = strchr(name, '.')) != NULL) {
         if (!lh_lookup(val->lh, name, cp-name, (void **)&obj, NULL))
             return VAL_ERR_ARG;
@@ -689,8 +701,7 @@
         return val_reg(child, cp+1, type, desc, storage);
     }
 
-
-
+    /* create a new value object */
     if (desc != NULL)
         newobj.desc = strdup(desc);
     else
@@ -703,12 +714,15 @@
         newobj.type   = (type & ~VAL_INLINE);
         newobj.data.p = storage;
     }
+
+    /* insert value into hash table */
     if (!lh_insert(val->lh, name, strlen(name), &newobj, sizeof(newobj), 1))
-        return VAL_ERR_SYS;
+        return VAL_ERR_HSH;
 
     return VAL_OK;
 }
 
+/* set a value (va_list variant) */
 val_rc_t val_vset(val_t *val, const char *name, va_list ap)
 {
     val_object_t *obj;
@@ -716,8 +730,11 @@
     const char *cp;
     val_t *child;
 
+    /* argument consistency check */
     if (val == NULL || name == NULL || ap == NULL)
         return VAL_ERR_ARG;
+
+    /* recursive step-down on structured name */
     if ((cp = strchr(name, '.')) != NULL) {
         if (!lh_lookup(val->lh, name, cp-name, (void **)&obj, NULL))
             return VAL_ERR_ARG;
@@ -726,51 +743,50 @@
         child = *(val_t **)(val_storage(obj));
         return val_vset(child, cp+1, ap);
     }
+
+    /* try to lookup object in hash table */
     if (!lh_lookup(val->lh, name, strlen(name), (void **)&obj, NULL))
         return VAL_ERR_ARG;
-    storage = val_storage(obj);
+
+    /* determine value storage */
+    if ((storage = val_storage(obj)) == NULL)
+        return VAL_ERR_INT;
+
+    /* copy value from variable argument into storage location */
     switch (obj->type & ~VAL_INLINE) {
-        case VAL_TYPE_VAL:
-            *(val_t **)storage = (val_t *)va_arg(ap, void *);
-            break;
-        case VAL_TYPE_PTR:
-            *(char **)storage = (char *)va_arg(ap, void *);
-            break;
-        case VAL_TYPE_CHAR:
-            *(char *)storage = (char)va_arg(ap, int);
-            break;
-        case VAL_TYPE_SHORT:
-            *(short *)storage = (short)va_arg(ap, int);
-            break;
-        case VAL_TYPE_INT:
-            *(int *)storage = (int)va_arg(ap, int);
-            break;
-        case VAL_TYPE_LONG:
-            *(long *)storage = (long)va_arg(ap, long);
-            break;
-        case VAL_TYPE_FLOAT:
-            *(float *)storage = (float)va_arg(ap, double);
-            break;
-        case VAL_TYPE_DOUBLE:
-            *(double *)storage = (double)va_arg(ap, double);
-            break;
+        case VAL_TYPE_VAL:    *(val_t **)storage = (val_t *)va_arg(ap, void *); break;
+        case VAL_TYPE_PTR:    *(char  **)storage = (char  *)va_arg(ap, void *); break;
+        case VAL_TYPE_CHAR:   *(char   *)storage = (char   )va_arg(ap, int   ); break;
+        case VAL_TYPE_SHORT:  *(short  *)storage = (short  )va_arg(ap, int   ); break;
+        case VAL_TYPE_INT:    *(int    *)storage = (int    )va_arg(ap, int   ); break;
+        case VAL_TYPE_LONG:   *(long   *)storage = (long   )va_arg(ap, long  ); break;
+        case VAL_TYPE_FLOAT:  *(float  *)storage = (float  )va_arg(ap, double); break;
+        case VAL_TYPE_DOUBLE: *(double *)storage = (double )va_arg(ap, double); break;
+        default: break; /* cannot happen */
     }
+
     return VAL_OK;
 }
 
+/* set a value */
 val_rc_t val_set(val_t *val, const char *name, ...)
 {
     val_rc_t rc;
     va_list ap;
 
+    /* argument consistency check */
     if (val == NULL || name == NULL)
         return VAL_ERR_ARG;
+
+    /* just pass-through to va_list variant */
     va_start(ap, name);
     rc = val_vset(val, name, ap);
     va_end(ap);
+
     return rc;
 }
 
+/* get a value (va_list variant) */
 val_rc_t val_vget(val_t *val, const char *name, va_list ap)
 {
     val_object_t *obj;
@@ -778,8 +794,11 @@
     const char *cp;
     val_t *child;
 
+    /* argument consistency check */
     if (val == NULL || name == NULL || ap == NULL)
         return VAL_ERR_ARG;
+    
+    /* recursive step-down on structured name */
     if ((cp = strchr(name, '.')) != NULL) {
         if (!lh_lookup(val->lh, name, cp-name, (void **)&obj, NULL))
             return VAL_ERR_ARG;
@@ -788,72 +807,71 @@
         child = *(val_t **)(val_storage(obj));
         return val_vget(child, cp+1, ap);
     }
+
+    /* try to lookup object in hash table */
     if (!lh_lookup(val->lh, name, strlen(name), (void **)&obj, NULL))
         return VAL_ERR_ARG;
-    storage = val_storage(obj);
+
+    /* determine value storage */
+    if ((storage = val_storage(obj)) == NULL)
+        return VAL_ERR_INT;
+
+    /* copy value from storage location into variable argument pointer location */
     switch (obj->type & ~VAL_INLINE) {
-        case VAL_TYPE_VAL:
-            *((val_t **)va_arg(ap, void *)) = *(val_t **)storage;
-            break;
-        case VAL_TYPE_PTR:
-            *((char **)va_arg(ap, void *)) = *(char **)storage;
-            break;
-        case VAL_TYPE_CHAR:
-            *((char *)va_arg(ap, int *)) = *(char *)storage;
-            break;
-        case VAL_TYPE_SHORT:
-            *((short *)va_arg(ap, int *)) = *(short *)storage;
-            break;
-        case VAL_TYPE_INT:
-            *((int *)va_arg(ap, int *)) = *(int *)storage;
-            break;
-        case VAL_TYPE_LONG:
-            *((long *)va_arg(ap, long *)) = *(long *)storage;
-            break;
-        case VAL_TYPE_FLOAT:
-            *((float *)va_arg(ap, double *)) = *(float *)storage;
-            break;
-        case VAL_TYPE_DOUBLE:
-            *((double *)va_arg(ap, double *)) = *(double *)storage;
-            break;
+        case VAL_TYPE_VAL:    *((val_t **)va_arg(ap, void   *)) = *(val_t **)storage; break;
+        case VAL_TYPE_PTR:    *((char  **)va_arg(ap, void   *)) = *(char  **)storage; break;
+        case VAL_TYPE_CHAR:   *((char   *)va_arg(ap, int    *)) = *(char   *)storage; break;
+        case VAL_TYPE_SHORT:  *((short  *)va_arg(ap, int    *)) = *(short  *)storage; break;
+        case VAL_TYPE_INT:    *((int    *)va_arg(ap, int    *)) = *(int    *)storage; break;
+        case VAL_TYPE_LONG:   *((long   *)va_arg(ap, long   *)) = *(long   *)storage; break;
+        case VAL_TYPE_FLOAT:  *((float  *)va_arg(ap, double *)) = *(float  *)storage; break;
+        case VAL_TYPE_DOUBLE: *((double *)va_arg(ap, double *)) = *(double *)storage; break;
+        default: break; /* cannot happen */
     }
+
     return VAL_OK;
 }
 
+/* get a value */
 val_rc_t val_get(val_t *val, const char *name, ...)
 {
     val_rc_t rc;
     va_list ap;
 
+    /* argument consistency check */
     if (val == NULL || name == NULL)
         return VAL_ERR_ARG;
+    
+    /* just pass-through to va_list variant */
     va_start(ap, name);
     rc = val_vget(val, name, ap);
     va_end(ap);
+
     return rc;
 }
 
-#define VAL_MAXNAME 1024
-
+/* internal lh_apply() recursion callback context structure */
 typedef struct {
-    val_t *val;
-    char *name;
-    int prefixlen;
-    int depth;
-    val_cb_t cb;
-    void *ctx;
-    val_rc_t rc;
+    val_t    *val;
+    char     *name;
+    int       prefixlen;
+    int       depth;
+    val_cb_t  cb;
+    void     *ctx;
+    val_rc_t  rc;
 } val_apply_ctx_t;
 
+/* forward declaration */
 static val_rc_t val_apply_internal(val_t *, const char *, int, int, val_cb_t, void *);
 
+/* internal lh_apply() recursion callback for use with val_apply() */
 static int (val_apply_cb)(void *_ctx, const void *keyptr, int keylen, const void *datptr, int datlen)
 {
     val_apply_ctx_t *ctx = (val_apply_ctx_t *)_ctx;
     char name[VAL_MAXNAME+1];
     int prefixlen;
 
-    /* on-the-fly create NUL-terminated name string */
+    /* on-the-fly create NUL-terminated concatenated name string */
     if ((strlen(ctx->name) + 1 + keylen) > VAL_MAXNAME) {
         ctx->rc = VAL_ERR_MEM;
         return FALSE;
@@ -868,12 +886,18 @@
         prefixlen = ctx->prefixlen;
     }
     strncat(name, (char *)keyptr, keylen);
-    if ((ctx->rc = val_apply_internal(ctx->val, name, prefixlen, ctx->depth, ctx->cb, ctx->ctx)) != VAL_OK)
+
+    /* recursive step-down */
+    if ((ctx->rc = val_apply_internal(ctx->val, name, prefixlen, 
+                                      ctx->depth, ctx->cb, ctx->ctx)) != VAL_OK)
         return FALSE;
+
     return TRUE;
 }
 
-static val_rc_t val_apply_internal(val_t *val, const char *name, int prefixlen, int depth, val_cb_t cb, void *ctx)
+/* internal API-increased variant of val_apply() */
+static val_rc_t val_apply_internal(val_t *val, const char *name, int prefixlen, 
+                                   int depth, val_cb_t cb, void *ctx)
 {
     val_object_t *obj;
     val_t *child;
@@ -882,7 +906,8 @@
     val_apply_ctx_t val_ctx;
 
     if (name[prefixlen] == '\0') {
-        /* prefix="foo.bar.", remainder="" */
+        /* CASE 1: apply to all elements 
+           prefix="foo.bar.", remainder="" */
         val_ctx.val       = val;
         val_ctx.name      = (char *)name;
         val_ctx.prefixlen = prefixlen;
@@ -893,41 +918,43 @@
         if (!lh_apply(val->lh, val_apply_cb, &val_ctx))
             return VAL_ERR_SYS;
     }
-    else {
-        if ((cp = strchr(name+prefixlen, '.')) != NULL) {
-            /* prefix="foo.bar.", remainder="quux.baz" */
-            if (!lh_lookup(val->lh, name+prefixlen, cp-(name+prefixlen), (void **)&obj, NULL))
-                return VAL_ERR_ARG;
-            if (!(obj->type & VAL_TYPE_VAL))
-                return VAL_ERR_USE;
-            child = *(val_t **)(val_storage(obj));
+    else if ((cp = strchr(name+prefixlen, '.')) != NULL) {
+        /* CASE 2: still stepping-down for structured name
+           prefix="foo.bar.", remainder="quux.baz" */
+        if (!lh_lookup(val->lh, name+prefixlen, cp-(name+prefixlen), (void **)&obj, NULL))
+            return VAL_ERR_ARG;
+        if (!(obj->type & VAL_TYPE_VAL))
+            return VAL_ERR_USE;
+        child = *(val_t **)(val_storage(obj));
+        if (depth == 0)
+            return VAL_OK;
+        return val_apply_internal(child, name, cp-name+1, depth-1, cb, ctx);
+    } else {
+        /* CASE 3: reached last component of structured name
+           prefix="foo.bar.quux.", remainder="baz" */
+        if (!lh_lookup(val->lh, name+prefixlen, strlen(name+prefixlen), (void **)&obj, NULL))
+            return VAL_ERR_ARG;
+        if ((rc = cb(ctx, name, (obj->type & ~VAL_INLINE), 
+                     obj->desc, val_storage(obj))) != VAL_OK)
+            return rc;
+        if (obj->type & VAL_TYPE_VAL) {
             if (depth == 0)
                 return VAL_OK;
-            return val_apply_internal(child, name, cp-name+1, --depth, cb, ctx);
-        }
-        else {
-            /* prefix="foo.bar.quux.", remainder="baz" */
-            if (!lh_lookup(val->lh, name+prefixlen, strlen(name+prefixlen), (void **)&obj, NULL))
-                return VAL_ERR_ARG;
-            /* execute VAL callback */
-            if ((rc = cb(ctx, name, (obj->type & ~VAL_INLINE), obj->desc, val_storage(obj))) != VAL_OK)
-                return rc;
-            if (obj->type & VAL_TYPE_VAL) {
-                if (depth == 0)
-                    return VAL_OK;
-                child = *(val_t **)(val_storage(obj));
-                return val_apply_internal(child, name, strlen(name), --depth, cb, ctx);
-            }
+            child = *(val_t **)(val_storage(obj));
+            return val_apply_internal(child, name, strlen(name), depth-1, cb, ctx);
         }
     }
     return VAL_OK;
 }
 
+/* apply a callback to each value */
 val_rc_t val_apply(val_t *val, const char *name, int depth, val_cb_t cb, void *ctx)
 {
+    /* argument consistency check */
     if (val == NULL || name == NULL || depth < 0 || cb == NULL)
         return VAL_ERR_ARG;
 
+    /* just pass-through to internal API-extended variant */
     return val_apply_internal(val, name, 0, depth, cb, ctx);
 }
 

CVSTrac 2.0.1