// main.c #include "arrayList.h" #include "FIDIndex.h" #include "StringHashTable.h" #include "nextField.h" #include "buildIndex.h" #include "GISParse.h" #include "cmdReader.h" #include <assert.h> #include <stdio.h> #include <string.h> #include <stdlib.h> #define MAX_LINE_LENGTH 500 #define DEFAULT_MASTER_SIZE 256 uint32_t elfhash(const char *str); int main(int args, char *files[]) { // Reads in input file and create output file FILE *readF = fopen(files[1], "r"); FILE *outF = fopen(files[2], "w"); // Checks for input file if (!readF) { printf("Error: unable to create %s\n", files[1]); return 1; } if (!outF) outF = fopen("script.out", "w"); arrayList *masterFID = AL_create(DEFAULT_MASTER_SIZE, sizeof(FIDIndex), compareFIDIndex, cleanFID); StringHashTable *masterName; FILE *gis; int cmdNum = 1; char *line = calloc(MAX_LINE_LENGTH - 1, sizeof(char)), *sep = "----------------------------------------------"; bool index_and_table_made = false; while (fgets(line, MAX_LINE_LENGTH - 1, readF)) { // Holds the current command and paramters char *cmd, *p1, *p2, *tok = strtok(line, "\t"); if (*tok != ';') { // Populates command and paramter fields cmd = tok, tok = strtok(NULL, "\t"); p1 = tok, tok = strtok(NULL, "\t"); if (tok != NULL) p2 = strtok(tok, "\n"); if (!strcmp(cmd, "db_file")) { char *fileName = strtok(p1, "\n"); gis = fopen(fileName, "r"); build_FID(masterFID, gis); // Builds FID index } if (!strcmp(cmd, "table_sz")) { int size = atoi(p1); masterName = StringHashTable_create(size, elfhash); build_name(masterName, gis); // Builds hash table index_and_table_made = true; } if (!strcmp(cmd, "exists")) { char *name = p1, *state = p2, *key = create_key(name, state); uint32_t *locations = StringHashTable_getLocationsOf(masterName, key), x = 0; if (locations) while (locations[x]) x++; fprintf(outF, "CMD\t%d:\t%s\t%s\t%s\n\n", cmdNum, cmd, name, state); if (x == 0) fprintf(outF, "Not found in index: %s %s\n%s\n", name, state, sep); else fprintf(outF, "%d occurrences: %s %s\n%s\n", x, name, state, sep); cmdNum++; } if (!strcmp(cmd, "details_of")) { char *name = p1, *state = p2, *key = create_key(name, state); uint32_t *locations = StringHashTable_getLocationsOf(masterName, key), x = 0; fprintf(outF, "CMD\t%d:\t%s\t%s\t%s\n\n", cmdNum, cmd, name, state); if (!locations) fprintf(outF, "Not found in index: %s %s\n%s\n", name, state, sep); else { while (locations[x]) { char **details = get_details_of(gis, locations[x]), **lat_long = get_readable_lat_and_long(locations[x], gis); fprintf(outF, "FID:\t\t%s\nName:\t\t%s\nType:\t\t%s\nState:\t\t%s\nCounty:\t\t%s\n", details[0], details[1], details[2], details[3], details[4]); fprintf(outF, "Longitude:\t%sd %dm %ds %s\t(%s)\nLatitude:\t%sd %dm %ds %s\t(%s)\n\n", lat_long[6], atoi(lat_long[7]), atoi(lat_long[8]), lat_long[9], details[8], lat_long[2], atoi(lat_long[3]), atoi(lat_long[4]), lat_long[5], details[7]); x++; } fprintf(outF, "%s\n", sep); } cmdNum++; } if (!strcmp(cmd, "distance_between")) { FIDIndex *entry1 = FIDIndex_create(p1, 0), *entry2 = FIDIndex_create(p2, 0), *id1 = AL_find(masterFID, entry1), *id2 = AL_find(masterFID, entry2); fprintf(outF, "CMD\t%d:\t%s\t%s\t%s\n\n", cmdNum, cmd, entry1->FID, entry2->FID); if (!id1) fprintf(outF, "Invalid feature ID:\t%s\n%s\n", entry1->FID, sep); else if (!id2) fprintf(outF, "Invalid feature ID:\t%s\n%s\n", entry2->FID, sep); else { double distance = find_distance_between(id1->occuranceOffset, id2->occuranceOffset, gis); char **first = get_readable_lat_and_long(id1->occuranceOffset, gis), **second = get_readable_lat_and_long(id2->occuranceOffset, gis); fprintf(outF, "First:\t( %sd %dm %ds %s,\t%sd %dm %ds %s )\t%s, %s\n", first[6], atoi(first[7]), atoi(first[8]), first[9], first[2], atoi(first[3]), atoi(first[4]), first[5], first[0], first[1]); fprintf(outF, "Second:\t( %sd %dm %ds %s,\t%sd %dm %ds %s )\t%s, %s\n", second[6], atoi(second[7]), atoi(second[8]), second[9], second[2], atoi(second[3]), atoi(second[4]), second[5], second[0], second[1]); fprintf(outF, "Distance:\t%.1fkm\n%s\n", distance, sep); } cmdNum++; } if (!strcmp(cmd, "quit")) { fprintf(outF, "CMD\t%d:\t%s\n\nExiting...\n%s", cmdNum, cmd, sep); clean(masterFID, masterName); fclose(gis); break; } } else if (index_and_table_made) fprintf(outF, "%s", line); } fclose(readF); fclose(outF); free(line); return 0; } uint32_t elfhash(const char *str) { assert(str != NULL); // self-destuct if called with NULL uint32_t hashvalue = 0, // value to be returned high; // high nybble of current hashvalue while (*str) { // continue until *str is '\0' hashvalue = (hashvalue << 4) + *str++; // shift high nybble out, // add in next char, // skip to the next char if ((high = (hashvalue & 0xF0000000))) // if high nybble != 0000 hashvalue = hashvalue ^ (high >> 24); // fold it back in hashvalue = hashvalue & 0x7FFFFFFF; // zero high nybble } return hashvalue; } /** * Closes all files and clears the dynamically allocated arrayList and StringHashTable */ void clean(arrayList *list, StringHashTable *table) { StringHashTable_clear(table); AL_clean(list); free(table); free(list); }