
#include "util.h"


int is_prefix(const char *pat, const char *txt)
{
   const char *p, *t;

   p = pat;
   t = txt;

   if (!p) return 1;
   if (!t) {
      return !(*p);
   }

   while (*p) {
      if (*p != *t) return 0;
      ++p;
      ++t;
   }

   return 1;
}



/* reads up a line of input into s, null terminated, no newline.
 * Assumes s has space for MAXLEN characters.
 * returns # of characters written into s (including trailing zero).
 * returns 0 on eof and -1 on error.
 */


int readline(FILE *fp, char *s)
{
   int i, c;

   c = getc(fp);

   if (c == EOF) {
      if (feof(fp)) 
         return 0;
      else
         return -1;
   }

   i = 0;
   while (c != EOF && c != '\n') {
      if (i >= MAXLEN) return -1;
      s[i] = c;
      i++;

      c = getc(fp);
   }

   if (c == EOF) return -1;

   if (i >= MAXLEN) return -1;
   s[i] = '\0';
   i++;

   return i;
}


/* some simple hash table routines.
 */

#define HASHSZ (4001)
#define HASHKEY (2117)

int hash_value(const char *s)
{
   int acc = 0;

   while (*s) {
      acc = acc * (HASHKEY) + ( (*s) & 0xff );
      acc = acc % HASHSZ;
      s++;
   }

   return acc;
}

struct htable_entry {
   char *key;
   int data;
   struct htable_entry *next;
};

typedef struct htable_entry *htable_entry_ptr;

htable_entry_ptr *htable = 0;

void htable_init()
{
   int i;

   htable = (htable_entry_ptr *) malloc( HASHSZ * sizeof(htable_entry_ptr) );
   if (!htable) {
      fprintf(stderr, "malloc error\n");
      exit(-1);
   }
   for (i = 0; i < HASHSZ; i++)
      htable[i] = 0;
}

htable_entry_ptr htable_lookup(const char *s)
{
   htable_entry_ptr p = htable[hash_value(s)];
   while (p && strcmp(s, p->key) != 0) p = p->next;
   return p;
}

htable_entry_ptr htable_insert(const char *s)
{
   int i = hash_value(s);
   htable_entry_ptr p = htable[i];
   while (p && strcmp(s, p->key) != 0) p = p->next;

   if (!p) {
      p = (htable_entry_ptr) malloc( sizeof(struct htable_entry) );
      if (!p) {
         fprintf(stderr, "malloc error\n");
         exit(-1);
      }
      p->key = strdup(s);
      if (!p->key) {
         fprintf(stderr, "malloc error\n");
         exit(-1);
      }
      p->data = 0;
      p->next = htable[i];
      htable[i] = p;
   }

   return p;
}

void collect_names(const char *fname)
{
   FILE *fp;
   char s[MAXLEN];
   int ret;
   htable_entry_ptr p;
   int i;

   fp = fopen(fname, "r");
   if (!fp) {
      fprintf(stderr, "can't open %s\n", fname);
      exit(-1);
   }

   htable_init();

   while ( (ret = readline(fp, s)) > 0) {
      if (ret == 1) continue; /* ignore blank lines */

      p = htable_insert(s);
      p->data = 1;
      for (i = ret-2; i >= 0; i--) {
         if (s[i] == '/') {
            s[i] = '\0';
            (void) htable_insert(s);
         }
      }
   }

   if (ret < 0) {
      fprintf(stderr, "error reading  %s\n", fname);
      exit(-1);
   }

   fclose(fp);
}

int lookup_name(const char *s)
{
   htable_entry_ptr p = htable_lookup(s);
   if (p) 
      return p->data;
   else
      return -1;
}

void overflow(void) 
{
   fprintf(stderr, "buffer overrun -- terminating\n");
   exit(-1);
}

