/*
** By Bob Jenkins, February 22, 1997, Public Domain
** Contains various modifications by j l decocq cisco systems 2007
** This is an example of how to use the hash table.
**
** Given an input (stdin) with lines in any order
** produce an output (stdout) with duplicate lines removed.
** Lines may not be longer than 4096 characters.
*/
#pragma warning(disable: 4996) /* quash VS compiler unsafe function warning JLD */

/*
 * JLD comments: the hash table appears to be fine with wide character support.
 * _UNICODE is for C runtime TCHAR support, i.e. _tcscpy (--> wcscpy vs strcpy), 
 * distinct from UNICODE, which turns, say, CreateWindowEx into CreateWindowExW 
 * instead of CreateWindowExA. 
*/

#ifndef _UNICODE    /* defined by default in VS2005 */
#define _UNICODE
#endif
#include "tchar.h"  /* wide char support, wmain() vs main() */

#ifndef UNICODE     /* defined by default in VS2005 */
#define UNICODE
#endif
 
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include "jenkstd.h"
#include "jenkhtab.h"
#include <conio.h>
#define TESTDATAPATH "jenktest.txt"
#define MAXLINELEN 64
#define INITIAL_TABLE_SIZE_LOG2 2


int _tmain(int argc, _TCHAR* argv[])
{
  /* when _UNICODE is defined _tmain expands to wmain, otherwise it expands to main */
  char  buf[MAXLINELEN];
  char* pkey;
  int   keylen, myincount=0, myhashcount=0, myfreecount=0;
  htab* myhashtable;
  char  c = 0;
  FILE* f;
  printf("** jenktest.c start\n\n");

  do {

  f = fopen(TESTDATAPATH,"r");
  if (!f)
  {   printf("could not open test data file %s\n",TESTDATAPATH);
      break;
  }

  myhashtable = hcreate(INITIAL_TABLE_SIZE_LOG2); /* create hash table */
  hstat(myhashtable);  /* show table stats */

  /* read in all the lines */
  while (fgets((char*)buf, MAXLINELEN, f))  
  {
    keylen = (ub4) strlen(buf);

    if (hadd(myhashtable, buf, keylen, (void *)0)) /* if not a duplicate */
    {
      pkey = (char*) malloc(keylen);      /* dumb use of malloc */
      memcpy(pkey, buf, keylen);          /* copy buf into pkey */
      hkey(myhashtable) = pkey;           /* replace buf with pkey */
      myincount++;
    }
  }

  fclose(f); f = 0;
  hstat(myhashtable);                  /* show table stats */

  if  (hfirst(myhashtable))            /* go to first element */  
       printf("%.*s\n", hkeyl(myhashtable), hkey(myhashtable));  
  else break;
  myhashcount = 1;
   
  while(hnext(myhashtable))           /* go to next element */
  {  printf("%.*s\n", hkeyl(myhashtable), hkey(myhashtable));  
     myhashcount++;
  }

  while (hcount(myhashtable))          /* while the table is not empty */
  {
    free(hkey(myhashtable));           /* free memory for the line */
    hdel(myhashtable);                 /* delete from hash table */
    myfreecount++;
  }

  hstat(myhashtable);                  /* show table stats */

  hdestroy(myhashtable);               /* destroy hash table */

  } while(0);

  printf("** keys read %d -- hashed %d -- removed %d\n", 
         myincount, myhashcount, myfreecount);
  printf("\n** jenktest.c end\n\n");
  printf("any key ..."); while(!c) c = _getch(); printf("\n"); 
  return 0;
}
