This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
[perl #46947] Parse method-BLOCK arguments as a term
[perl5.git] / ext / GDBM_File / GDBM_File.xs
index 808850d..33e08e2 100644 (file)
@@ -1,3 +1,5 @@
+#define PERL_NO_GET_CONTEXT
+
 #include "EXTERN.h"
 #include "perl.h"
 #include "XSUB.h"
@@ -5,41 +7,51 @@
 #include <gdbm.h>
 #include <fcntl.h>
 
-typedef GDBM_FILE GDBM_File;
+#define fetch_key 0
+#define store_key 1
+#define fetch_value 2
+#define store_value 3
 
-#define GDBM_BLOCKSIZE 0 /* gdbm defaults to stat blocksize */
-#define gdbm_TIEHASH(dbtype, name, read_write, mode, fatal_func) \
-       gdbm_open(name, GDBM_BLOCKSIZE, read_write, mode, fatal_func)
+typedef struct {
+       GDBM_FILE       dbp ;
+       SV *    filter[4];
+       int     filtering ;
+       } GDBM_File_type;
 
-#define gdbm_FETCH(db,key)                     gdbm_fetch(db,key)
-#define gdbm_STORE(db,key,value,flags)         gdbm_store(db,key,value,flags)
-#define gdbm_DELETE(db,key)                    gdbm_delete(db,key)
-#define gdbm_FIRSTKEY(db)                      gdbm_firstkey(db)
-#define gdbm_NEXTKEY(db,key)                   gdbm_nextkey(db,key)
-#define gdbm_EXISTS(db,key)                    gdbm_exists(db,key)
+typedef GDBM_File_type * GDBM_File ;
+typedef datum datum_key ;
+typedef datum datum_value ;
+typedef datum datum_key_copy;
 
+#define GDBM_BLOCKSIZE 0 /* gdbm defaults to stat blocksize */
+
+#if defined(GDBM_VERSION_MAJOR) && defined(GDBM_VERSION_MINOR) \
+    && GDBM_VERSION_MAJOR > 1 || \
+    (GDBM_VERSION_MAJOR == 1 && GDBM_VERSION_MINOR >= 9)
+typedef void (*FATALFUNC)(const char *);
+#else
 typedef void (*FATALFUNC)();
+#endif
 
+#ifndef GDBM_FAST
 static int
 not_here(char *s)
 {
     croak("GDBM_File::%s not implemented on this architecture", s);
     return -1;
 }
+#endif
 
 /* GDBM allocates the datum with system malloc() and expects the user
  * to free() it.  So we either have to free() it immediately, or have
  * perl free() it when it deallocates the SV, depending on whether
  * perl uses malloc()/free() or not. */
 static void
-output_datum(SV *arg, char *str, int size)
+output_datum(pTHX_ SV *arg, char *str, int size)
 {
-#if !defined(MYMALLOC) || (defined(MYMALLOC) && defined(PERL_POLLUTE_MALLOC))
-       sv_usepvn(arg, str, size);
-#else
        sv_setpvn(arg, str, size);
-       safesysfree(str);
-#endif
+#      undef free
+       free(str);
 }
 
 /* Versions of gdbm prior to 1.7x might not have the gdbm_sync,
@@ -52,142 +64,40 @@ output_datum(SV *arg, char *str, int size)
 #define gdbm_setopt(db,optflag,optval,optlen) not_here("gdbm_setopt")
 #endif
 
-static double
-constant(char *name, int arg)
-{
-    errno = 0;
-    switch (*name) {
-    case 'A':
-       break;
-    case 'B':
-       break;
-    case 'C':
-       break;
-    case 'D':
-       break;
-    case 'E':
-       break;
-    case 'F':
-       break;
-    case 'G':
-       if (strEQ(name, "GDBM_CACHESIZE"))
-#ifdef GDBM_CACHESIZE
-           return GDBM_CACHESIZE;
-#else
-           goto not_there;
-#endif
-       if (strEQ(name, "GDBM_FAST"))
-#ifdef GDBM_FAST
-           return GDBM_FAST;
-#else
-           goto not_there;
-#endif
-       if (strEQ(name, "GDBM_FASTMODE"))
-#ifdef GDBM_FASTMODE
-           return GDBM_FASTMODE;
-#else
-           goto not_there;
-#endif
-       if (strEQ(name, "GDBM_INSERT"))
-#ifdef GDBM_INSERT
-           return GDBM_INSERT;
-#else
-           goto not_there;
-#endif
-       if (strEQ(name, "GDBM_NEWDB"))
-#ifdef GDBM_NEWDB
-           return GDBM_NEWDB;
-#else
-           goto not_there;
-#endif
-       if (strEQ(name, "GDBM_READER"))
-#ifdef GDBM_READER
-           return GDBM_READER;
-#else
-           goto not_there;
-#endif
-       if (strEQ(name, "GDBM_REPLACE"))
-#ifdef GDBM_REPLACE
-           return GDBM_REPLACE;
-#else
-           goto not_there;
-#endif
-       if (strEQ(name, "GDBM_WRCREAT"))
-#ifdef GDBM_WRCREAT
-           return GDBM_WRCREAT;
-#else
-           goto not_there;
-#endif
-       if (strEQ(name, "GDBM_WRITER"))
-#ifdef GDBM_WRITER
-           return GDBM_WRITER;
-#else
-           goto not_there;
-#endif
-       break;
-    case 'H':
-       break;
-    case 'I':
-       break;
-    case 'J':
-       break;
-    case 'K':
-       break;
-    case 'L':
-       break;
-    case 'M':
-       break;
-    case 'N':
-       break;
-    case 'O':
-       break;
-    case 'P':
-       break;
-    case 'Q':
-       break;
-    case 'R':
-       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;
-    }
-    errno = EINVAL;
-    return 0;
-
-not_there:
-    errno = ENOENT;
-    return 0;
+static void
+croak_string(const char *message) {
+    Perl_croak_nocontext("%s", message);
 }
 
-MODULE = GDBM_File     PACKAGE = GDBM_File     PREFIX = gdbm_
+#include "const-c.inc"
 
-double
-constant(name,arg)
-       char *          name
-       int             arg
+MODULE = GDBM_File     PACKAGE = GDBM_File     PREFIX = gdbm_
 
+INCLUDE: const-xs.inc
 
 GDBM_File
-gdbm_TIEHASH(dbtype, name, read_write, mode, fatal_func = (FATALFUNC)croak)
+gdbm_TIEHASH(dbtype, name, read_write, mode)
        char *          dbtype
        char *          name
        int             read_write
        int             mode
-       FATALFUNC       fatal_func
+       CODE:
+       {
+           GDBM_FILE   dbp ;
+
+           RETVAL = NULL ;
+           if ((dbp =  gdbm_open(name, GDBM_BLOCKSIZE, read_write, mode,
+                                 (FATALFUNC) croak_string))) {
+               RETVAL = (GDBM_File)safecalloc(1, sizeof(GDBM_File_type)) ;
+               RETVAL->dbp = dbp ;
+           }
+           
+       }
+       OUTPUT:
+         RETVAL
+       
 
+#define gdbm_close(db)                 gdbm_close(db->dbp)
 void
 gdbm_close(db)
        GDBM_File       db
@@ -196,19 +106,28 @@ gdbm_close(db)
 void
 gdbm_DESTROY(db)
        GDBM_File       db
+       PREINIT:
+       int i = store_value;
        CODE:
        gdbm_close(db);
-
-datum
+       do {
+           if (db->filter[i])
+               SvREFCNT_dec(db->filter[i]);
+       } while (i-- > 0);
+       safefree(db);
+
+#define gdbm_FETCH(db,key)                     gdbm_fetch(db->dbp,key)
+datum_value
 gdbm_FETCH(db, key)
        GDBM_File       db
-       datum           key
+       datum_key_copy  key
 
+#define gdbm_STORE(db,key,value,flags)         gdbm_store(db->dbp,key,value,flags)
 int
 gdbm_STORE(db, key, value, flags = GDBM_REPLACE)
        GDBM_File       db
-       datum           key
-       datum           value
+       datum_key       key
+       datum_value     value
        int             flags
     CLEANUP:
        if (RETVAL) {
@@ -216,37 +135,43 @@ gdbm_STORE(db, key, value, flags = GDBM_REPLACE)
                croak("No write permission to gdbm file");
            croak("gdbm store returned %d, errno %d, key \"%.*s\"",
                        RETVAL,errno,key.dsize,key.dptr);
-           /* gdbm_clearerr(db); */
        }
 
+#define gdbm_DELETE(db,key)                    gdbm_delete(db->dbp,key)
 int
 gdbm_DELETE(db, key)
        GDBM_File       db
-       datum           key
+       datum_key       key
 
-datum
+#define gdbm_FIRSTKEY(db)                      gdbm_firstkey(db->dbp)
+datum_key
 gdbm_FIRSTKEY(db)
        GDBM_File       db
 
-datum
+#define gdbm_NEXTKEY(db,key)                   gdbm_nextkey(db->dbp,key)
+datum_key
 gdbm_NEXTKEY(db, key)
        GDBM_File       db
-       datum           key
+       datum_key       key 
 
+#define gdbm_reorganize(db)                    gdbm_reorganize(db->dbp)
 int
 gdbm_reorganize(db)
        GDBM_File       db
 
 
+#define gdbm_sync(db)                          gdbm_sync(db->dbp)
 void
 gdbm_sync(db)
        GDBM_File       db
 
+#define gdbm_EXISTS(db,key)                    gdbm_exists(db->dbp,key)
 int
 gdbm_EXISTS(db, key)
        GDBM_File       db
-       datum           key
+       datum_key       key
 
+#define gdbm_setopt(db,optflag, optval, optlen)        gdbm_setopt(db->dbp,optflag, optval, optlen)
 int
 gdbm_setopt (db, optflag, optval, optlen)
        GDBM_File       db
@@ -254,3 +179,16 @@ gdbm_setopt (db, optflag, optval, optlen)
        int             &optval
        int             optlen
 
+
+SV *
+filter_fetch_key(db, code)
+       GDBM_File       db
+       SV *            code
+       SV *            RETVAL = &PL_sv_undef ;
+       ALIAS:
+       GDBM_File::filter_fetch_key = fetch_key
+       GDBM_File::filter_store_key = store_key
+       GDBM_File::filter_fetch_value = fetch_value
+       GDBM_File::filter_store_value = store_value
+       CODE:
+           DBM_setFilter(db->filter[ix], code);