Branch: Tag:

1997-02-11

1997-02-11 08:08:54 by Fredrik Hübinette (Hubbe) <hubbe@hubbe.net>

files moved for new module system

Rev: src/modules/Gdbm/.cvsignore:1.1
Rev: src/modules/Gdbm/Makefile.in:1.1
Rev: src/modules/Gdbm/configure.in:1.1
Rev: src/modules/Gdbm/doc/gdbm:1.1
Rev: src/modules/Gdbm/gdbm_machine.h.in:1.1
Rev: src/modules/Gdbm/gdbmmod.c:1.1
Rev: src/modules/Gdbm/testsuite.in:1.1
Rev: src/modules/Gmp/.cvsignore:1.1
Rev: src/modules/Gmp/Makefile.in:1.1
Rev: src/modules/Gmp/configure.in:1.1
Rev: src/modules/Gmp/doc/mpz:1.1
Rev: src/modules/Gmp/gmp_machine.h.in:1.1
Rev: src/modules/Gmp/mpz_glue.c:1.1
Rev: src/modules/Gmp/testsuite.in:1.1

1: + /*\ + ||| This file a part of Pike, and is copyright by Fredrik Hubinette + ||| Pike is distributed as GPL (General Public License) + ||| See the files COPYING and DISCLAIMER for more information. + \*/ + #include "global.h" + RCSID("$Id: gdbmmod.c,v 1.1 1997/02/11 08:00:50 hubbe Exp $"); + #include "gdbm_machine.h" + #include "types.h" + #include "threads.h"    -  + /* Todo: make sure only one thread accesses the same gdbmmod */ +  + #if defined(HAVE_GDBM_H) && defined(HAVE_LIBGDBM) +  + #include "interpret.h" + #include "svalue.h" + #include "stralloc.h" + #include "array.h" + #include "object.h" + #include "macros.h" +  + #include <gdbm.h> +  + #ifdef _REENTRANT + static MUTEX_T gdbm_lock; + #endif +  + struct gdbm_glue + { +  GDBM_FILE dbf; + }; +  + #define THIS ((struct gdbm_glue *)(fp->current_storage)) +  + static void do_free() + { +  if(THIS->dbf) +  { +  GDBM_FILE dbf; +  dbf=THIS->dbf; +  THIS->dbf=0; +  +  THREADS_ALLOW(); +  mt_lock(& gdbm_lock); +  gdbm_close(dbf); +  mt_unlock(& gdbm_lock); +  THREADS_DISALLOW(); +  } + } +  + static int fixmods(char *mods) + { +  int mode; +  mode=0; +  while(1) +  { +  switch(*(mods++)) +  { +  case 0: +  switch(mode & 15) +  { +  default: error("No mode given for gdbm->open()\n"); +  case 1|16: +  case 1: mode=GDBM_READER; break; +  case 3: mode=GDBM_WRITER; break; +  case 3|16: mode=GDBM_WRITER | GDBM_FAST; break; +  case 7: mode=GDBM_WRCREAT; break; +  case 7|16: mode=GDBM_WRCREAT | GDBM_FAST; break; +  case 15: mode=GDBM_NEWDB; break; +  case 15|16: mode=GDBM_NEWDB | GDBM_FAST; break; +  } +  return mode; +  +  case 'r': case 'R': mode|=1; break; +  case 'w': case 'W': mode|=3; break; +  case 'c': case 'C': mode|=7; break; +  case 't': case 'T': mode|=15; break; +  case 'f': case 'F': mode|=16; break; +  +  default: +  error("Bad mode flag in gdbm->open.\n"); +  } +  } + } +  + void gdbmmod_fatal(char *err) + { +  error("GDBM: %s\n",err); + } +  + static void gdbmmod_create(INT32 args) + { +  struct gdbm_glue *this=THIS; +  do_free(); +  if(args) +  { +  GDBM_FILE tmp; +  struct pike_string *tmp2; +  int rwmode = GDBM_WRCREAT; +  +  if(sp[-args].type != T_STRING) +  error("Bad argument 1 to gdbm->create()\n"); +  +  if(args>1) +  { +  if(sp[1-args].type != T_STRING) +  error("Bad argument 2 to gdbm->create()\n"); +  +  rwmode=fixmods(sp[1-args].u.string->str); +  } +  +  tmp2=sp[-args].u.string; +  +  THREADS_ALLOW(); +  mt_lock(& gdbm_lock); +  tmp=gdbm_open(tmp2->str, 512, rwmode, 00666, gdbmmod_fatal); +  mt_unlock(& gdbm_lock); +  THREADS_DISALLOW(); +  +  if(!fp->current_object->prog) +  { +  if(tmp) gdbm_close(tmp); +  error("Object destructed in gdbm->open()n"); +  } +  THIS->dbf=tmp; +  +  pop_n_elems(args); +  if(!THIS->dbf) +  error("Failed to open GDBM database.\n"); +  } + } +  + #define STRING_TO_DATUM(dat, st) dat.dptr=st->str,dat.dsize=st->len; + #define DATUM_TO_STRING(dat) make_shared_binary_string(dat.dptr, dat.dsize) +  + static void gdbmmod_fetch(INT32 args) + { +  struct gdbm_glue *this=THIS; +  datum key,ret; +  +  if(!args) +  error("Too few arguments to gdbm->fetch()\n"); +  +  if(sp[-args].type != T_STRING) +  error("Bad argument 1 to gdbm->fetch()\n"); +  +  if(!THIS->dbf) +  error("GDBM database not open.\n"); +  +  STRING_TO_DATUM(key, sp[-args].u.string); +  +  THREADS_ALLOW(); +  mt_lock(& gdbm_lock); +  ret=gdbm_fetch(this->dbf, key); +  mt_unlock(& gdbm_lock); +  THREADS_DISALLOW(); +  +  pop_n_elems(args); +  if(ret.dptr) +  { +  push_string(DATUM_TO_STRING(ret)); +  free(ret.dptr); +  }else{ +  push_int(0); +  } + } +  + static void gdbmmod_delete(INT32 args) + { +  struct gdbm_glue *this=THIS; +  datum key; +  int ret; +  if(!args) +  error("Too few arguments to gdbm->delete()\n"); +  +  if(sp[-args].type != T_STRING) +  error("Bad argument 1 to gdbm->delete()\n"); +  +  if(!this->dbf) +  error("GDBM database not open.\n"); +  +  STRING_TO_DATUM(key, sp[-args].u.string); +  +  THREADS_ALLOW(); +  mt_lock(& gdbm_lock); +  ret=gdbm_delete(this->dbf, key); +  mt_unlock(& gdbm_lock); +  THREADS_DISALLOW(); +  +  pop_n_elems(args); +  push_int(0); + } +  + static void gdbmmod_firstkey(INT32 args) + { +  struct gdbm_glue *this=THIS; +  datum ret; +  pop_n_elems(args); +  +  if(!this->dbf) error("GDBM database not open.\n"); +  +  THREADS_ALLOW(); +  mt_lock(& gdbm_lock); +  ret=gdbm_firstkey(this->dbf); +  mt_unlock(& gdbm_lock); +  THREADS_DISALLOW(); +  +  if(ret.dptr) +  { +  push_string(DATUM_TO_STRING(ret)); +  free(ret.dptr); +  }else{ +  push_int(0); +  } + } +  + static void gdbmmod_nextkey(INT32 args) + { +  struct gdbm_glue *this=THIS; +  datum key,ret; +  if(!args) +  error("Too few arguments to gdbm->nextkey()\n"); +  +  if(sp[-args].type != T_STRING) +  error("Bad argument 1 to gdbm->nextkey()\n"); +  +  if(!THIS->dbf) +  error("GDBM database not open.\n"); +  +  STRING_TO_DATUM(key, sp[-args].u.string); +  +  THREADS_ALLOW(); +  mt_lock(& gdbm_lock); +  ret=gdbm_nextkey(this->dbf, key); +  mt_unlock(& gdbm_lock); +  THREADS_DISALLOW(); +  +  pop_n_elems(args); +  if(ret.dptr) +  { +  push_string(DATUM_TO_STRING(ret)); +  free(ret.dptr); +  }else{ +  push_int(0); +  } + } +  + static void gdbmmod_store(INT32 args) + { +  struct gdbm_glue *this=THIS; +  datum key,data; +  int ret; +  if(args<2) +  error("Too few arguments to gdbm->store()\n"); +  +  if(sp[-args].type != T_STRING) +  error("Bad argument 1 to gdbm->store()\n"); +  +  if(sp[1-args].type != T_STRING) +  error("Bad argument 2 to gdbm->store()\n"); +  +  if(!THIS->dbf) +  error("GDBM database not open.\n"); +  +  STRING_TO_DATUM(key, sp[-args].u.string); +  STRING_TO_DATUM(data, sp[1-args].u.string); +  +  THREADS_ALLOW(); +  mt_lock(& gdbm_lock); +  ret=gdbm_store(this->dbf, key, data, GDBM_REPLACE); +  mt_unlock(& gdbm_lock); +  THREADS_DISALLOW(); +  +  if(ret == -1) +  error("GDBM database not open for writing.\n"); +  +  pop_n_elems(args); +  push_int(ret == 0); + } +  + static void gdbmmod_reorganize(INT32 args) + { +  struct gdbm_glue *this=THIS; +  int ret; +  pop_n_elems(args); +  +  if(!THIS->dbf) error("GDBM database not open.\n"); +  THREADS_ALLOW(); +  mt_lock(& gdbm_lock); +  ret=gdbm_reorganize(this->dbf); +  mt_unlock(& gdbm_lock); +  THREADS_DISALLOW(); +  pop_n_elems(args); +  push_int(ret); + } +  + static void gdbmmod_sync(INT32 args) + { +  struct gdbm_glue *this=THIS; +  pop_n_elems(args); +  +  if(!THIS->dbf) error("GDBM database not open.\n"); +  THREADS_ALLOW(); +  mt_lock(& gdbm_lock); +  gdbm_sync(this->dbf); +  mt_unlock(& gdbm_lock); +  THREADS_DISALLOW(); +  push_int(0); + } +  + static void gdbmmod_close(INT32 args) + { +  pop_n_elems(args); +  +  do_free(THIS->dbf); +  push_int(0); + } +  + static void init_gdbm_glue(struct object *o) + { +  THIS->dbf=0; + } +  + static void exit_gdbm_glue(struct object *o) + { +  do_free(); + } +  + #endif +  + void pike_module_exit(void) {} +  + void pike_module_init(void) + { + #if defined(HAVE_GDBM_H) && defined(HAVE_LIBGDBM) +  start_new_program(); +  add_storage(sizeof(struct gdbm_glue)); +  +  add_function("create",gdbmmod_create,"function(void|string,void|string:void)",0); +  +  add_function("close",gdbmmod_close,"function(:void)",0); +  add_function("store",gdbmmod_store,"function(string,string:int)",0); +  add_function("`[]=",gdbmmod_store,"function(string,string:int)",0); +  add_function("fetch",gdbmmod_fetch,"function(string:string)",0); +  add_function("`[]",gdbmmod_fetch,"function(string:string)",0); +  add_function("delete",gdbmmod_delete,"function(string:int)",0); +  add_function("firstkey",gdbmmod_firstkey,"function(:string)",0); +  add_function("nextkey",gdbmmod_nextkey,"function(string:string)",0); +  add_function("reorganize",gdbmmod_reorganize,"function(:int)",0); +  add_function("sync",gdbmmod_sync,"function(:void)",0); +  +  set_init_callback(init_gdbm_glue); +  set_exit_callback(exit_gdbm_glue); +  end_class("gdbm",0); + #endif + } +    Newline at end of file added.