Index: ossp-pkg/lmtp2nntp/lmtp2nntp_config.c RCS File: /v/ossp/cvs/ossp-pkg/lmtp2nntp/lmtp2nntp_config.c,v rcsdiff -q -kk '-r1.5' '-r1.6' -u '/v/ossp/cvs/ossp-pkg/lmtp2nntp/lmtp2nntp_config.c,v' 2>/dev/null --- lmtp2nntp_config.c 2002/01/15 13:04:09 1.5 +++ lmtp2nntp_config.c 2002/01/16 09:46:52 1.6 @@ -98,10 +98,53 @@ void die(char *); //FIXME void die(char *msg) { - printf("ERROR: %s", msg); + printf("ERROR: %s\n", msg); exit(-1); } +static val_rc_t dumper(void *ctx, const char *name, int type, const char *desc, void *data) +{ + switch (type) { + case VAL_TYPE_VAL: + fprintf(stderr, "DEBUG: <%10s> VAL_TYPE_VAL, desc=<%20s>, data@%.8lx INTERNAL\n", + (char *)ctx, desc, (long)data); + break; + case VAL_TYPE_PTR: + fprintf(stderr, "DEBUG: <%10s> VAL_TYPE_PTR, desc=<%20s>, data@%.8lx=%.8lx\n", + (char *)ctx, desc, (long)data, *(long *)data); + break; + case VAL_TYPE_CHAR: + fprintf(stderr, "DEBUG: <%10s> VAL_TYPE_CHAR, desc=<%20s>, data@%.8lx='%c'\n", + (char *)ctx, desc, (long)data, *(char *)data); + break; + case VAL_TYPE_SHORT: + fprintf(stderr, "DEBUG: <%10s> VAL_TYPE_SHORT, desc=<%20s>, data@%.8lx=%8d\n", + (char *)ctx, desc, (long)data, *(short *)data); + break; + case VAL_TYPE_INT: + fprintf(stderr, "DEBUG: <%10s> VAL_TYPE_INT, desc=<%20s>, data@%.8lx=%8d\n", + (char *)ctx, desc, (long)data, *(int *)data); + break; + case VAL_TYPE_LONG: + fprintf(stderr, "DEBUG: <%10s> VAL_TYPE_LONG, desc=<%20s>, data@%.8lx=%8d\n", + (char *)ctx, desc, (long)data, *(long *)data); + break; + case VAL_TYPE_FLOAT: + fprintf(stderr, "DEBUG: <%10s> VAL_TYPE_FLOAT, desc=<%20s>, data@%.8lx=%8f\n", + (char *)ctx, desc, (long)data, *(float *)data); + break; + case VAL_TYPE_DOUBLE: + fprintf(stderr, "DEBUG: <%10s> VAL_TYPE_DOUBLE, desc=<%20s>, data@%.8lx=%8f\n", + (char *)ctx, desc, (long)data, *(double *)data); + break; + default: + fprintf(stderr, "DEBUG: <%10s> type = %.8lx, desc=<%20s>, data@%.8lx\n", + (char *)ctx, type, desc, (long)data); + } + + return VAL_OK; +} + void dotconftest(int argc, char **argv) /*FIXME*/ { popt_context poptCon; /* context for parsing command-line options */ @@ -140,28 +183,95 @@ { int testint = 10; int testintout = 100; + int testint2 = 20; + int testintout2 = 200; val_rc_t rc; - val_t *v; + val_t *v, *v2, *v3; if ((rc = val_create(&v)) != VAL_OK) die("val_create"); printf("DEBUG: testint = %d, testintout = %d\n", testint, testintout); - if ((rc = val_reg(v, "foo.bar", VAL_TYPE_INT, (void *)&testint)) != VAL_OK) + if ((rc = val_reg(v, "foo", VAL_TYPE_INT, "foo variable", (void *)&testint)) != VAL_OK) die("val_reg"); testint++; - if ((rc = val_get(v, "foo.bar", &testintout)) != VAL_OK) + if ((rc = val_get(v, "foo", &testintout)) != VAL_OK) die("val_get"); printf("DEBUG: testint = %d, testintout = %d\n", testint, testintout); - if ((rc = val_set(v, "foo.bar", 2)) != VAL_OK) + if ((rc = val_set(v, "foo", 2)) != VAL_OK) die("val_set"); - if ((rc = val_get(v, "foo.bar", &testintout)) != VAL_OK) + if ((rc = val_get(v, "foo", &testintout)) != VAL_OK) die("val_get"); printf("DEBUG: testint = %d, testintout = %d\n", testint, testintout); + if ((rc = val_create(&v2)) != VAL_OK) + die("val_create 2"); + +#if 0 + if ((rc = val_reg(v, "bar", VAL_TYPE_VAL, "bar variable", (void *)&v2)) != VAL_OK) + die("val_reg 2"); +#endif + val_reg(v, "bar", VAL_TYPE_VAL, "bar variable", NULL); + val_set(v, "bar", v2); + if ((rc = val_get(v, "bar", &v3)) != VAL_OK) + die("val_get v3"); + + if ((rc = val_reg(v2, "quux", VAL_TYPE_INT, "quux variable", (void *)&testint2)) != VAL_OK) + die("val_reg 2b"); + + testint2++; + if ((rc = val_get(v2, "quux", &testintout2)) != VAL_OK) + die("val_get 2c"); + printf("DEBUG: testint2 = %d, testintout2 = %d\n", testint2, testintout2); + if ((rc = val_get(v, "bar.quux", &testintout2)) != VAL_OK) { + fprintf(stderr, "rc=%d\n", rc); + die("val_get 2d"); + } + printf("DEBUG: testint2 = %d, testintout2 = %d\n", testint2, testintout2); + + printf("DEBUG: testint at address %lx\n", (long)&testint); + printf("DEBUG: testintout at address %lx\n", (long)&testintout); + printf("DEBUG: testint2 at address %lx\n", (long)&testint2); + printf("DEBUG: testint2out at address %lx\n", (long)&testintout2); + + if ((rc = val_reg(v, "bar.ptr", VAL_TYPE_PTR, "bar ptr (&testint)", NULL)) != VAL_OK) + die("val_ret for bar.ptr using inline data"); + if ((rc = val_set(v, "bar.ptr", &testint)) != VAL_OK) + die("val_set for bar.ptr using inline data"); + if ((rc = val_reg(v, "bar.char", VAL_TYPE_CHAR, "bar character (!)", NULL)) != VAL_OK) + die("val_ret for bar.char using inline data"); + if ((rc = val_set(v, "bar.char", '!')) != VAL_OK) + die("val_set for bar.char using inline data"); + if ((rc = val_reg(v, "bar.short", VAL_TYPE_SHORT, "bar short (555)", NULL)) != VAL_OK) + die("val_ret for bar.short using inline data"); + if ((rc = val_set(v, "bar.short", 555)) != VAL_OK) + die("val_set for bar.short using inline data"); + if ((rc = val_reg(v, "bar.int", VAL_TYPE_INT, "bar integer (76543)", NULL)) != VAL_OK) + die("val_ret for bar.int using inline data"); + if ((rc = val_set(v, "bar.int", 76543)) != VAL_OK) + die("val_set for bar.int using inline data"); + if ((rc = val_reg(v, "bar.long", VAL_TYPE_LONG, "bar long (2097152)", NULL)) != VAL_OK) + die("val_ret for bar.long using inline data"); + if ((rc = val_set(v, "bar.long", 2097152)) != VAL_OK) + die("val_set for bar.long using inline data"); + if ((rc = val_reg(v, "bar.float", VAL_TYPE_FLOAT, "bar float (1.955830)", NULL)) != VAL_OK) + die("val_ret for bar.float using inline data"); + if ((rc = val_set(v, "bar.float", 1.95583)) != VAL_OK) + die("val_set for bar.float using inline data"); + if ((rc = val_reg(v, "bar.double", VAL_TYPE_DOUBLE, "bar double (3.1415+)", NULL)) != VAL_OK) + die("val_ret for bar.double using inline data"); + if ((rc = val_set(v, "bar.double", 3.14159265358979)) != VAL_OK) + die("val_set for bar.double using inline data"); + + val_apply(v, dumper, "v" ); + val_apply(v2, dumper, "v2"); + + if ((rc = val_destroy(v2)) != VAL_OK) + die("val_destroy 2"); + if ((rc = val_destroy(v)) != VAL_OK) die("val_destroy"); Index: ossp-pkg/lmtp2nntp/lmtp2nntp_lh.c RCS File: /v/ossp/cvs/ossp-pkg/lmtp2nntp/Attic/lmtp2nntp_lh.c,v rcsdiff -q -kk '-r1.2' '-r1.3' -u '/v/ossp/cvs/ossp-pkg/lmtp2nntp/Attic/lmtp2nntp_lh.c,v' 2>/dev/null --- lmtp2nntp_lh.c 2002/01/15 11:57:31 1.2 +++ lmtp2nntp_lh.c 2002/01/16 09:46:52 1.3 @@ -87,13 +87,6 @@ #include #include -#ifndef FALSE -#define FALSE 0 -#endif -#ifndef TRUE -#define TRUE !FALSE -#endif - #include "lmtp2nntp_lh.h" /* fixed size (number of pointers) of the directory and of each segment */ @@ -513,6 +506,35 @@ return rv; } +/* apply a callback for all elements in the hash table */ +int lh_apply(lh_t *h, lh_cb_t cb, void *ctx) +{ + element_t *el, **pel; + unsigned int i, j; + + /* argument consistency check */ + if (h == NULL || cb == NULL) + return FALSE; + + /* interate over all segment's entries */ + for (i = 0; i < h->h_dirsize; i++) { + if (h->h_dir[i] == NULL) + continue; + /* interate over all collision chains */ + for (j = 0; j < SEGMENTSIZE; j++) { + if (h->h_dir[i]->s_element[j] == NULL) + continue; + /* interate over all elements in collision chain */ + el = h->h_dir[i]->s_element[j]; + for (; el != NULL; el = el->e_next) { + if (!cb(ctx, el->e_keyptr, el_keylen(el), el->e_datptr, el_datlen(el))) + return; + } + } + } + return TRUE; +} + /* destroy the whole hash table */ int lh_destroy(lh_t *h) { Index: ossp-pkg/lmtp2nntp/lmtp2nntp_lh.h RCS File: /v/ossp/cvs/ossp-pkg/lmtp2nntp/Attic/lmtp2nntp_lh.h,v rcsdiff -q -kk '-r1.2' '-r1.3' -u '/v/ossp/cvs/ossp-pkg/lmtp2nntp/Attic/lmtp2nntp_lh.h,v' 2>/dev/null --- lmtp2nntp_lh.h 2002/01/15 11:57:31 1.2 +++ lmtp2nntp_lh.h 2002/01/16 09:46:52 1.3 @@ -27,13 +27,23 @@ #ifndef __LH_H__ #define __LH_H__ +#ifndef FALSE +#define FALSE 0 +#endif +#ifndef TRUE +#define TRUE !FALSE +#endif + struct lh_st; typedef struct lh_st lh_t; +typedef int (*lh_cb_t)(void *ctx, const void *keyptr, int keylen, const void *datptr, int datlen); + 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 /* __LH_H__ */ Index: ossp-pkg/lmtp2nntp/lmtp2nntp_val.c RCS File: /v/ossp/cvs/ossp-pkg/lmtp2nntp/Attic/lmtp2nntp_val.c,v rcsdiff -q -kk '-r1.1' '-r1.2' -u '/v/ossp/cvs/ossp-pkg/lmtp2nntp/Attic/lmtp2nntp_val.c,v' 2>/dev/null --- lmtp2nntp_val.c 2002/01/15 13:02:20 1.1 +++ lmtp2nntp_val.c 2002/01/16 09:46:52 1.2 @@ -4,7 +4,7 @@ #include #include #include - +#include /* 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] @@ -14,9 +14,9 @@ }; typedef struct { - char *name; int type; union { + val_t *v; void *p; char c; short s; @@ -25,41 +25,49 @@ float f; double d; } data; + char *desc; } val_object_t; struct val_s { lh_t *lh; }; -static void *val_unionptr(val_object_t *obj) +static void *val_storage(val_object_t *obj) { void *storage; - switch (obj->type & ~VAL_INLINE) { - case VAL_TYPE_PTR: - storage = &obj->data.p; - break; - case VAL_TYPE_CHAR: - storage = (void *)&obj->data.c; - break; - case VAL_TYPE_SHORT: - storage = (void *)&obj->data.s; - break; - case VAL_TYPE_INT: - storage = (void *)&obj->data.i; - break; - case VAL_TYPE_LONG: - storage = (void *)&obj->data.l; - break; - case VAL_TYPE_FLOAT: - storage = (void *)&obj->data.f; - break; - case VAL_TYPE_DOUBLE: - storage = (void *)&obj->data.d; - break; - default: - storage = NULL; + 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; + } } + else + storage = obj->data.p; return storage; } @@ -67,40 +75,77 @@ { val_t *val; + if (valp == NULL) + return VAL_ERR_ARG; if ((val = (val_t *)malloc(sizeof(val_t))) == NULL) - return VAL_MEMORY; - if ((val->lh = lh_create()) == NULL) - return VAL_LH; + return VAL_ERR_SYS; + if ((val->lh = lh_create()) == NULL) { + free(val); + return VAL_ERR_SYS; + } *valp = val; return VAL_OK; } +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); + return TRUE; +} + val_rc_t val_destroy(val_t *val) { if (val == NULL) - return VAL_MEMORY; - lh_destroy(val->lh); + return VAL_ERR_ARG; + lh_apply(val->lh, val_destroy_cb, NULL); + if (!lh_destroy(val->lh)) + return VAL_ERR_SYS; free(val); return VAL_OK; } -val_rc_t val_reg(val_t *val, const char *name, int type, void *storage) +val_rc_t val_reg(val_t *val, const char *name, int type, const char *desc, void *storage) { - val_object_t obj; + val_object_t *obj; + val_object_t newobj; + const char *cp; + val_t *child; + + if (val == NULL || name == NULL || type == 0) + return VAL_ERR_ARG; + + - if ((obj.name = strdup(name)) == NULL) - return VAL_MEMORY; - obj.type = type; - if (storage == NULL) { - obj.type |= VAL_INLINE; - obj.data.l = 0; + if ((cp = strchr(name, '.')) != NULL) { + if (!lh_lookup(val->lh, name, cp-name, (void **)&obj, NULL)) + return VAL_ERR_ARG; + if (!(obj->type & VAL_TYPE_VAL)) + return VAL_ERR_USE; + child = *(val_t **)(val_storage(obj)); + return val_reg(child, cp+1, type, desc, storage); } + + + + if (desc != NULL) + newobj.desc = strdup(desc); else - obj.data.p = storage; + newobj.desc = NULL; + if (storage == NULL) { + newobj.type = (type | VAL_INLINE); + newobj.data.l = 0; + } + else { + newobj.type = (type & ~VAL_INLINE); + newobj.data.p = storage; + } + if (!lh_insert(val->lh, name, strlen(name), &newobj, sizeof(newobj), 1)) + return VAL_ERR_SYS; - if (! lh_insert(val->lh, name, strlen(name), &obj, sizeof(obj), 1)) - return VAL_LH; - return VAL_OK; } @@ -109,19 +154,25 @@ val_object_t *obj; void *storage; const char *cp; + val_t *child; + if (val == NULL || name == NULL || ap == NULL) + return VAL_ERR_ARG; if ((cp = strchr(name, '.')) != NULL) { - if (! lh_lookup(val->lh, name, cp-name, (void **)&obj, NULL)) - return VAL_LH; - return val_vset((val_t *)obj->data.p, cp+1, ap); - } - if (! lh_lookup(val->lh, name, strlen(name), (void **)&obj, NULL)) - return VAL_LH; - if (obj->type & VAL_INLINE) - storage = val_unionptr(obj); - else - storage = obj->data.p; - switch(obj->type & ~VAL_INLINE) { + if (!lh_lookup(val->lh, name, cp-name, (void **)&obj, NULL)) + return VAL_ERR_ARG; + if (!(obj->type & VAL_TYPE_VAL)) + return VAL_ERR_USE; + child = *(val_t **)(val_storage(obj)); + return val_vset(child, cp+1, ap); + } + if (!lh_lookup(val->lh, name, strlen(name), (void **)&obj, NULL)) + return VAL_ERR_ARG; + storage = val_storage(obj); + 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; @@ -152,6 +203,8 @@ val_rc_t rc; va_list ap; + if (val == NULL || name == NULL) + return VAL_ERR_ARG; va_start(ap, name); rc = val_vset(val, name, ap); va_end(ap); @@ -163,19 +216,25 @@ val_object_t *obj; void *storage; const char *cp; + val_t *child; + if (val == NULL || name == NULL || ap == NULL) + return VAL_ERR_ARG; if ((cp = strchr(name, '.')) != NULL) { - if (! lh_lookup(val->lh, name, cp-name, (void **)&obj, NULL)) - return VAL_LH; - return val_vget((val_t *)obj->data.p, cp+1, ap); - } - if (! lh_lookup(val->lh, name, strlen(name), (void **)&obj, NULL)) - return VAL_LH; - if (obj->type & VAL_INLINE) - storage = val_unionptr(obj); - else - storage = obj->data.p; + if (!lh_lookup(val->lh, name, cp-name, (void **)&obj, NULL)) + return VAL_ERR_ARG; + if (!(obj->type & VAL_TYPE_VAL)) + return VAL_ERR_USE; + child = *(val_t **)(val_storage(obj)); + return val_vget(child, cp+1, ap); + } + if (!lh_lookup(val->lh, name, strlen(name), (void **)&obj, NULL)) + return VAL_ERR_ARG; + storage = val_storage(obj); 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; @@ -206,9 +265,61 @@ val_rc_t rc; va_list ap; + if (val == NULL || name == NULL) + return VAL_ERR_ARG; va_start(ap, name); rc = val_vget(val, name, ap); va_end(ap); return rc; } +#define VAL_MAXNAME 1024 + +typedef struct { + val_cb_t cb; + void *ctx; + val_rc_t rc; +} val_apply_ctx_t; + +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; + val_object_t *obj; + char name[VAL_MAXNAME+1]; + + /* on-the-fly create NUL-terminated name string */ + if (keylen > VAL_MAXNAME) { + ctx->rc = VAL_ERR_MEM; + return FALSE; + } + strncpy(name, (char *)keyptr, keylen); + *((char *)name+keylen) = '\0'; + + /* take object */ + if (datlen != sizeof(val_object_t)) { + ctx->rc = VAL_ERR_ARG; + return FALSE; + } + obj = (val_object_t *)datptr; + + /* execute VAL callback */ + if ((ctx->rc = ctx->cb(ctx->ctx, name, (obj->type & ~VAL_INLINE), obj->desc, val_storage(obj))) != VAL_OK) + return FALSE; + + return TRUE; +} + +val_rc_t val_apply(val_t *val, val_cb_t cb, void *ctx) +{ + val_apply_ctx_t val_ctx; + + if (val == NULL || cb == NULL) + return VAL_ERR_ARG; + val_ctx.cb = cb; + val_ctx.ctx = ctx; + val_ctx.rc = VAL_OK; + if (!lh_apply(val->lh, val_apply_cb, &val_ctx)) + return VAL_ERR_SYS; + return val_ctx.rc; +} + Index: ossp-pkg/lmtp2nntp/lmtp2nntp_val.h RCS File: /v/ossp/cvs/ossp-pkg/lmtp2nntp/Attic/lmtp2nntp_val.h,v rcsdiff -q -kk '-r1.1' '-r1.2' -u '/v/ossp/cvs/ossp-pkg/lmtp2nntp/Attic/lmtp2nntp_val.h,v' 2>/dev/null --- lmtp2nntp_val.h 2002/01/15 13:02:20 1.1 +++ lmtp2nntp_val.h 2002/01/16 09:46:52 1.2 @@ -1,31 +1,41 @@ +#ifndef __LMTP2NNTP_VAL_H__ +#define __LMTP2NNTP_VAL_H__ + #include enum { - VAL_TYPE_PTR = 1<<0, - VAL_TYPE_CHAR = 1<<1, - VAL_TYPE_SHORT = 1<<2, - VAL_TYPE_INT = 1<<3, - VAL_TYPE_LONG = 1<<4, - VAL_TYPE_FLOAT = 1<<5, - VAL_TYPE_DOUBLE = 1<<6 + VAL_TYPE_VAL = 1<<0, + VAL_TYPE_PTR = 1<<1, + VAL_TYPE_CHAR = 1<<2, + VAL_TYPE_SHORT = 1<<3, + VAL_TYPE_INT = 1<<4, + VAL_TYPE_LONG = 1<<5, + VAL_TYPE_FLOAT = 1<<6, + VAL_TYPE_DOUBLE = 1<<7 }; typedef enum { VAL_OK, - VAL_MEMORY, - VAL_LH, - VAL_UNKNOWN + VAL_ERR_ARG, + VAL_ERR_USE, + VAL_ERR_MEM, + VAL_ERR_SYS } val_rc_t; struct val_s; typedef struct val_s val_t; +typedef val_rc_t (*val_cb_t)(void *, const char *, int, const char *, void *); + val_rc_t val_create (val_t **); val_rc_t val_destroy (val_t *); -val_rc_t val_reg (val_t *, const char *, int, void *); +val_rc_t val_reg (val_t *, const char *, int, const char *, void *); val_rc_t val_set (val_t *, const char *, ...); val_rc_t val_get (val_t *, const char *, ...); val_rc_t val_vset (val_t *, const char *, va_list); val_rc_t val_vget (val_t *, const char *, va_list); +val_rc_t val_apply (val_t *, val_cb_t cb, void *ctx); + +#endif /* __LMTP2NNTP_VAL_H__ */