summaryrefslogtreecommitdiff
path: root/distcc/src/stringmap.c
diff options
context:
space:
mode:
Diffstat (limited to 'distcc/src/stringmap.c')
-rw-r--r--distcc/src/stringmap.c116
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