Merge r21-4-14-chise-b1.
[chise/xemacs-chise.git.1] / src / database.c
index 350f9af..3e70dc3 100644 (file)
@@ -45,20 +45,32 @@ Boston, MA 02111-1307, USA.  */
 #ifdef HAVE_INTTYPES_H
 #define __BIT_TYPES_DEFINED__
 #include <inttypes.h>
+#ifndef __FreeBSD__
 typedef uint8_t  u_int8_t;
 typedef uint16_t u_int16_t;
 typedef uint32_t u_int32_t;
 #ifdef WE_DONT_NEED_QUADS
 typedef uint64_t u_int64_t;
+#endif
 #endif /* WE_DONT_NEED_QUADS */
 #endif /* HAVE_INTTYPES_H */
 #endif /* !(defined __GLIBC__ && __GLIBC_MINOR__ >= 1) */
-#include DB_H_PATH              /* Berkeley db's header file */
+/* Berkeley DB wants __STDC__ to be defined; else if does `#define const' */
+#if ! defined (__STDC__) && ! defined(__cplusplus)
+#define __STDC__ 0
+#endif
+#include DB_H_FILE              /* Berkeley db's header file */
 #ifndef DB_VERSION_MAJOR
 # define DB_VERSION_MAJOR 1
 #endif /* DB_VERSION_MAJOR */
+#ifndef DB_VERSION_MINOR
+# define DB_VERSION_MINOR 0
+#endif /* DB_VERSION_MINOR */
 Lisp_Object Qberkeley_db;
 Lisp_Object Qhash, Qbtree, Qrecno, Qunknown;
+#if DB_VERSION_MAJOR > 2
+Lisp_Object Qqueue;
+#endif 
 #endif /* HAVE_BERKELEY_DB */
 
 #ifdef HAVE_DBM
@@ -75,9 +87,6 @@ Lisp_Object Vdatabase_coding_system;
 
 Lisp_Object Qdatabasep;
 
-struct Lisp_Database;
-typedef struct Lisp_Database Lisp_Database;
-
 typedef struct
 {
   Lisp_Object (*get_subtype) (Lisp_Database *);
@@ -113,7 +122,6 @@ struct Lisp_Database
 #define XDATABASE(x) XRECORD (x, database, Lisp_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 CONCHECK_DATABASE(x) CONCHECK_RECORD (x, database)
 #define DATABASE_LIVE_P(x) (x->live_p)
@@ -128,7 +136,7 @@ struct Lisp_Database
 static Lisp_Database *
 allocate_database (void)
 {
-  Lisp_Database *db = alloc_lcrecord_type (Lisp_Database, lrecord_database);
+  Lisp_Database *db = alloc_lcrecord_type (Lisp_Database, &lrecord_database);
 
   db->fname = Qnil;
   db->live_p = 0;
@@ -148,12 +156,10 @@ allocate_database (void)
 }
 
 static Lisp_Object
-mark_database (Lisp_Object obj, void (*markobj) (Lisp_Object))
+mark_database (Lisp_Object object)
 {
-  Lisp_Database *db = XDATABASE (obj);
-
-  markobj (db->fname);
-  return Qnil;
+  Lisp_Database *db = XDATABASE (object);
+  return db->fname;
 }
 
 static void
@@ -184,18 +190,18 @@ finalize_database (void *header, int for_disksave)
 
   if (for_disksave)
     {
-      Lisp_Object obj;
-      XSETDATABASE (obj, db);
+      Lisp_Object object;
+      XSETDATABASE (object, db);
 
       signal_simple_error
-       ("Can't dump an emacs containing database objects", obj);
+       ("Can't dump an emacs containing database objects", object);
     }
   db->funcs->close (db);
 }
 
 DEFINE_LRECORD_IMPLEMENTATION ("database", database,
                                mark_database, print_database,
-                              finalize_database, 0, 0,
+                              finalize_database, 0, 0, 0,
                               Lisp_Database);
 
 DEFUN ("close-database", Fclose_database, 1, 1, 0, /*
@@ -232,11 +238,12 @@ Return the subtype of database DATABASE, if any.
 }
 
 DEFUN ("database-live-p", Fdatabase_live_p, 1, 1, 0, /*
-Return t if OBJ is an active database.
+Return t if OBJECT is an active database.
 */
-       (obj))
+       (object))
 {
-  return DATABASEP (obj) && DATABASE_LIVE_P (XDATABASE (obj)) ? Qt : Qnil;
+  return DATABASEP (object) && DATABASE_LIVE_P (XDATABASE (object)) ?
+    Qt : Qnil;
 }
 
 DEFUN ("database-file-name", Fdatabase_file_name, 1, 1, 0, /*
@@ -250,11 +257,11 @@ Return the filename associated with the database DATABASE.
 }
 
 DEFUN ("databasep", Fdatabasep, 1, 1, 0, /*
-Return t if OBJ is a database.
+Return t if OBJECT is a database.
 */
-       (obj))
+       (object))
 {
-  return DATABASEP (obj) ? Qt : Qnil;
+  return DATABASEP (object) ? Qt : Qnil;
 }
 
 #ifdef HAVE_DBM
@@ -374,6 +381,9 @@ berkdb_subtype (Lisp_Database *db)
     case DB_BTREE: return Qbtree;
     case DB_HASH:  return Qhash;
     case DB_RECNO: return Qrecno;
+#if DB_VERSION_MAJOR > 2
+    case DB_QUEUE: return Qqueue;
+#endif
     default:       return Qunknown;
     }
 }
@@ -492,7 +502,7 @@ berkdb_map (Lisp_Database *db, Lisp_Object func)
        status == 0;
        status = dbp->seq (dbp, &keydatum, &valdatum, R_NEXT))
     {
-      /* ### Needs mule-izing */
+      /* #### Needs mule-izing */
       key = make_string ((Bufbyte *) keydatum.data, keydatum.size);
       val = make_string ((Bufbyte *) valdatum.data, valdatum.size);
       call2 (func, key, val);
@@ -501,12 +511,16 @@ berkdb_map (Lisp_Database *db, Lisp_Object func)
   {
     DBC *dbcp;
 
+#if DB_VERSION_MAJOR > 2 || DB_VERSION_MINOR >=6
+    status = dbp->cursor (dbp, NULL, &dbcp, 0);
+#else
     status = dbp->cursor (dbp, NULL, &dbcp);
+#endif
     for (status = dbcp->c_get (dbcp, &keydatum, &valdatum, DB_FIRST);
         status == 0;
         status = dbcp->c_get (dbcp, &keydatum, &valdatum, DB_NEXT))
       {
-       /* ### Needs mule-izing */
+       /* #### Needs mule-izing */
        key = make_string ((Bufbyte *) keydatum.data, keydatum.size);
        val = make_string ((Bufbyte *) valdatum.data, valdatum.size);
        call2 (func, key, val);
@@ -580,7 +594,9 @@ and defaults to 0755.
   file = Fexpand_file_name (file, Qnil);
   UNGCPRO;
 
-  GET_C_CHARPTR_EXT_FILENAME_DATA_ALLOCA (XSTRING_DATA (file), filename);
+  TO_EXTERNAL_FORMAT (LISP_STRING, file,
+                     C_STRING_ALLOCA, filename,
+                     Qfile_name);
 
   if (NILP (access_))
     {
@@ -643,6 +659,10 @@ and defaults to 0755.
        real_subtype = DB_BTREE;
       else if (EQ (subtype, Qrecno))
        real_subtype = DB_RECNO;
+#if DB_VERSION_MAJOR > 2
+      else if (EQ (subtype, Qqueue))
+       real_subtype = DB_QUEUE;
+#endif
       else
        signal_simple_error ("Unsupported subtype", subtype);
 
@@ -668,10 +688,31 @@ and defaults to 0755.
          if (strchr (acc, 'r') && !strchr (acc, 'w'))
            accessmask |= DB_RDONLY;
        }
+#if DB_VERSION_MAJOR == 2
       status = db_open (filename, real_subtype, accessmask,
                        modemask, NULL , NULL, &dbase);
       if (status)
        return Qnil;
+#else
+      status = db_create (&dbase, NULL, 0);
+      if (status)
+        return Qnil;
+#if DB_VERSION_MAJOR < 4 || (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR < 1)
+      status = dbase->open (dbase, filename, NULL,
+                            real_subtype, accessmask, modemask);
+#else /* DB_VERSION >= 4.1 */
+      /* DB_AUTO_COMMIT requires transaction support, don't try it */
+      status = dbase->open (dbase, NULL, filename, NULL, real_subtype,
+                           accessmask, modemask);
+#endif /* DB_VERSION < 4.1 */
+      if (status)
+        {
+          dbase->close (dbase, 0);
+          return Qnil;
+        }
+#endif /* DB_VERSION_MAJOR > 2 */
+      /* Normalize into system specific file modes. Only for printing */
+      accessmask = accessmask & DB_RDONLY ? O_RDONLY : O_RDWR;
 #endif /* DB_VERSION_MAJOR */
 
       db = allocate_database ();
@@ -743,7 +784,7 @@ If there is no corresponding value, return DEFAULT (defaults to nil).
   }
 }
 
-DEFUN ("map-database", Fmapdatabase, 2, 2, 0, /*
+DEFUN ("map-database", Fmap_database, 2, 2, 0, /*
 Map FUNCTION over entries in DATABASE, calling it with two args,
 each key and value in the database.
 */
@@ -759,6 +800,8 @@ each key and value in the database.
 void
 syms_of_database (void)
 {
+  INIT_LRECORD_IMPLEMENTATION (database);
+
   defsymbol (&Qdatabasep, "databasep");
 #ifdef HAVE_DBM
   defsymbol (&Qdbm, "dbm");
@@ -768,12 +811,15 @@ syms_of_database (void)
   defsymbol (&Qhash, "hash");
   defsymbol (&Qbtree, "btree");
   defsymbol (&Qrecno, "recno");
+#if DB_VERSION_MAJOR > 2
+  defsymbol (&Qqueue, "queue");
+#endif
   defsymbol (&Qunknown, "unknown");
 #endif
 
   DEFSUBR (Fopen_database);
   DEFSUBR (Fdatabasep);
-  DEFSUBR (Fmapdatabase);
+  DEFSUBR (Fmap_database);
   DEFSUBR (Fput_database);
   DEFSUBR (Fget_database);
   DEFSUBR (Fremove_database);