/*
* Copyright 2012 Steven Gribble
*
* This file is part of the UW CSE 333 course project sequence
* (333proj).
*
* 333proj is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* 333proj is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with 333proj. If not, see .
*/
#include
#include
#include
#include
#include "./HashTable.h"
// What we are storing as the value in our hashtable.
typedef struct word_count_st {
char *word;
unsigned int count;
} WordCount;
// Print the usage message to STDERR and exit(EXIT_FAILURE);
void Usage(void);
// Reads the file into memory, allocating sufficient space
// for the file as it goes. Returns NULL on failure, non-NULL
// on success.
char *ReadFileIntoMemory(char *filename);
// Insert a word into the hashtable. Returns 0 on failure,
// 1 on success.
int InsertWordIntoHashTable(HashTable ht, char *word);
int main(int argc, char **argv) {
if (argc != 2)
Usage();
// Read in the file content.
char *fdata = ReadFileIntoMemory(argv[1]);
if (fdata == NULL)
Usage();
// Create a hashtable.
HashTable ht = AllocateHashTable(1);
// Split the file up into tokens.
char *tok = strtok(fdata, " \r\n\t");
while (tok != NULL) {
// Convert the word to lower-case.
for (int i=0; icount, wc->word);
HTIteratorNext(it);
}
// Clean up and exit.
HTIteratorFree(it);
free(fdata);
FreeHashTable(ht, &free);
return EXIT_SUCCESS;
}
void Usage(void) {
fprintf(stderr, "usage: word_count filename\n");
exit(EXIT_FAILURE);
}
char *ReadFileIntoMemory(char *filename) {
// Try to open the file.
FILE *f = fopen(filename, "rb");
if (f == NULL)
return NULL;
// Figure out how big the file is.
long fsize;
if (fseek(f, 0, SEEK_END) == -1) {
fclose(f);
return NULL;
}
fsize = ftell(f);
if (fsize < 0) {
fclose(f);
return NULL;
}
if (fseek(f, 0, SEEK_SET) == -1) {
fclose(f);
return NULL;
}
// Allocate space for the file.
char *retval = (char *) malloc(sizeof(char) * (fsize + 1));
if (retval == NULL) {
fclose(f);
return NULL;
}
// Read the file into memory.
size_t readval = fread(retval, fsize, 1, f);
if (readval != 1) {
fclose(f);
free(retval);
return NULL;
}
// NULL-terminate the file data.
retval[fsize] = '\0';
// Clean up.
fclose(f);
return retval;
}
int InsertWordIntoHashTable(HashTable ht, char *word) {
HTKeyValue kv, oldkv;
// Test to see if the word is already in the HT.
if (LookupHashTable(ht,
FNVHash64((unsigned char *) word, strlen(word)),
&kv) == 1) {
WordCount *wc = (WordCount *) kv.value;
wc->count += 1;
return 1;
}
// Allocate a WordCount to store the word.
WordCount *wc = (WordCount *) malloc(sizeof(WordCount));
if (wc == NULL) {
return 0;
}
// Prep the WordCount and insert it.
wc->word = word;
wc->count = 1;
kv.key = FNVHash64((unsigned char *) word, strlen(word));
kv.value = (void *) wc;
if (InsertHashTable(ht, kv, &oldkv) != 1) {
free(wc);
return 0;
}
// All done!
return 1;
}