diff options
Diffstat (limited to 'distcc/src/stringmap.c')
-rw-r--r-- | distcc/src/stringmap.c | 116 |
1 files changed, 116 insertions, 0 deletions
diff --git a/distcc/src/stringmap.c b/distcc/src/stringmap.c new file mode 100644 index 0000000..2c3d26f --- /dev/null +++ b/distcc/src/stringmap.c @@ -0,0 +1,116 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <limits.h> +#include <assert.h> +#include "stringmap.h" + +#ifndef NULL +#define NULL 0 +#endif + +/* Load the given list of strings into the key/value map. + * The key for each string is the numFinalWordsToMatch of the string; + * the value for each string is the entire string. + * FIXME: doesn't work for utf-8 strings, since it scans raw chars for / + */ +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); + /* strip trailing \n */ + if (len > 0 && buf[len-1] == '\n') { + buf[len-1] = 0; + len--; + } + /* set pos to the start of the significant part of the string */ + for (pos=len-1, w=0; pos>0; pos--) { + if (buf[pos] == '/') { + w++; + if (w >= numFinalWordsToMatch) + 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) + break; + } + } + for (i=0; i<map->n; i++) { + /*printf("Comparing %s and %s\n", map->map[i].key, string+pos);*/ + 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)); } } + +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", NULL); + verifyMap(sm, "/foo/bar/bletch", "/foo/bar/bletch"); +} + +#endif |