Subject: gdbm GNU library.

From: Oscar Alejandro Ferrer Bernal <[email-masked]>
Date: Mon, 14 Jun 1999 02:46:49 +0100

I am having problems loading a Win32 DLL on SWI-Prolog 3.2.6:

        The problem is using the gdbm GNU library.

         When I use the gdbm_open (the function to open the database
file)function, the value returned
by that is NULL, then, the function cannot open the file.
        I originally wrote the program in a Unix system where the
program ran well,
but rewriting the program to a Win32 system I had these problem.

        The path of the file to be opened is right, could be the memory
management done by the GDBM.lib?

        I have used Visual C++ 5.0 to compile it and a GDBM library for
win32

The code of the predicates are:

#include "SWI-Prolog.h"
#include <stdlib.h>
#include <string.h>
#include "gdbm.h"   /* Headers of the gdbm.lib */
#include "compjuga.h"

#define BASE_PATH "c:\\nombres.dat"      /* the path is rigth */
#define BASEV_PATH "Verbos2.dat"

/* Definición del predicado que buscará un nombre en la base de
   datos devolverá verdadero si lo encuantra y además las Variables
   genero,numero instanciadas a su valor correspondiente si fuese
   necesario*/
foreign_t
pl_nombre(term_t nombre,term_t genero,term_t numero)
{
  GDBM_FILE fichero;   /* Fichero de la base de datos*/
  datum key1,data;
  char *n,*g,num[2],*copia;
  int i=0;

  if (!PL_get_atom_chars(nombre,&n))  /* Cojemos lo que nos llega de
Prolog*/
    return PL_warning("nombre/2: instantation fault"); /* si el nombre
no esta instanciado salimos*/
   fichero = gdbm_open(BASE_PATH,512,GDBM_READER,0,0);
  if (fichero==NULL) return FALSE;
  copia = (char*)malloc(sizeof(char)*strlen(n));    /*Copiamos*/
  printf("extradequeso");
  for (i=0;i<strlen(n);i++) copia[i]=n[i];

  key1.dptr=copia;
  if (copia[strlen(copia)-1]=='s'){    /* Nos encontramos con un
plural?*/
    copia[strlen(copia)-1]='\0';
    PL_unify_atom_chars(numero,"p");}
  else PL_unify_atom_chars(numero,"s");

  key1.dsize = strlen(copia);

   if (!gdbm_exists(fichero,key1)) return FALSE;
   printf("extradequeso");
   printf("en la base de datod\n");
  data = gdbm_fetch(fichero,key1);
  if (data.dptr[0]!='_') return PL_unify_atom_chars(genero,data.dptr);
  return TRUE;
}

/* Predicado al que le pasamos el verbo en infinitivo y los accidentes y
nos devuelve lo que queremos */

foreign_t
pl_verboc(term_t verbo,term_t numero,term_t persona,term_t tiempo,term_t
modo,term_t verbocon){
  char
*pnumero,*ptiempo,*pverbo,*pmodo,*pverbocon,*ppersona,*recoge,*pasa;
  int npersona;
  Init_Conjugator();
  if (!PL_get_atom_chars(verbo,&pverbo)) return FALSE;
  if (!PL_get_integer(persona,&npersona)) return FALSE;
  if (!PL_get_atom_chars(numero,&pnumero)) return FALSE;
  if (!PL_get_atom_chars(tiempo,&ptiempo)) return FALSE;
  if (!PL_get_atom_chars(modo,&pmodo)) return FALSE;
  if (!Esta(pverbo)) return FALSE;
  return
PL_unify_atom_chars(verbocon,Verbo(pverbo,pnumero,npersona,ptiempo,pmodo));

  End_Conjugator();
}

foreign_t
pl_verbo(term_t verbocon,term_t numero,term_t persona,term_t
tiempo,term_t modo,term_t verbo)
{
  GDBM_FILE fichero;   /* Fichero de la base de datos*/
  datum key1,data;
  char
pnumero[2],ppersona[2],ptiempo[20],pmodo[20],pverbo[30],*pverbocon[40],*codec,num[10],infinitivo[30],*copia;

  int i=0,offset,npersona,cont=0,j=0;

  if (!PL_get_atom_chars(verbocon,pverbocon))  /* Cojemos lo que nos
llega de Prolog*/
    return PL_warning("nombre/2: instantation fault"); /* si el nombre
no esta instanciado salimos*/
  fichero = gdbm_open(BASEV_PATH,512,GDBM_READER,0,0);

  key1.dptr = *pverbocon;
  key1.dsize = strlen(*pverbocon);

  if (!gdbm_exists(fichero,key1)) return FALSE;
  data = gdbm_fetch(fichero,key1);
  codec = data.dptr;

  while ((codec[cont]>=48)&&(codec[cont]<=57)) cont++;
  for (j=0;j<cont;j++) num[j]=codec[j];
  num[j+1]='\0';

  for (j=cont;codec[j]!='\0';j++) infinitivo[j-cont]=codec[j];
  strcat(infinitivo+(j-cont+1),'\0');
  copia=(char*)malloc(sizeof(char)*(j-cont+1));
  offset = atoi(num);

  for (i=0;i<=j-cont+1;i++) copia[i]=infinitivo[i];
  Reconoce(pnumero,&npersona,ptiempo,pmodo,offset);
  npersona%=3;

  if (!PL_unify_atom_chars(numero,pnumero)) return FALSE;
  if (!PL_unify_atom_chars(tiempo,ptiempo)) return FALSE;
  if (!PL_unify_atom_chars(modo,pmodo)) return FALSE;
  if (!PL_unify_integer(persona,(long)npersona)) return FALSE;
  if (!PL_unify_atom_chars(verbo,copia)) return FALSE;
  return TRUE;
}

install_t
       install()
       { PL_register_foreign("nombre",3,pl_nombre,0);
         PL_register_foreign("verbo",6,pl_verbo,0);
         PL_register_foreign("verboc",6,pl_verboc,0);
       }