/* This file is part of the Q programming system.
The Q programming system is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
The Q programming system is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#if defined (HAVE_CONFIG_H)
# include "config.h"
#endif
/* system headers */
#include <stdio.h>
#include <ctype.h>
/* check for standard C headers */
#if STDC_HEADERS
# include <stdlib.h>
# include <string.h>
#else
# ifndef HAVE_STRCHR
# define strchr index
# define strrchr rindex
# endif
char *strchr (), *strrchr ();
#endif
#ifdef HAVE_MALLOC_H
#include <stdlib.h>
#endif
#ifdef HAVE_LIMITS_H
#include <limits.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef WIN32
#define __GDBM_IMPORT__ 1
#endif
#include <gdbm.h>
#include <libq.h>
#ifdef DMALLOC
#include <dmalloc.h>
#endif
MODULE(gdbm)
#ifndef HAVE_STRDUP
static char *strdup(char *s)
{
char *t;
return ((t=malloc(strlen(s)+1))?strcpy(t, s):NULL);
}
#endif
/* ByteStr data structure, see clib.c */
typedef struct bstr {
long size;
unsigned char *v;
} bstr_t;
FUNCTION(gdbm,gdbm_vars,argc,argv)
{
if (argc != 0) return __FAIL;
return mktuplel
(9,
mkint(GDBM_READER),
mkint(GDBM_WRITER),
mkint(GDBM_WRCREAT),
mkint(GDBM_NEWDB),
mkint(GDBM_FAST),
mkint(GDBM_SYNC),
mkint(GDBM_NOLOCK),
mkint(GDBM_INSERT),
mkint(GDBM_REPLACE));
}
DESTRUCTOR(gdbm,GdbmFile,ptr)
{
GDBM_FILE *dbf = (GDBM_FILE*)ptr;
if (*dbf) gdbm_close(*dbf);
free(dbf);
}
FUNCTION(gdbm,gdbm_version,argc,argv)
{
if (argc == 0)
return mkstr(strdup(gdbm_version));
else
return __FAIL;
}
FUNCTION(gdbm,gdbm_errno,argc,argv)
{
if (argc == 0)
return mkint(gdbm_errno);
else
return __FAIL;
}
FUNCTION(gdbm,gdbm_seterrno,argc,argv)
{
long n;
if (argc == 1 && isint(argv[0], &n)) {
gdbm_errno = (int)n;
return mkvoid;
} else
return __FAIL;
}
FUNCTION(gdbm,gdbm_strerror,argc,argv)
{
long n;
char *s;
if (argc == 1 && isint(argv[0], &n) &&
(s = gdbm_strerror((int)n)))
return mkstr(strdup(s));
else
return __FAIL;
}
FUNCTION(gdbm,gdbm_open,argc,argv)
{
char *name;
long block_size, flags, mode;
if (argc == 4 && isstr(argv[0], &name) &&
isint(argv[1], &block_size) && isint(argv[2], &flags) &&
isint(argv[3], &mode)) {
GDBM_FILE *dbf;
if (!(dbf = malloc(sizeof(GDBM_FILE))))
return __ERROR;
else if ((*dbf = gdbm_open(name, (int)block_size, (int)flags, (int)mode,
NULL)))
return mkobj(type(GdbmFile), dbf);
else {
free(dbf);
return __FAIL;
}
} else
return __FAIL;
}
FUNCTION(gdbm,gdbm_close,argc,argv)
{
GDBM_FILE *dbf;
if (argc == 1 && isobj(argv[0], type(GdbmFile), (void**)&dbf) && *dbf) {
gdbm_close(*dbf);
*dbf = NULL;
return mkvoid;
} else
return __FAIL;
}
FUNCTION(gdbm,gdbm_fdesc,argc,argv)
{
GDBM_FILE *dbf;
if (argc == 1 && isobj(argv[0], type(GdbmFile), (void**)&dbf) && *dbf)
return mkint(gdbm_fdesc(*dbf));
else
return __FAIL;
}
static char dummy_data[1];
#define gdbm_data(v) ((v)?((char*)v):dummy_data)
FUNCTION(gdbm,gdbm_store,argc,argv)
{
GDBM_FILE *dbf;
bstr_t *mk, *md;
long flag;
if (argc == 4 && isobj(argv[0], type(GdbmFile), (void**)&dbf) && *dbf &&
isobj(argv[1], type(ByteStr), (void**)&mk) &&
isobj(argv[2], type(ByteStr), (void**)&md) &&
isint(argv[3], &flag)) {
datum key, data;
key.dsize = (int)mk->size;
key.dptr = gdbm_data(mk->v);
data.dsize = (int)md->size;
data.dptr = gdbm_data(md->v);
if (!gdbm_store(*dbf, key, data, (int)flag))
return mkvoid;
else
return __FAIL;
} else
return __FAIL;
}
FUNCTION(gdbm,gdbm_delete,argc,argv)
{
GDBM_FILE *dbf;
bstr_t *m;
if (argc == 2 && isobj(argv[0], type(GdbmFile), (void**)&dbf) && *dbf &&
isobj(argv[1], type(ByteStr), (void**)&m)) {
datum key;
key.dsize = (int)m->size;
key.dptr = gdbm_data(m->v);
if (!gdbm_delete(*dbf, key))
return mkvoid;
else
return __FAIL;
} else
return __FAIL;
}
FUNCTION(gdbm,gdbm_fetch,argc,argv)
{
GDBM_FILE *dbf;
bstr_t *m;
if (argc == 2 && isobj(argv[0], type(GdbmFile), (void**)&dbf) && *dbf &&
isobj(argv[1], type(ByteStr), (void**)&m)) {
datum key, data;
key.dsize = (int)m->size;
key.dptr = gdbm_data(m->v);
data = gdbm_fetch(*dbf, key);
if (data.dptr) {
if (!(m = malloc(sizeof(bstr_t)))) {
free(data.dptr);
return __ERROR;
}
m->size = (long)data.dsize;
if (data.dsize > 0)
m->v = (unsigned char*)data.dptr;
else {
free(data.dptr);
m->v = NULL;
}
return mkobj(type(ByteStr), m);
} else
return __FAIL;
} else
return __FAIL;
}
FUNCTION(gdbm,gdbm_exists,argc,argv)
{
GDBM_FILE *dbf;
bstr_t *m;
if (argc == 2 && isobj(argv[0], type(GdbmFile), (void**)&dbf) && *dbf &&
isobj(argv[1], type(ByteStr), (void**)&m)) {
datum key;
key.dsize = (int)m->size;
key.dptr = gdbm_data(m->v);
if (gdbm_exists(*dbf, key))
return mktrue;
else
return mkfalse;
} else
return __FAIL;
}
FUNCTION(gdbm,gdbm_firstkey,argc,argv)
{
GDBM_FILE *dbf;
bstr_t *m;
if (argc == 1 && isobj(argv[0], type(GdbmFile), (void**)&dbf) && *dbf) {
datum key;
key = gdbm_firstkey(*dbf);
if (key.dptr) {
if (!(m = malloc(sizeof(bstr_t)))) {
free(key.dptr);
return __ERROR;
}
m->size = (long)key.dsize;
if (key.dsize > 0)
m->v = (unsigned char*)key.dptr;
else {
free(key.dptr);
m->v = NULL;
}
return mkobj(type(ByteStr), m);
} else
return __FAIL;
} else
return __FAIL;
}
FUNCTION(gdbm,gdbm_nextkey,argc,argv)
{
GDBM_FILE *dbf;
bstr_t *m;
if (argc == 2 && isobj(argv[0], type(GdbmFile), (void**)&dbf) && *dbf &&
isobj(argv[1], type(ByteStr), (void**)&m)) {
datum key;
key.dsize = (int)m->size;
key.dptr = gdbm_data(m->v);
key = gdbm_nextkey(*dbf, key);
if (key.dptr) {
if (!(m = malloc(sizeof(bstr_t)))) {
free(key.dptr);
return __ERROR;
}
m->size = (long)key.dsize;
if (key.dsize > 0)
m->v = (unsigned char*)key.dptr;
else {
free(key.dptr);
m->v = NULL;
}
return mkobj(type(ByteStr), m);
} else
return __FAIL;
} else
return __FAIL;
}
FUNCTION(gdbm,gdbm_sync,argc,argv)
{
GDBM_FILE *dbf;
if (argc == 1 && isobj(argv[0], type(GdbmFile), (void**)&dbf) && *dbf) {
gdbm_sync(*dbf);
return mkvoid;
} else
return __FAIL;
}
FUNCTION(gdbm,gdbm_reorganize,argc,argv)
{
GDBM_FILE *dbf;
if (argc == 1 && isobj(argv[0], type(GdbmFile), (void**)&dbf) && *dbf &&
!gdbm_reorganize(*dbf))
return mkvoid;
else
return __FAIL;
}
syntax highlighted by Code2HTML, v. 0.9.1