chiark / gitweb /
ro compiles
authorian <ian>
Sat, 11 Feb 2006 20:05:20 +0000 (20:05 +0000)
committerian <ian>
Sat, 11 Feb 2006 20:05:20 +0000 (20:05 +0000)
cdb/cdb.tct
cdb/chiark_tcl_cdb.h
cdb/lookup.c
cdb/readonly.c
cdb/writeable.c

index 4df47f3..a7d22b4 100644 (file)
@@ -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)
 
index 63259a8..d06713d 100644 (file)
@@ -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*/
index 52598ef..4902295 100644 (file)
@@ -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;
+}
index b644a1d..d9f3eef 100644 (file)
@@ -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);
+}
index 1059a10..e584b79 100644 (file)
@@ -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);
 }