]> asedeno.scripts.mit.edu Git - PuTTY.git/blobdiff - conf.c
first pass
[PuTTY.git] / conf.c
diff --git a/conf.c b/conf.c
index 7b6a0137aa1cae2c1728d5bf91e5be301b24a361..92341758abf89f5de29b7794b03b0a2230c1e968 100644 (file)
--- a/conf.c
+++ b/conf.c
@@ -39,6 +39,16 @@ struct key {
     } secondary;
 };
 
+/* Variant form of struct key which doesn't contain dynamic data, used
+ * for lookups. */
+struct constkey {
+    int primary;
+    union {
+       int i;
+       const char *s;
+    } secondary;
+};
+
 struct value {
     union {
        int intval;
@@ -88,6 +98,29 @@ static int conf_cmp(void *av, void *bv)
     }
 }
 
+static int conf_cmp_constkey(void *av, void *bv)
+{
+    struct key *a = (struct key *)av;
+    struct constkey *b = (struct constkey *)bv;
+
+    if (a->primary < b->primary)
+       return -1;
+    else if (a->primary > b->primary)
+       return +1;
+    switch (subkeytypes[a->primary]) {
+      case TYPE_INT:
+       if (a->secondary.i < b->secondary.i)
+           return -1;
+       else if (a->secondary.i > b->secondary.i)
+           return +1;
+       return 0;
+      case TYPE_STR:
+       return strcmp(a->secondary.s, b->secondary.s);
+      default:
+       return 0;
+    }
+}
+
 /*
  * Free any dynamic data items pointed to by a 'struct key'. We
  * don't free the structure itself, since it's probably part of a
@@ -286,7 +319,7 @@ char *conf_get_str_str(Conf *conf, int primary, const char *secondary)
 char *conf_get_str_strs(Conf *conf, int primary,
                       char *subkeyin, char **subkeyout)
 {
-    struct key key;
+    struct constkey key;
     struct conf_entry *entry;
 
     assert(subkeytypes[primary] == TYPE_STR);
@@ -297,7 +330,7 @@ char *conf_get_str_strs(Conf *conf, int primary,
        entry = findrel234(conf->tree, &key, NULL, REL234_GT);
     } else {
        key.secondary.s = "";
-       entry = findrel234(conf->tree, &key, NULL, REL234_GE);
+       entry = findrel234(conf->tree, &key, conf_cmp_constkey, REL234_GE);
     }
     if (!entry || entry->key.primary != primary)
        return NULL;
@@ -307,7 +340,7 @@ char *conf_get_str_strs(Conf *conf, int primary,
 
 char *conf_get_str_nthstrkey(Conf *conf, int primary, int n)
 {
-    struct key key;
+    struct constkey key;
     struct conf_entry *entry;
     int index;
 
@@ -315,7 +348,8 @@ char *conf_get_str_nthstrkey(Conf *conf, int primary, int n)
     assert(valuetypes[primary] == TYPE_STR);
     key.primary = primary;
     key.secondary.s = "";
-    entry = findrelpos234(conf->tree, &key, NULL, REL234_GE, &index);
+    entry = findrelpos234(conf->tree, &key, conf_cmp_constkey,
+                          REL234_GE, &index);
     if (!entry || entry->key.primary != primary)
        return NULL;
     entry = index234(conf->tree, index + n);
@@ -522,14 +556,15 @@ int conf_deserialise(Conf *conf, void *vdata, int maxsize)
     unsigned char *data = (unsigned char *)vdata;
     unsigned char *start = data;
     struct conf_entry *entry;
-    int primary, used;
+    unsigned primary;
+    int used;
     unsigned char *zero;
 
     while (maxsize >= 4) {
        primary = GET_32BIT_MSB_FIRST(data);
        data += 4, maxsize -= 4;
 
-       if ((unsigned)primary >= N_CONFIG_OPTIONS)
+       if (primary >= N_CONFIG_OPTIONS)
            break;
 
        entry = snew(struct conf_entry);
@@ -541,7 +576,7 @@ int conf_deserialise(Conf *conf, void *vdata, int maxsize)
                sfree(entry);
                goto done;
            }
-           entry->key.secondary.i = GET_32BIT_MSB_FIRST(data);
+           entry->key.secondary.i = toint(GET_32BIT_MSB_FIRST(data));
            data += 4, maxsize -= 4;
            break;
          case TYPE_STR:
@@ -564,7 +599,7 @@ int conf_deserialise(Conf *conf, void *vdata, int maxsize)
                sfree(entry);
                goto done;
            }
-           entry->value.u.intval = GET_32BIT_MSB_FIRST(data);
+           entry->value.u.intval = toint(GET_32BIT_MSB_FIRST(data));
            data += 4, maxsize -= 4;
            break;
          case TYPE_STR: