#include <stdio.h>
#include <ndbm.h>
#include <strings.h>
#include <ctype.h>
#include <sys/file.h>

#define OFFSETSFILE "/mit/sipb/src/src/Roget/lib/@sys/offsets"
#define WORDINDEX "/mit/sipb/src/src/Roget/lib/@sys/word-index"
#define DEPTH 12

long pdb_fetch();

main(argc, argv)
int argc;
char* argv[];
{
  int entries[20];
  int count;
  int i;
  char* word;
  DBM* db;
  if (argc != 2) exit();
 
  word = argv[1];
  
  count = get_entries(word, entries);

  if(!count) exit();
  
  db= dbm_open(OFFSETSFILE, O_RDONLY, 0);

  for(i = 0; i < count;i++) {
    long offset;
    printf("----------------------------------------------------------------------\n");
    offset = pdb_fetch(db,entries[i]);
    printf("%d %d\n", entries[i], offset);
    
  }
}

long pdb_fetch(db, entry)
    DBM* db;
{
  datum data;
  char temp[20];
  sprintf(temp, "%d", entry);
  data = dbm_fetch(db, temp, strlen(temp));
  bcopy( data.dptr, temp, data.dsize);
  return atol(temp);
}


get_entries(word, entries)
     char* word;
     int *entries;
{
  FILE* fptr;
  char buffer[1024];
  int filesize, partsize, location;
  int i, cmp;
  if(!(fptr = fopen(WORDINDEX, "r")))
    perror("fopen");

  lower(word);
  fseek(fptr, 0L, 2);
  filesize = ftell(fptr);
  partsize = filesize/2;
  location = partsize;
  fseek(fptr, location, 0);

  /* narrow down the search by binary splitting*/
  for(i = 0; i < DEPTH; i++) {
    
    if (location != 0) {
      /* if it's not at the beginning, eat a line first*/
      if(!fgets(buffer,1024,fptr)) return 0;
    }
    
    if(!fgets(buffer,1024,fptr))  return 0; /* get a word*/
    *index(buffer, ':') = 0;
    lower(buffer);

    cmp = strcmp(word, buffer);
    partsize /= 2;
    if(cmp > 0) 
      location += partsize;
    else
      location -= partsize;
    fseek(fptr,location, 0);
  }
  
  location -= partsize;
  if(location < partsize || location < 0) location = 0;
  fseek(fptr,location, 0);


  /* linear search*/
  if (location != 0) {
    /* if it's not at the beginning, eat a line first*/
    if(!fgets(buffer,1024,fptr))
      return 0;
  }
  
  for(;;) {
    if(!fgets(buffer, 1024, fptr)) return 0;
    *index(buffer, ':') = 0;
    lower(buffer);
    cmp = strcmp(word, buffer);
    if(cmp < 0) return 0; /* overpassed where it would be*/
    if(cmp == 0) { /* found it*/
      return chars2ints(buffer + strlen(buffer) + 1, entries);
    }
  }
  
}

chars2ints(str, entries)
char* str;
int* entries;
{
  int count = 0;
  for(;;) {
    while(*str && isspace(*str)) str++;
    if(!*str) return count;
    *entries = atoi(str);
    entries++;
    count++;
    while(*str && !isspace(*str)) str++;
    if(!*str) return count;
  }
}

lower(str)
char* str;
{
  while(*str){
    if(isupper(*str)) *str = tolower(*str);
    str++;
  }
}
