Mercurial > hg > xemacs-beta
diff src/database.c @ 185:3d6bfa290dbd r20-3b19
Import from CVS: tag r20-3b19
author | cvs |
---|---|
date | Mon, 13 Aug 2007 09:55:28 +0200 |
parents | 6075d714658b |
children | b405438285a2 |
line wrap: on
line diff
--- a/src/database.c Mon Aug 13 09:54:24 2007 +0200 +++ b/src/database.c Mon Aug 13 09:55:28 2007 +0200 @@ -21,7 +21,7 @@ /* Synched up with: Not in FSF. */ /* Written by Bill Perry */ -/* Hacked on by Martin Buchholz */ +/* Substantially rewritten by Martin Buchholz */ #include <config.h> #include "lisp.h" @@ -63,24 +63,23 @@ typedef enum { DB_DBM, DB_BERKELEY, DB_UNKNOWN } XEMACS_DB_TYPE; -struct database_struct; -typedef struct database_struct database_struct; +struct database; +typedef struct database database; typedef struct { - CONST char * (*get_subtype) (struct database_struct *); - CONST char * (*get_type) (struct database_struct *); - void * (*open_file) (CONST char *, Lisp_Object, int, int); - Lisp_Object (*get) (struct database_struct *, Lisp_Object); - int (*put) (struct database_struct *, Lisp_Object, Lisp_Object, Lisp_Object); - int (*rem) (struct database_struct *, Lisp_Object); - void (*map) (struct database_struct *, Lisp_Object); - Lisp_Object (*get_lisp_type) (struct database_struct *); - void (*close) (struct database_struct *); - Lisp_Object (*last_error) (struct database_struct *); + CONST char * (*get_subtype) (struct database *); + CONST char * (*get_type) (struct database *); + Lisp_Object (*get) (struct database *, Lisp_Object); + int (*put) (struct database *, Lisp_Object, Lisp_Object, Lisp_Object); + int (*rem) (struct database *, Lisp_Object); + void (*map) (struct database *, Lisp_Object); + Lisp_Object (*get_lisp_type) (struct database *); + void (*close) (struct database *); + Lisp_Object (*last_error) (struct database *); } DB_FUNCS; -struct database_struct +struct database { struct lcrecord_header header; Lisp_Object fname; @@ -88,35 +87,54 @@ int mode; int access_; int dberrno; - void *db_handle; + int live_p; +#ifdef HAVE_DBM + DBM *dbm_handle; +#endif +#ifdef HAVE_BERKELEY_DB + DB *db_handle; +#endif DB_FUNCS *funcs; #ifdef MULE Lisp_Object coding_system; #endif }; -#define XDATABASE(x) XRECORD (x, database, struct database_struct) +#define XDATABASE(x) XRECORD (x, database, struct database) #define XSETDATABASE(x, p) XSETRECORD (x, p, database) #define DATABASEP(x) RECORDP (x, database) #define GC_DATABASEP(x) GC_RECORDP (x, database) #define CHECK_DATABASE(x) CHECK_RECORD (x, database) -#define DATABASE_LIVE_P(x) (x->db_handle) +#define DATABASE_LIVE_P(x) (x->live_p) static Lisp_Object mark_database (Lisp_Object, void (*) (Lisp_Object)); static void print_database (Lisp_Object, Lisp_Object, int); static void finalize_database (void *, int); DEFINE_LRECORD_IMPLEMENTATION ("database", database, mark_database, print_database, finalize_database, 0, 0, - struct database_struct); + struct database); -static struct database_struct * +#define CHECK_LIVE_DATABASE(db) do { \ + CHECK_DATABASE(db); \ + if (!DATABASE_LIVE_P (XDATABASE(db))) \ + signal_simple_error ("Attempting to access closed database", db); \ +} while (0) + + +static struct database * new_database (void) { - struct database_struct *dbase - = alloc_lcrecord (sizeof (struct database_struct), lrecord_database); + struct database *dbase = + alloc_lcrecord_type (struct database, lrecord_database); dbase->fname = Qnil; + dbase->live_p = 0; +#ifdef HAVE_BERKELEY_DB dbase->db_handle = NULL; +#endif +#ifdef HAVE_DBM + dbase->dbm_handle = NULL; +#endif dbase->access_ = 0; dbase->mode = 0; dbase->dberrno = 0; @@ -130,7 +148,7 @@ static Lisp_Object mark_database (Lisp_Object obj, void (*markobj) (Lisp_Object)) { - struct database_struct *dbase = XDATABASE (obj); + struct database *dbase = XDATABASE (obj); ((markobj) (dbase->fname)); return Qnil; @@ -139,7 +157,7 @@ static void print_database (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag) { - struct database_struct *dbase = XDATABASE (obj); + struct database *dbase = XDATABASE (obj); char buf[200]; if (print_readably) @@ -148,19 +166,13 @@ } else { - CONST char *type; - CONST char *subtype; - CONST char *perms; - - perms = (!dbase->db_handle) ? "closed" : - (dbase->access_ & O_WRONLY) ? "writeonly" : - (dbase->access_ & O_RDWR) ? "readwrite" : "readonly"; - - type = dbase->funcs->get_type (dbase); - subtype = dbase->funcs->get_subtype (dbase); - - sprintf (buf, "#<database %s (%s/%s/%s) 0x%x>", - XSTRING_DATA (dbase->fname), type, subtype, perms, + sprintf (buf, "#<database \"%s\" (%s/%s/%s) 0x%x>", + XSTRING_DATA (dbase->fname), + dbase->funcs->get_type (dbase), + dbase->funcs->get_subtype (dbase), + (!DATABASE_LIVE_P (dbase) ? "closed" : + (dbase->access_ & O_WRONLY) ? "writeonly" : + (dbase->access_ & O_RDWR) ? "readwrite" : "readonly"), dbase->header.uid); write_c_string (buf, printcharfun); } @@ -169,13 +181,13 @@ static void finalize_database (void *header, int for_disksave) { - struct database_struct *db = (struct database_struct *) header; + struct database *db = (struct database *) header; if (for_disksave) { - Lisp_Object obj; - XSETOBJ (obj, Lisp_Record, (void *) db); - + Lisp_Object obj; + XSETOBJ (obj, Lisp_Type_Record, (void *) db); + signal_simple_error ("Can't dump an emacs containing window system objects", obj); } @@ -187,15 +199,9 @@ */ (obj)) { - struct database_struct *db; - CHECK_DATABASE (obj); - db = XDATABASE (obj); - - if (DATABASE_LIVE_P (db)) - db->funcs->close (db); - else - signal_simple_error ("Attempting to access closed database", obj); - + CHECK_LIVE_DATABASE (obj); + XDATABASE (obj)->funcs->close (XDATABASE (obj)); + XDATABASE (obj)->live_p = 0; return Qnil; } @@ -204,11 +210,9 @@ */ (obj)) { - struct database_struct *db; CHECK_DATABASE (obj); - db = XDATABASE (obj); - return db->funcs->get_lisp_type (db); + return XDATABASE (obj)->funcs->get_lisp_type (XDATABASE (obj)); } DEFUN ("database-subtype", Fdatabase_subtype, 1, 1, 0, /* @@ -216,12 +220,9 @@ */ (obj)) { - struct database_struct *db; - CHECK_DATABASE (obj); - db = XDATABASE (obj); - - return intern (db->funcs->get_subtype (db)); + + return intern (XDATABASE (obj)->funcs->get_subtype (XDATABASE (obj))); } DEFUN ("database-live-p", Fdatabase_live_p, 1, 1, 0, /* @@ -229,11 +230,9 @@ */ (obj)) { - struct database_struct *db; CHECK_DATABASE (obj); - db = XDATABASE (obj); - return DATABASE_LIVE_P (db) ? Qt : Qnil; + return DATABASE_LIVE_P (XDATABASE (obj)) ? Qt : Qnil; } DEFUN ("database-file-name", Fdatabase_file_name, 1, 1, 0, /* @@ -241,10 +240,9 @@ */ (obj)) { - struct database_struct *db; CHECK_DATABASE (obj); - db = XDATABASE (obj); - return db->fname; + + return XDATABASE (obj)->fname; } DEFUN ("databasep", Fdatabasep, 1, 1, 0, /* @@ -257,17 +255,16 @@ #ifdef HAVE_DBM static void -dbm_map (struct database_struct *db, Lisp_Object func) +dbm_map (struct database *db, Lisp_Object func) { datum keydatum, valdatum; - DBM *handle = (DBM *)db->db_handle; Lisp_Object key, val; - for (keydatum = dbm_firstkey (handle); + for (keydatum = dbm_firstkey (db->dbm_handle); keydatum.dptr != NULL; - keydatum = dbm_nextkey (handle)) + keydatum = dbm_nextkey (db->dbm_handle)) { - valdatum = dbm_fetch (handle, keydatum); + valdatum = dbm_fetch (db->dbm_handle, keydatum); key = make_string ((unsigned char *) keydatum.dptr, keydatum.dsize); val = make_string ((unsigned char *) valdatum.dptr, valdatum.dsize); call2 (func, key, val); @@ -275,13 +272,13 @@ } static Lisp_Object -dbm_get (struct database_struct *db, Lisp_Object key) +dbm_get (struct database *db, Lisp_Object key) { datum keydatum, valdatum; - DBM *handle = (DBM *)db->db_handle; + keydatum.dptr = (char *) XSTRING_DATA (key); keydatum.dsize = XSTRING_LENGTH (key); - valdatum = dbm_fetch (handle, keydatum); + valdatum = dbm_fetch (db->dbm_handle, keydatum); return (valdatum.dptr ? make_string ((unsigned char *) valdatum.dptr, valdatum.dsize) @@ -289,77 +286,69 @@ } static int -dbm_put (struct database_struct *db, - Lisp_Object key, - Lisp_Object val, - Lisp_Object replace) +dbm_put (struct database *db, + Lisp_Object key, Lisp_Object val, Lisp_Object replace) { - DBM *handle = (DBM *)db->db_handle; datum keydatum, valdatum; - + valdatum.dptr = (char *) XSTRING_DATA (val); valdatum.dsize = XSTRING_LENGTH (val); keydatum.dptr = (char *) XSTRING_DATA (key); keydatum.dsize = XSTRING_LENGTH (key); - return (!dbm_store (handle, keydatum, valdatum, - (NILP (replace)) ? DBM_INSERT : DBM_REPLACE)); + return !dbm_store (db->dbm_handle, keydatum, valdatum, + NILP (replace) ? DBM_INSERT : DBM_REPLACE); } static int -dbm_remove (struct database_struct *db, Lisp_Object key) +dbm_remove (struct database *db, Lisp_Object key) { datum keydatum; + keydatum.dptr = (char *) XSTRING_DATA (key); keydatum.dsize = XSTRING_LENGTH (key); - return dbm_delete (db->db_handle, keydatum); + + return dbm_delete (db->dbm_handle, keydatum); } static Lisp_Object -dbm_lisp_type (struct database_struct *db) +dbm_lisp_type (struct database *db) { return Qdbm; } static CONST char * -dbm_type (struct database_struct *db) +dbm_type (struct database *db) { return "dbm"; } static CONST char * -dbm_subtype (struct database_struct *db) +dbm_subtype (struct database *db) { return "nil"; } -static void * -new_dbm_file (CONST char *file, Lisp_Object subtype, int access_, int mode) -{ - DBM *db = NULL; - db = dbm_open ((char *) file, access_, mode); - return (void *) db; -} - static Lisp_Object -dbm_lasterr (struct database_struct *dbp) +dbm_lasterr (struct database *dbp) { return lisp_strerror (dbp->dberrno); } static void -dbm_closeit (struct database_struct *db) +dbm_closeit (struct database *db) { - if (db->db_handle) - dbm_close ((DBM *)db->db_handle); - db->db_handle = NULL; + if (db->dbm_handle) + { + dbm_close (db->dbm_handle); + db->dbm_handle = NULL; + } } static DB_FUNCS ndbm_func_block = { dbm_subtype, dbm_type, - new_dbm_file, dbm_get, dbm_put, dbm_remove, @@ -368,159 +357,131 @@ dbm_closeit, dbm_lasterr }; -#endif +#endif /* HAVE_DBM */ #ifdef HAVE_BERKELEY_DB static Lisp_Object -berkdb_lisp_type (struct database_struct *db) +berkdb_lisp_type (struct database *db) { return Qberkeley_db; } static CONST char * -berkdb_type (struct database_struct *db) +berkdb_type (struct database *db) { return "berkeley"; } static CONST char * -berkdb_subtype (struct database_struct *db) +berkdb_subtype (struct database *db) { - DB *temp = (DB *)db->db_handle; - - if (!temp) + if (!db->db_handle) return "nil"; - - switch (temp->type) - { - case DB_BTREE: - return "btree"; - case DB_HASH: - return "hash"; - case DB_RECNO: - return "recno"; - } - return "unknown"; -} -static void * -berkdb_open (CONST char *file, Lisp_Object subtype, int access_, int mode) -{ - DB *db; - DBTYPE real_subtype; - - if (EQ (subtype, Qhash) || NILP (subtype)) - real_subtype = DB_HASH; - else if (EQ (subtype, Qbtree)) - real_subtype = DB_BTREE; - else if (EQ (subtype, Qrecno)) - real_subtype = DB_RECNO; - else - signal_simple_error ("Unsupported subtype", subtype); - - db = dbopen (file, access_, mode, real_subtype, NULL); - - return (void *) db; + switch (db->db_handle->type) + { + case DB_BTREE: return "btree"; + case DB_HASH: return "hash"; + case DB_RECNO: return "recno"; + default: return "unknown"; + } } static Lisp_Object -berkdb_lasterr (struct database_struct *dbp) +berkdb_lasterr (struct database *dbp) { return lisp_strerror (dbp->dberrno); } static Lisp_Object -berkdb_get (struct database_struct *db, Lisp_Object key) +berkdb_get (struct database *db, Lisp_Object key) { + /* #### Needs mule-izing */ DBT keydatum, valdatum; - DB *dbp = (DB *) db->db_handle; int status = 0; keydatum.data = XSTRING_DATA (key); keydatum.size = XSTRING_LENGTH (key); - - status = dbp->get (dbp, &keydatum, &valdatum, 0); + + status = db->db_handle->get (db->db_handle, &keydatum, &valdatum, 0); if (!status) - return make_string (valdatum.data, valdatum.size); + return make_string ((Bufbyte *) valdatum.data, valdatum.size); db->dberrno = (status == 1) ? -1 : errno; return Qnil; } static int -berkdb_put (struct database_struct *db, +berkdb_put (struct database *db, Lisp_Object key, Lisp_Object val, Lisp_Object replace) { DBT keydatum, valdatum; - DB *dbp = (DB *) db->db_handle; int status = 0; keydatum.data = XSTRING_DATA (key); keydatum.size = XSTRING_LENGTH (key); valdatum.data = XSTRING_DATA (val); valdatum.size = XSTRING_LENGTH (val); - status = dbp->put (dbp, &keydatum, &valdatum, NILP (replace) - ? R_NOOVERWRITE : 0); + status = db->db_handle->put (db->db_handle, &keydatum, &valdatum, + NILP (replace) ? R_NOOVERWRITE : 0); db->dberrno = (status == 1) ? -1 : errno; return status; } static int -berkdb_remove (struct database_struct *db, Lisp_Object key) +berkdb_remove (struct database *db, Lisp_Object key) { DBT keydatum; - DB *dbp = (DB *) db->db_handle; int status; keydatum.data = XSTRING_DATA (key); keydatum.size = XSTRING_LENGTH (key); - - status = dbp->del (dbp, &keydatum, 0); + + status = db->db_handle->del (db->db_handle, &keydatum, 0); if (!status) return 0; - + db->dberrno = (status == 1) ? -1 : errno; return 1; } static void -berkdb_map (struct database_struct *db, Lisp_Object func) +berkdb_map (struct database *db, Lisp_Object func) { DBT keydatum, valdatum; Lisp_Object key, val; - DB *dbp = (DB *) db->db_handle; + DB *dbp = db->db_handle; int status; for (status = dbp->seq (dbp, &keydatum, &valdatum, R_FIRST); status == 0; status = dbp->seq (dbp, &keydatum, &valdatum, R_NEXT)) { - key = make_string (keydatum.data, keydatum.size); - val = make_string (valdatum.data, valdatum.size); + /* ### Needs mule-izing */ + key = make_string ((Bufbyte *) keydatum.data, keydatum.size); + val = make_string ((Bufbyte *) valdatum.data, valdatum.size); call2 (func, key, val); } } static void -berkdb_close (struct database_struct *db) +berkdb_close (struct database *db) { - DB *dbp = (DB *)db->db_handle; - if (dbp) + if (db->db_handle) { - dbp->sync (dbp, 0); - dbp->close (dbp); + db->db_handle->sync (db->db_handle, 0); + db->db_handle->close (db->db_handle); + db->db_handle = NULL; } - db->db_handle = NULL; } static DB_FUNCS berk_func_block = { berkdb_subtype, berkdb_type, - berkdb_open, berkdb_get, berkdb_put, berkdb_remove, @@ -529,21 +490,19 @@ berkdb_close, berkdb_lasterr }; -#endif +#endif /* HAVE_BERKELEY_DB */ DEFUN ("database-last-error", Fdatabase_error, 0, 1, 0, /* Return the last error associated with database OBJ. */ (obj)) { - struct database_struct *db; - if (NILP (obj)) return lisp_strerror (errno); - + CHECK_DATABASE (obj); - db = XDATABASE (obj); - return db->funcs->last_error (db); + + return XDATABASE (obj)->funcs->last_error (XDATABASE (obj)); } DEFUN ("open-database", Fmake_database, 1, 5, 0, /* @@ -556,12 +515,11 @@ Lisp_Object retval = Qnil; int modemask; int accessmask = 0; - XEMACS_DB_TYPE the_type; - DB_FUNCS *funcblock; - struct database_struct *dbase = NULL; - void *db = NULL; + struct database *dbase = NULL; + char *filename; CHECK_STRING (file); + filename = (char *) XSTRING_DATA (file); if (NILP (access_)) { @@ -572,27 +530,21 @@ char *acc; CHECK_STRING (access_); acc = (char *) XSTRING_DATA (access_); - + if (strchr (acc, '+')) accessmask |= O_CREAT; - + if (strchr (acc, 'r') && strchr (acc, 'w')) - { accessmask |= O_RDWR; - } else if (strchr (acc, 'w')) - { accessmask |= O_WRONLY; - } else - { accessmask |= O_RDONLY; - } } if (NILP (mode)) { - modemask = 493; /* rwxr-xr-x */ + modemask = 0755; /* rwxr-xr-x */ } else { @@ -603,67 +555,73 @@ #ifdef HAVE_DBM if (NILP (type) || EQ (type, Qdbm)) { - the_type = DB_DBM; - funcblock = &ndbm_func_block; + DBM *dbm = dbm_open (filename, accessmask, modemask); + if (!dbm) + return Qnil; + + dbase = new_database (); + dbase->dbm_handle = dbm; + dbase->type = DB_DBM; + dbase->funcs = &ndbm_func_block; goto db_done; } -#endif +#endif /* HAVE_DBM */ #ifdef HAVE_BERKELEY_DB if (NILP (type) || EQ (type, Qberkeley_db)) { + DBTYPE real_subtype; + DB *db; - funcblock = &berk_func_block; - the_type = DB_BERKELEY; + if (EQ (subtype, Qhash) || NILP (subtype)) + real_subtype = DB_HASH; + else if (EQ (subtype, Qbtree)) + real_subtype = DB_BTREE; + else if (EQ (subtype, Qrecno)) + real_subtype = DB_RECNO; + else + signal_simple_error ("Unsupported subtype", subtype); + + db = dbopen (filename, accessmask, modemask, real_subtype, NULL); + if (!db) + return Qnil; + + dbase = new_database (); + dbase->db_handle = db; + dbase->type = DB_BERKELEY; + dbase->funcs = &berk_func_block; goto db_done; } -#endif - +#endif /* HAVE_BERKELEY_DB */ + signal_simple_error ("Unsupported database type", type); return Qnil; db_done: - db = funcblock->open_file ((char *) XSTRING_DATA (file), subtype, - accessmask, modemask); - - if (!db) - { - return Qnil; - } - - dbase = new_database (); + dbase->live_p = 1; dbase->fname = file; - dbase->type = the_type; dbase->mode = modemask; dbase->access_ = accessmask; - dbase->db_handle = db; - dbase->funcs = funcblock; XSETDATABASE (retval, dbase); return retval; } DEFUN ("put-database", Fputdatabase, 3, 4, 0, /* -Store KEY and VAL in DATABASE. If optinal fourth arg REPLACE is +Store KEY and VAL in DATABASE. If optional fourth arg REPLACE is non-nil, replace any existing entry in the database. */ (key, val, dbase, replace)) { - struct database_struct *db; - int status; - struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; - - CHECK_DATABASE (dbase); + CHECK_LIVE_DATABASE (dbase); CHECK_STRING (key); CHECK_STRING (val); - db = XDATABASE (dbase); - if (!DATABASE_LIVE_P (db)) - signal_simple_error ("Attempting to access closed database", dbase); - GCPRO4 (key, val, dbase, replace); - status = db->funcs->put (db, key, val, replace); - UNGCPRO; - return status ? Qt : Qnil; + { + int status = + XDATABASE (dbase)->funcs->put (XDATABASE (dbase), key, val, replace); + return status ? Qt : Qnil; + } } DEFUN ("remove-database", Fremdatabase, 2, 2, 0, /* @@ -671,34 +629,27 @@ */ (key, dbase)) { - struct database_struct *db; - CHECK_DATABASE (dbase); + CHECK_LIVE_DATABASE (dbase); CHECK_STRING (key); - db = XDATABASE (dbase); - if (!DATABASE_LIVE_P (db)) - signal_simple_error ("Attempting to access closed database", dbase); - return db->funcs->rem (db, key) ? Qt : Qnil; + return XDATABASE (dbase)->funcs->rem (XDATABASE (dbase), key) ? Qt : Qnil; } - + DEFUN ("get-database", Fgetdatabase, 2, 3, 0, /* Find value for KEY in DATABASE. If there is no corresponding value, return DEFAULT (defaults to nil). */ (key, dbase, default_)) { - Lisp_Object retval; - struct database_struct *db; - CHECK_DATABASE (dbase); + CHECK_LIVE_DATABASE (dbase); CHECK_STRING (key); - db = XDATABASE (dbase); - if (!DATABASE_LIVE_P (db)) - signal_simple_error ("Attempting to access closed database", dbase); - retval = db->funcs->get (db, key); - - return NILP (retval) ? default_ : retval; + { + Lisp_Object retval = + XDATABASE (dbase)->funcs->get (XDATABASE (dbase), key); + return NILP (retval) ? default_ : retval; + } } DEFUN ("map-database", Fmapdatabase, 2, 2, 0, /* @@ -707,17 +658,10 @@ */ (function, dbase)) { - struct gcpro gcpro1, gcpro2; - struct database_struct *db; - - CHECK_DATABASE (dbase); - GCPRO2 (dbase, function); + CHECK_LIVE_DATABASE (dbase); - db = XDATABASE (dbase); - if (!DATABASE_LIVE_P (db)) - signal_simple_error ("Attempting to access closed database", dbase); - db->funcs->map (db, function); - UNGCPRO; + XDATABASE (dbase)->funcs->map (XDATABASE (dbase), function); + return Qnil; }