Integrate mainline
[p5sagit/p5-mst-13.2.git] / ext / DB_File / DB_File.xs
index db4382b..fc2f63e 100644 (file)
@@ -3,12 +3,12 @@
  DB_File.xs -- Perl 5 interface to Berkeley DB 
 
  written by Paul Marquess <Paul.Marquess@btinternet.com>
- last modified 30th July 2001
- version 1.78
+ last modified 1st March 2002
+ version 1.803
 
  All comments/suggestions/problems are welcome
 
-     Copyright (c) 1995-2001 Paul Marquess. All rights reserved.
+     Copyright (c) 1995-2002 Paul Marquess. All rights reserved.
      This program is free software; you can redistribute it and/or
      modify it under the same terms as Perl itself.
 
         1.76 -  No change to DB_File.xs
         1.77 -  Tidied up a few types used in calling newSVpvn.
         1.78 -  Core patch 10335, 10372, 10534, 10549, 11051 included.
+        1.79 -  NEXTKEY ignores the input key.
+                Added lots of casts
+        1.800 - Moved backward compatability code into ppport.h.
+                Use the new constants code.
+        1.801 - No change to DB_File.xs
+        1.802 - No change to DB_File.xs
+        1.803 - FETCH, STORE & DELETE don't map the flags parameter
+                into the equivalent Berkeley DB function anymore.
 
 */
 
 #include "perl.h"
 #include "XSUB.h"
 
-#ifndef PERL_VERSION
-#    include "patchlevel.h"
-#    define PERL_REVISION      5
-#    define PERL_VERSION       PATCHLEVEL
-#    define PERL_SUBVERSION    SUBVERSION
-#endif
-
-#if PERL_REVISION == 5 && (PERL_VERSION < 4 || (PERL_VERSION == 4 && PERL_SUBVERSION <= 75 ))
-
-#    define PL_sv_undef                sv_undef
-#    define PL_na              na
-
-#endif
-
-/* DEFSV appears first in 5.004_56 */
-#ifndef DEFSV
-#    define DEFSV              GvSV(defgv)
+#ifdef _NOT_CORE
+#  include "ppport.h"
 #endif
 
 /* Mention DB_VERSION_MAJOR_CFG, DB_VERSION_MINOR_CFG, and
 #    undef __attribute__
 #endif
 
-
-
-/* If Perl has been compiled with Threads support,the symbol op will
-   be defined here. This clashes with a field name in db.h, so get rid of it.
- */
-#ifdef op
-#    undef op
-#endif
-
 #ifdef COMPAT185
 #    include <db_185.h>
 #else
 
 #endif /* Perl >= 5.7 */
 
-#ifndef pTHX
-#    define pTHX
-#    define pTHX_
-#    define aTHX
-#    define aTHX_
-#endif
-
-#ifndef newSVpvn
-#    define newSVpvn(a,b)      newSVpv(a,b)
-#endif
-
 #include <fcntl.h> 
 
 /* #define TRACE */
@@ -354,9 +327,9 @@ typedef union INFO {
 
 
 
-#define db_DELETE(db, key, flags)       ((db->dbp)->del)(db->dbp, TXN &key, flags)
-#define db_STORE(db, key, value, flags) ((db->dbp)->put)(db->dbp, TXN &key, &value, flags)
-#define db_FETCH(db, key, flags)        ((db->dbp)->get)(db->dbp, TXN &key, &value, flags)
+#define db_DELETE(db, key, flags)       ((db->dbp)->del)(db->dbp, TXN &key, 0)
+#define db_STORE(db, key, value, flags) ((db->dbp)->put)(db->dbp, TXN &key, &value, 0)
+#define db_FETCH(db, key, flags)        ((db->dbp)->get)(db->dbp, TXN &key, &value, 0)
 
 #define db_sync(db, flags)              ((db->dbp)->sync)(db->dbp, flags)
 #define db_get(db, key, value, flags)   ((db->dbp)->get)(db->dbp, TXN &key, &value, flags)
@@ -412,7 +385,7 @@ typedef DBT DBTKEY ;
 #define ckFilter(arg,type,name)                                        \
        if (db->type) {                                         \
            SV * save_defsv ;                                   \
-            /* printf("filtering %s\n", name) ;*/              \
+            /* printf("filtering %s\n", name) ; */             \
            if (db->filtering)                                  \
                croak("recursion detected in %s", name) ;       \
            db->filtering = TRUE ;                              \
@@ -424,7 +397,7 @@ typedef DBT DBTKEY ;
            sv_setsv(DEFSV, save_defsv) ;                       \
            SvREFCNT_dec(save_defsv) ;                          \
            db->filtering = FALSE ;                             \
-           /*printf("end of filtering %s\n", name) ;*/         \
+           /* printf("end of filtering %s\n", name) ; */       \
        }
 
 #else
@@ -454,16 +427,29 @@ typedef DBT DBTKEY ;
          }                                                             \
        }
 
+#define my_SvUV32(sv) ((u_int32_t)SvUV(sv))
 
 #ifdef CAN_PROTOTYPE
 extern void __getBerkeleyDBInfo(void);
 #endif
 
 /* Internal Global Data */
-static recno_t Value ; 
-static recno_t zero = 0 ;
-static DB_File CurrentDB ;
-static DBTKEY empty ;
+
+#define MY_CXT_KEY "DB_File::_guts" XS_VERSION
+
+typedef struct {
+    recno_t    x_Value; 
+    recno_t    x_zero;
+    DB_File    x_CurrentDB;
+    DBTKEY     x_empty;
+} my_cxt_t;
+
+START_MY_CXT
+
+#define Value          (MY_CXT.x_Value)
+#define zero           (MY_CXT.x_zero)
+#define CurrentDB      (MY_CXT.x_CurrentDB)
+#define empty          (MY_CXT.x_empty)
 
 #ifdef DB_VERSION_MAJOR
 
@@ -557,7 +543,8 @@ const DBT * key2 ;
     dTHX;
 #endif    
     dSP ;
-    char * data1, * data2 ;
+    dMY_CXT ;
+    void * data1, * data2 ;
     int retval ;
     int count ;
     
@@ -628,6 +615,7 @@ const DBT * key2 ;
     dTHX;
 #endif    
     dSP ;
+    dMY_CXT ;
     char * data1, * data2 ;
     int retval ;
     int count ;
@@ -706,6 +694,7 @@ HASH_CB_SIZE_TYPE size ;
     dTHX;
 #endif    
     dSP ;
+    dMY_CXT;
     int retval ;
     int count ;
 
@@ -881,6 +870,7 @@ SV *   sv ;
     void *     openinfo = NULL ;
     INFO       * info  = &RETVAL->info ;
     STRLEN     n_a;
+    dMY_CXT;
 
 /* printf("In ParseOpenInfo name=[%s] flags=[%d] mode = [%d]\n", name, flags, mode) ;  */
     Zero(RETVAL, 1, DB_File_type) ;
@@ -1154,6 +1144,7 @@ SV *   sv ;
     DB *       dbp ;
     STRLEN     n_a;
     int                status ;
+    dMY_CXT;
 
 /* printf("In ParseOpenInfo name=[%s] flags=[%d] mode = [%d]\n", name, flags, mode) ;  */
     Zero(RETVAL, 1, DB_File_type) ;
@@ -1210,23 +1201,23 @@ SV *   sv ;
 
            svp = hv_fetch(action, "ffactor", 7, FALSE);
           if (svp)
-              (void)dbp->set_h_ffactor(dbp, SvIV(*svp)) ;
+              (void)dbp->set_h_ffactor(dbp, my_SvUV32(*svp)) ;
          
            svp = hv_fetch(action, "nelem", 5, FALSE);
           if (svp)
-               (void)dbp->set_h_nelem(dbp, SvIV(*svp)) ;
+               (void)dbp->set_h_nelem(dbp, my_SvUV32(*svp)) ;
          
            svp = hv_fetch(action, "bsize", 5, FALSE);
           if (svp)
-               (void)dbp->set_pagesize(dbp, SvIV(*svp));
+               (void)dbp->set_pagesize(dbp, my_SvUV32(*svp));
            
            svp = hv_fetch(action, "cachesize", 9, FALSE);
           if (svp)
-               (void)dbp->set_cachesize(dbp, 0, SvIV(*svp), 0) ;
+               (void)dbp->set_cachesize(dbp, 0, my_SvUV32(*svp), 0) ;
          
            svp = hv_fetch(action, "lorder", 6, FALSE);
           if (svp)
-               (void)dbp->set_lorder(dbp, SvIV(*svp)) ;
+               (void)dbp->set_lorder(dbp, (int)SvIV(*svp)) ;
 
            PrintHash(info) ; 
         }
@@ -1253,19 +1244,19 @@ SV *   sv ;
 
            svp = hv_fetch(action, "flags", 5, FALSE);
           if (svp)
-              (void)dbp->set_flags(dbp, (u_int32_t)SvIV(*svp)) ;
+              (void)dbp->set_flags(dbp, my_SvUV32(*svp)) ;
    
            svp = hv_fetch(action, "cachesize", 9, FALSE);
           if (svp)
-               (void)dbp->set_cachesize(dbp, 0, SvIV(*svp), 0) ;
+               (void)dbp->set_cachesize(dbp, 0, my_SvUV32(*svp), 0) ;
          
            svp = hv_fetch(action, "psize", 5, FALSE);
           if (svp)
-               (void)dbp->set_pagesize(dbp, SvIV(*svp)) ;
+               (void)dbp->set_pagesize(dbp, my_SvUV32(*svp)) ;
          
            svp = hv_fetch(action, "lorder", 6, FALSE);
           if (svp)
-               (void)dbp->set_lorder(dbp, SvIV(*svp)) ;
+               (void)dbp->set_lorder(dbp, (int)SvIV(*svp)) ;
 
             PrintBtree(info) ;
          
@@ -1291,17 +1282,17 @@ SV *   sv ;
 
            svp = hv_fetch(action, "cachesize", 9, FALSE);
           if (svp) {
-               status = dbp->set_cachesize(dbp, 0, SvIV(*svp), 0) ;
+               status = dbp->set_cachesize(dbp, 0, my_SvUV32(*svp), 0) ;
           }
          
            svp = hv_fetch(action, "psize", 5, FALSE);
           if (svp) {
-               status = dbp->set_pagesize(dbp, SvIV(*svp)) ;
+               status = dbp->set_pagesize(dbp, my_SvUV32(*svp)) ;
            }
          
            svp = hv_fetch(action, "lorder", 6, FALSE);
           if (svp) {
-               status = dbp->set_lorder(dbp, SvIV(*svp)) ;
+               status = dbp->set_lorder(dbp, (int)SvIV(*svp)) ;
           }
 
            svp = hv_fetch(action, "bval", 4, FALSE);
@@ -1311,7 +1302,7 @@ SV *   sv ;
                 if (SvPOK(*svp))
                    value = (int)*SvPV(*svp, n_a) ;
                else
-                   value = SvIV(*svp) ;
+                   value = (int)SvIV(*svp) ;
 
                if (fixed) {
                    status = dbp->set_re_pad(dbp, value) ;
@@ -1325,7 +1316,7 @@ SV *   sv ;
           if (fixed) {
                svp = hv_fetch(action, "reclen", 6, FALSE);
               if (svp) {
-                  u_int32_t len =  (u_int32_t)SvIV(*svp) ;
+                  u_int32_t len =  my_SvUV32(*svp) ;
                    status = dbp->set_re_len(dbp, len) ;
               }    
           }
@@ -1344,10 +1335,10 @@ SV *   sv ;
                name = NULL ;
          
 
-           status = dbp->set_flags(dbp, DB_RENUMBER) ;
+           status = dbp->set_flags(dbp, (u_int32_t)DB_RENUMBER) ;
          
                if (flags){
-                   (void)dbp->set_flags(dbp, flags) ;
+                   (void)dbp->set_flags(dbp, (u_int32_t)flags) ;
                }
             PrintRecno(info) ;
         }
@@ -1356,7 +1347,7 @@ SV *   sv ;
     }
 
     {
-        int            Flags = 0 ;
+        u_int32_t      Flags = 0 ;
         int            status ;
 
         /* Map 1.x flags to 3.x flags */
@@ -1396,246 +1387,15 @@ SV *   sv ;
 } /* ParseOpenInfo */
 
 
-static double 
-#ifdef CAN_PROTOTYPE
-constant(char *name, int arg)
-#else
-constant(name, arg)
-char *name;
-int arg;
-#endif
-{
-    errno = 0;
-    switch (*name) {
-    case 'A':
-       break;
-    case 'B':
-       if (strEQ(name, "BTREEMAGIC"))
-#ifdef BTREEMAGIC
-           return BTREEMAGIC;
-#else
-           goto not_there;
-#endif
-       if (strEQ(name, "BTREEVERSION"))
-#ifdef BTREEVERSION
-           return BTREEVERSION;
-#else
-           goto not_there;
-#endif
-       break;
-    case 'C':
-       break;
-    case 'D':
-       if (strEQ(name, "DB_LOCK"))
-#ifdef DB_LOCK
-           return DB_LOCK;
-#else
-           goto not_there;
-#endif
-       if (strEQ(name, "DB_SHMEM"))
-#ifdef DB_SHMEM
-           return DB_SHMEM;
-#else
-           goto not_there;
-#endif
-       if (strEQ(name, "DB_TXN"))
-#ifdef DB_TXN
-           return (U32)DB_TXN;
-#else
-           goto not_there;
-#endif
-       break;
-    case 'E':
-       break;
-    case 'F':
-       break;
-    case 'G':
-       break;
-    case 'H':
-       if (strEQ(name, "HASHMAGIC"))
-#ifdef HASHMAGIC
-           return HASHMAGIC;
-#else
-           goto not_there;
-#endif
-       if (strEQ(name, "HASHVERSION"))
-#ifdef HASHVERSION
-           return HASHVERSION;
-#else
-           goto not_there;
-#endif
-       break;
-    case 'I':
-       break;
-    case 'J':
-       break;
-    case 'K':
-       break;
-    case 'L':
-       break;
-    case 'M':
-       if (strEQ(name, "MAX_PAGE_NUMBER"))
-#ifdef MAX_PAGE_NUMBER
-           return (U32)MAX_PAGE_NUMBER;
-#else
-           goto not_there;
-#endif
-       if (strEQ(name, "MAX_PAGE_OFFSET"))
-#ifdef MAX_PAGE_OFFSET
-           return MAX_PAGE_OFFSET;
-#else
-           goto not_there;
-#endif
-       if (strEQ(name, "MAX_REC_NUMBER"))
-#ifdef MAX_REC_NUMBER
-           return (U32)MAX_REC_NUMBER;
-#else
-           goto not_there;
-#endif
-       break;
-    case 'N':
-       break;
-    case 'O':
-       break;
-    case 'P':
-       break;
-    case 'Q':
-       break;
-    case 'R':
-       if (strEQ(name, "RET_ERROR"))
-#ifdef RET_ERROR
-           return RET_ERROR;
-#else
-           goto not_there;
-#endif
-       if (strEQ(name, "RET_SPECIAL"))
-#ifdef RET_SPECIAL
-           return RET_SPECIAL;
-#else
-           goto not_there;
-#endif
-       if (strEQ(name, "RET_SUCCESS"))
-#ifdef RET_SUCCESS
-           return RET_SUCCESS;
-#else
-           goto not_there;
-#endif
-       if (strEQ(name, "R_CURSOR"))
-#ifdef R_CURSOR
-           return R_CURSOR;
-#else
-           goto not_there;
-#endif
-       if (strEQ(name, "R_DUP"))
-#ifdef R_DUP
-           return R_DUP;
-#else
-           goto not_there;
-#endif
-       if (strEQ(name, "R_FIRST"))
-#ifdef R_FIRST
-           return R_FIRST;
-#else
-           goto not_there;
-#endif
-       if (strEQ(name, "R_FIXEDLEN"))
-#ifdef R_FIXEDLEN
-           return R_FIXEDLEN;
-#else
-           goto not_there;
-#endif
-       if (strEQ(name, "R_IAFTER"))
-#ifdef R_IAFTER
-           return R_IAFTER;
-#else
-           goto not_there;
-#endif
-       if (strEQ(name, "R_IBEFORE"))
-#ifdef R_IBEFORE
-           return R_IBEFORE;
-#else
-           goto not_there;
-#endif
-       if (strEQ(name, "R_LAST"))
-#ifdef R_LAST
-           return R_LAST;
-#else
-           goto not_there;
-#endif
-       if (strEQ(name, "R_NEXT"))
-#ifdef R_NEXT
-           return R_NEXT;
-#else
-           goto not_there;
-#endif
-       if (strEQ(name, "R_NOKEY"))
-#ifdef R_NOKEY
-           return R_NOKEY;
-#else
-           goto not_there;
-#endif
-       if (strEQ(name, "R_NOOVERWRITE"))
-#ifdef R_NOOVERWRITE
-           return R_NOOVERWRITE;
-#else
-           goto not_there;
-#endif
-       if (strEQ(name, "R_PREV"))
-#ifdef R_PREV
-           return R_PREV;
-#else
-           goto not_there;
-#endif
-       if (strEQ(name, "R_RECNOSYNC"))
-#ifdef R_RECNOSYNC
-           return R_RECNOSYNC;
-#else
-           goto not_there;
-#endif
-       if (strEQ(name, "R_SETCURSOR"))
-#ifdef R_SETCURSOR
-           return R_SETCURSOR;
-#else
-           goto not_there;
-#endif
-       if (strEQ(name, "R_SNAPSHOT"))
-#ifdef R_SNAPSHOT
-           return R_SNAPSHOT;
-#else
-           goto not_there;
-#endif
-       break;
-    case 'S':
-       break;
-    case 'T':
-       break;
-    case 'U':
-       break;
-    case 'V':
-       break;
-    case 'W':
-       break;
-    case 'X':
-       break;
-    case 'Y':
-       break;
-    case 'Z':
-       break;
-    case '_':
-       break;
-    }
-    errno = EINVAL;
-    return 0;
-
-not_there:
-    errno = ENOENT;
-    return 0;
-}
+#include "constants.h"   
 
 MODULE = DB_File       PACKAGE = DB_File       PREFIX = db_
 
+INCLUDE: constants.xs
+
 BOOT:
   {
+    MY_CXT_INIT;
     __getBerkeleyDBInfo() ;
  
     DBT_clear(empty) ; 
@@ -1643,10 +1403,6 @@ BOOT:
     empty.size =  sizeof(recno_t) ;
   }
 
-double
-constant(name,arg)
-       char *          name
-       int             arg
 
 
 DB_File
@@ -1677,6 +1433,8 @@ db_DoTie_(isHASH, dbtype, name=undef, flags=O_CREAT|O_RDWR, mode=0666, type=DB_H
 int
 db_DESTROY(db)
        DB_File         db
+       PREINIT:
+         dMY_CXT;
        INIT:
          CurrentDB = db ;
        CLEANUP:
@@ -1708,6 +1466,8 @@ db_DELETE(db, key, flags=0)
        DB_File         db
        DBTKEY          key
        u_int           flags
+       PREINIT:
+         dMY_CXT;
        INIT:
          CurrentDB = db ;
 
@@ -1716,6 +1476,8 @@ int
 db_EXISTS(db, key)
        DB_File         db
        DBTKEY          key
+       PREINIT:
+         dMY_CXT;
        CODE:
        {
           DBT          value ;
@@ -1733,7 +1495,8 @@ db_FETCH(db, key, flags=0)
        DBTKEY          key
        u_int           flags
        PREINIT:
-       int RETVAL;
+         dMY_CXT ;
+         int RETVAL ;
        CODE:
        {
             DBT                value ;
@@ -1752,6 +1515,8 @@ db_STORE(db, key, value, flags=0)
        DBTKEY          key
        DBT             value
        u_int           flags
+       PREINIT:
+         dMY_CXT;
        INIT:
          CurrentDB = db ;
 
@@ -1760,7 +1525,8 @@ void
 db_FIRSTKEY(db)
        DB_File         db
        PREINIT:
-       int RETVAL;
+         dMY_CXT ;
+         int RETVAL ;
        CODE:
        {
            DBTKEY      key ;
@@ -1777,13 +1543,15 @@ db_FIRSTKEY(db)
 void
 db_NEXTKEY(db, key)
        DB_File         db
-       DBTKEY          key
+       DBTKEY          key = NO_INIT
        PREINIT:
-       int RETVAL;
+         dMY_CXT ;
+         int RETVAL ;
        CODE:
        {
            DBT         value ;
 
+           DBT_clear(key) ; 
            DBT_clear(value) ; 
            CurrentDB = db ;
            RETVAL = do_SEQ(db, key, value, R_NEXT) ;
@@ -1799,6 +1567,8 @@ int
 unshift(db, ...)
        DB_File         db
        ALIAS:          UNSHIFT = 1
+       PREINIT:
+         dMY_CXT;
        CODE:
        {
            DBTKEY      key ;
@@ -1839,9 +1609,11 @@ unshift(db, ...)
 void
 pop(db)
        DB_File         db
+       PREINIT:
+         dMY_CXT;
        ALIAS:          POP = 1
        PREINIT:
-       I32 RETVAL;
+         I32 RETVAL;
        CODE:
        {
            DBTKEY      key ;
@@ -1868,9 +1640,11 @@ pop(db)
 void
 shift(db)
        DB_File         db
+       PREINIT:
+         dMY_CXT;
        ALIAS:          SHIFT = 1
        PREINIT:
-       I32 RETVAL;
+         I32 RETVAL;
        CODE:
        {
            DBT         value ;
@@ -1897,6 +1671,8 @@ shift(db)
 I32
 push(db, ...)
        DB_File         db
+       PREINIT:
+         dMY_CXT;
        ALIAS:          PUSH = 1
        CODE:
        {
@@ -1939,6 +1715,8 @@ push(db, ...)
 I32
 length(db)
        DB_File         db
+       PREINIT:
+         dMY_CXT;
        ALIAS:          FETCHSIZE = 1
        CODE:
            CurrentDB = db ;
@@ -1956,6 +1734,8 @@ db_del(db, key, flags=0)
        DB_File         db
        DBTKEY          key
        u_int           flags
+       PREINIT:
+         dMY_CXT;
        CODE:
          CurrentDB = db ;
          RETVAL = db_del(db, key, flags) ;
@@ -1975,6 +1755,8 @@ db_get(db, key, value, flags=0)
        DBTKEY          key
        DBT             value = NO_INIT
        u_int           flags
+       PREINIT:
+         dMY_CXT;
        CODE:
          CurrentDB = db ;
          DBT_clear(value) ; 
@@ -1995,6 +1777,8 @@ db_put(db, key, value, flags=0)
        DBTKEY          key
        DBT             value
        u_int           flags
+       PREINIT:
+         dMY_CXT;
        CODE:
          CurrentDB = db ;
          RETVAL = db_put(db, key, value, flags) ;
@@ -2011,6 +1795,8 @@ db_put(db, key, value, flags=0)
 int
 db_fd(db)
        DB_File         db
+       PREINIT:
+         dMY_CXT ;
        CODE:
          CurrentDB = db ;
 #ifdef DB_VERSION_MAJOR
@@ -2035,6 +1821,8 @@ int
 db_sync(db, flags=0)
        DB_File         db
        u_int           flags
+       PREINIT:
+         dMY_CXT;
        CODE:
          CurrentDB = db ;
          RETVAL = db_sync(db, flags) ;
@@ -2052,6 +1840,8 @@ db_seq(db, key, value, flags)
        DBTKEY          key 
        DBT             value = NO_INIT
        u_int           flags
+       PREINIT:
+         dMY_CXT;
        CODE:
          CurrentDB = db ;
          DBT_clear(value) ;