From: ian Date: Sat, 11 Feb 2006 20:05:20 +0000 (+0000) Subject: ro compiles X-Git-Tag: debian/1.1.1~67 X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ian/git?p=chiark-tcl.git;a=commitdiff_plain;h=602f89cabd45c343f6adb4b788d26d316f5be47b;hp=9eb8c5c8a5caa7264d7d3464cf650baffb42a05c ro compiles --- diff --git a/cdb/cdb.tct b/cdb/cdb.tct index 4df47f3..a7d22b4 100644 --- a/cdb/cdb.tct +++ b/cdb/cdb.tct @@ -13,11 +13,13 @@ Table cdb Cdb_SubCommand lookup db iddata(&cdbtcl_databases) key obj + ?def obj => obj lookup-hb db iddata(&cdbtcl_databases) key hb - => hb + ?def obj + => obj close db iddata(&cdbtcl_databases) diff --git a/cdb/chiark_tcl_cdb.h b/cdb/chiark_tcl_cdb.h index 63259a8..d06713d 100644 --- a/cdb/chiark_tcl_cdb.h +++ b/cdb/chiark_tcl_cdb.h @@ -23,17 +23,23 @@ extern const IdDataSpec cdbtcl_databases, cdbtcl_rwdatabases; /*---------- from lookup.c ----------*/ -int cht_cdb_dosomelookup(Tcl_Interp *ip, void *db_v, - const char *key, Tcl_Obj *def, - Tcl_Obj **result, - int (*somelookup)(Tcl_Interp *ip, void *db_v, - const char *key, - const Byte **data_r, int *len_r), - int (*storeanswer)(Tcl_Interp *ip, Tcl_Obj **result, - const Byte *data, int len)); +int cht_cdb_donesomelookup(Tcl_Interp *ip, void *db_v, + Tcl_Obj *def, Tcl_Obj **result, + const Byte *data, int dlen, + int (*storeanswer)(Tcl_Interp *ip, Tcl_Obj **result, + const Byte *data, int len)); int cht_cdb_storeanswer_string(Tcl_Interp *ip, Tcl_Obj **result, const Byte *data, int len); int cht_cdb_storeanswer_hb(Tcl_Interp *ip, Tcl_Obj **result, const Byte *data, int len); +int cht_cdb_lookup_cdb(Tcl_Interp *ip, struct cdb *cdb, + const Byte *key, int klen, + const Byte **data_r, int *dlen_r); + +/*---------- macros ----------*/ + +#define PE(m) do{ \ + rc= cht_posixerr(ip, errno, "failed to " m); goto x_rc; \ + }while(0) #endif /*CHIARK_TCL_CDB_H*/ diff --git a/cdb/lookup.c b/cdb/lookup.c index 52598ef..4902295 100644 --- a/cdb/lookup.c +++ b/cdb/lookup.c @@ -2,20 +2,12 @@ #include "chiark_tcl_cdb.h" -int cht_cdb_dosomelookup(Tcl_Interp *ip, void *db_v, - const char *key, Tcl_Obj *def, - Tcl_Obj **result, - int (*somelookup)(Tcl_Interp *ip, void *db_v, - const char *key, - const Byte **data_r, int *len_r), - int (*storeanswer)(Tcl_Interp *ip, Tcl_Obj **result, - const Byte *data, int len)) { - int r, len; - const Byte *data; - - r= somelookup(ip, db_v, key, &data, &len); - if (r) return r; - if (len>0) return storeanswer(ip, result, data, len); +int cht_cdb_donesomelookup(Tcl_Interp *ip, void *db_v, + Tcl_Obj *def, Tcl_Obj **result, + const Byte *data, int dlen, + int (*storeanswer)(Tcl_Interp *ip, Tcl_Obj **result, + const Byte *data, int len)) { + if (dlen>0) return storeanswer(ip, result, data, dlen); if (def) { *result= def; return TCL_OK; } return cht_staticerr(ip, "cdbwr lookup key not found", "CDB NOTFOUND"); } @@ -35,3 +27,19 @@ int cht_cdb_storeanswer_hb(Tcl_Interp *ip, Tcl_Obj **result, *result= cht_ret_hb(ip, val); return TCL_OK; } + +int cht_cdb_lookup_cdb(Tcl_Interp *ip, struct cdb *cdb, + const Byte *key, int klen, + const Byte **data_r, int *len_r) { + int r; + + r= cdb_find(cdb, key, klen); + if (!r) { *data_r= 0; *len_r= -1; return TCL_OK; } + if (r<0) return cht_posixerr(ip, errno, "cdb_find failed"); + assert(r==1); + *len_r= cdb_datalen(cdb); + assert(*len_r > 0); + *data_r= cdb_getdata(cdb); + if (!*data_r) return cht_posixerr(ip, errno, "cdb_getdata failed"); + return TCL_OK; +} diff --git a/cdb/readonly.c b/cdb/readonly.c index b644a1d..d9f3eef 100644 --- a/cdb/readonly.c +++ b/cdb/readonly.c @@ -7,3 +7,65 @@ static void destroy_cdb_idtabcb(Tcl_Interp *ip, void *val) { abort(); } const IdDataSpec cdbtcl_databases= { "cdb-db", "cdb-opendatabases-table", destroy_cdb_idtabcb }; + +typedef struct Ro { + int ix, fd; + struct cdb cdb; +} Ro; + +int cht_do_cdb_open(ClientData cd, Tcl_Interp *ip, + const char *path, void **result) { + Ro *ro; + int rc, r; + + ro= TALLOC(sizeof(*ro)); + ro->fd= open(path, O_RDONLY); + if (ro->fd<0) PE("open database file"); + r= cdb_init(&ro->cdb, ro->fd); + if (r) PE("initialise cdb"); + *result= ro; + return TCL_OK; + + x_rc: + if (ro->fd >= 0) close(ro->fd); + return rc; +} + +int cht_do_cdb_close(ClientData cd, Tcl_Interp *ip, void *ro_v) { + Ro *ro= ro_v; + cdb_free(&ro->cdb); + close(ro->fd); + TFREE(ro); + return TCL_OK; +} + +int cht_do_cdb_lookup(ClientData cd, Tcl_Interp *ip, void *ro_v, + Tcl_Obj *keyo, Tcl_Obj *def, Tcl_Obj **result) { + Ro *ro= ro_v; + const Byte *key; + const Byte *data; + int r, dlen, klen; + + key= Tcl_GetStringFromObj(keyo, &klen); assert(key); + + r= cht_cdb_lookup_cdb(ip, &ro->cdb, key, klen, &data, &dlen); + if (r) return r; + + return cht_cdb_donesomelookup(ip, ro_v, def, result, data, dlen, + cht_cdb_storeanswer_string); +} + +int cht_do_cdb_lookup_hb(ClientData cd, Tcl_Interp *ip, void *ro_v, + HBytes_Value key, Tcl_Obj *def, Tcl_Obj **result) { + Ro *ro= ro_v; + const Byte *data; + int r, dlen; + + r= cht_cdb_lookup_cdb(ip, &ro->cdb, + cht_hb_data(&key), cht_hb_len(&key), + &data, &dlen); + if (r) return r; + + return cht_cdb_donesomelookup(ip, ro_v, def, result, data, dlen, + cht_cdb_storeanswer_hb); +} diff --git a/cdb/writeable.c b/cdb/writeable.c index 1059a10..e584b79 100644 --- a/cdb/writeable.c +++ b/cdb/writeable.c @@ -15,10 +15,6 @@ static void maybe_close(int fd) { if (fd>=0) close(fd); } -#define PE(m) do{ \ - rc= cht_posixerr(ip, errno, "failed to " m); goto x_rc; \ - }while(0) - /*==================== Subsystems and subtypes ====================*/ /*---------- Pathbuf ----------*/ @@ -416,7 +412,7 @@ int cht_do_cdbwr_open(ClientData cd, Tcl_Interp *ip, const char *pathb, } mainfd= open(pathbuf_sfx(&rw->pbsome,".main"), O_RDONLY); - if (mainfd<0) PE("open exist3ing database file .main"); + if (mainfd<0) PE("open existing database file .main"); rc= acquire_lock(ip, &rw->pbsome, &rw->lock_fd); if (rc) goto x_rc; r= fstat(mainfd, &stab); if (r) PE("fstat .main"); @@ -850,7 +846,6 @@ static int lookup_rw(Tcl_Interp *ip, void *rw_v, const char *key, const Byte **data_r, int *len_r /* -1 => notfound */) { Rw *rw= rw_v; const HashValue *val; - int r; val= ht_lookup(&rw->logincore, key); if (val) { @@ -858,27 +853,27 @@ static int lookup_rw(Tcl_Interp *ip, void *rw_v, const char *key, else { *data_r= 0; *len_r= -1; return TCL_OK; } } - r= cdb_find(&rw->cdb, key, strlen(key)); - if (!r) { *data_r= 0; *len_r= -1; return TCL_OK; } - if (r<0) return cht_posixerr(ip, errno, "cdb_find failed"); - assert(r==1); - *len_r= cdb_datalen(&rw->cdb); - assert(*len_r > 0); - *data_r= cdb_getdata(&rw->cdb); - if (!*data_r) return cht_posixerr(ip, errno, "cdb_getdata failed"); - return TCL_OK; + return cht_cdb_lookup_cdb(ip, &rw->cdb, key, strlen(key), data_r, len_r); } int cht_do_cdbwr_lookup(ClientData cd, Tcl_Interp *ip, void *rw_v, const char *key, Tcl_Obj *def, Tcl_Obj **result) { - return cht_cdb_dosomelookup(ip, rw_v, key, def, result, - lookup_rw, cht_cdb_storeanswer_string); + const Byte *data; + int dlen, r; + + r= lookup_rw(ip, rw_v, key, &data, &dlen); if (r) return r; + return cht_cdb_donesomelookup(ip, rw_v, def, result, data, dlen, + cht_cdb_storeanswer_string); } int cht_do_cdbwr_lookup_hb(ClientData cd, Tcl_Interp *ip, void *rw_v, const char *key, Tcl_Obj *def, Tcl_Obj **result) { - return cht_cdb_dosomelookup(ip, rw_v, key, def, result, - lookup_rw, cht_cdb_storeanswer_hb); + const Byte *data; + int dlen, r; + + r= lookup_rw(ip, rw_v, key, &data, &dlen); if (r) return r; + return cht_cdb_donesomelookup(ip, rw_v, def, result, data, dlen, + cht_cdb_storeanswer_hb); }