#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <assert.h>
#include "stringmap.h"
#ifndef NULL
#define NULL 0
#endif
stringmap_t *stringmap_load(const char *filename, int numFinalWordsToMatch)
{
stringmap_t *result = calloc(1, sizeof(*result));
FILE *fp = fopen(filename, "r");
char buf[2*PATH_MAX];
int n;
result->numFinalWordsToMatch = numFinalWordsToMatch;
if (!fp)
return NULL;
n=0;
while (fgets(buf, sizeof(buf), fp))
n++;
result->n = n;
result->map = malloc(n * sizeof(result->map[0]));
rewind(fp);
n=0;
while (fgets(buf, sizeof(buf), fp)) {
int pos, w;
int len = strlen(buf);
if (len > 0 && buf[len-1] == '\n') {
buf[len-1] = 0;
len--;
}
for (pos=len-1, w=0; pos>0; pos--) {
if (buf[pos] == '/') {
w++;
if (w >= numFinalWordsToMatch) {
pos++;
break;
}
}
}
result->map[n].value = strdup(buf);
result->map[n].key = strdup(buf+pos);
n++;
} fclose(fp);
return result;
}
const char *stringmap_lookup(const stringmap_t *map, const char *string)
{
int i, w;
int len = strlen(string);
int pos;
for (pos=len-1, w=0; pos>0; pos--) {
if (string[pos] == '/') {
w++;
if (w >= map->numFinalWordsToMatch) {
pos++;
break;
}
}
}
for (i=0; i<map->n; i++) {
if (!strcmp(map->map[i].key, string+pos))
return map->map[i].value;
}
return NULL;
}
#if 0
void dumpMap(stringmap_t *sm)
{
int i;
printf("map has %d elements, and numFinalWordsToMatch is %d\n", sm->n, sm->numFinalWordsToMatch);
for (i=0; i < sm->n; i++) {
printf("row %d: key %s, value %s\n", i, sm->map[i].key, sm->map[i].value);
}
}
#define verifyMap(sm, a, b) { \
const char *c = stringmap_lookup(sm, a); \
if (!b) \
assert(!c); \
else { \
assert(c); \
assert(!strcmp(b, c)); } }
int main(int argc, char **argv)
{
FILE *fp;
stringmap_t *sm;
fp = fopen("stringmap_test.dat", "w");
fprintf(fp, "/foo/bar/bletch\n");
fclose(fp);
sm = stringmap_load("stringmap_test.dat", 1);
dumpMap(sm);
verifyMap(sm, "/bar/bletch", "/foo/bar/bletch");
verifyMap(sm, "bletch", "/foo/bar/bletch");
verifyMap(sm, "/whatever/bletch", "/foo/bar/bletch");
verifyMap(sm, "baz", NULL);
verifyMap(sm, "/foo/bar/bletch", "/foo/bar/bletch");
fp = fopen("stringmap_test.dat", "w");
fprintf(fp, "/usr/bin/gcc\n");
fprintf(fp, "/usr/bin/cc\n");
fclose(fp);
sm = stringmap_load("stringmap_test.dat", 1);
dumpMap(sm);
verifyMap(sm, "/usr/bin/gcc", "/usr/bin/gcc");
verifyMap(sm, "/usr/bin/cc", "/usr/bin/cc");
verifyMap(sm, "gcc", "/usr/bin/gcc");
verifyMap(sm, "cc", "/usr/bin/cc");
verifyMap(sm, "g77", NULL);
fp = fopen("stringmap_test.dat", "w");
fprintf(fp, "/usr/bin/i686-blah-blah/gcc\n");
fprintf(fp, "/usr/bin/i386-blah-blah/gcc\n");
fclose(fp);
sm = stringmap_load("stringmap_test.dat", 2);
dumpMap(sm);
verifyMap(sm, "/usr/bin/i686-blah-blah/gcc",
"/usr/bin/i686-blah-blah/gcc");
verifyMap(sm, "/usr/bin/i386-blah-blah/gcc",
"/usr/bin/i386-blah-blah/gcc");
verifyMap(sm, "i686-blah-blah/gcc", "/usr/bin/i686-blah-blah/gcc");
verifyMap(sm, "i386-blah-blah/gcc", "/usr/bin/i386-blah-blah/gcc");
verifyMap(sm, "gcc", NULL);
verifyMap(sm, "g77", NULL);
return 0;
}
#endif