]> 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 e3ce258fc687a1d9f9767eb7f3158ebd094a7b00..92341758abf89f5de29b7794b03b0a2230c1e968 100644 (file)
--- a/conf.c
+++ b/conf.c
@@ -39,11 +39,21 @@ 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;
        char *stringval;
-       Filename fileval;
+       Filename *fileval;
        FontSpec *fontval;
     } u;
 };
@@ -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
@@ -125,6 +158,8 @@ static void free_value(struct value *val, int type)
 {
     if (type == TYPE_STR)
        sfree(val->u.stringval);
+    else if (type == TYPE_FILENAME)
+       filename_free(val->u.fileval);
     else if (type == TYPE_FONT)
        fontspec_free(val->u.fontval);
 }
@@ -143,7 +178,7 @@ static void copy_value(struct value *to, struct value *from, int type)
        to->u.stringval = dupstr(from->u.stringval);
        break;
       case TYPE_FILENAME:
-       to->u.fileval = from->u.fileval;
+       to->u.fileval = filename_copy(from->u.fileval);
        break;
       case TYPE_FONT:
        to->u.fontval = fontspec_copy(from->u.fontval);
@@ -284,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);
@@ -295,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;
@@ -305,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;
 
@@ -313,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);
@@ -332,7 +368,7 @@ Filename *conf_get_filename(Conf *conf, int primary)
     key.primary = primary;
     entry = find234(conf->tree, &key, NULL);
     assert(entry);
-    return &entry->value.u.fileval;
+    return entry->value.u.fileval;
 }
 
 FontSpec *conf_get_fontspec(Conf *conf, int primary)
@@ -418,7 +454,7 @@ void conf_set_filename(Conf *conf, int primary, const Filename *value)
     assert(subkeytypes[primary] == TYPE_NONE);
     assert(valuetypes[primary] == TYPE_FILENAME);
     entry->key.primary = primary;
-    entry->value.u.fileval = *value;   /* structure copy */
+    entry->value.u.fileval = filename_copy(value);
     conf_insert(conf, entry);
 }
 
@@ -457,7 +493,7 @@ int conf_serialised_size(Conf *conf)
            size += 1 + strlen(entry->value.u.stringval);
            break;
          case TYPE_FILENAME:
-           size += sizeof(entry->value.u.fileval);
+           size += filename_serialise(entry->value.u.fileval, NULL);
            break;
          case TYPE_FONT:
            size += fontspec_serialise(entry->value.u.fontval, NULL);
@@ -504,9 +540,7 @@ void conf_serialise(Conf *conf, void *vdata)
            *data++ = 0;
            break;
          case TYPE_FILENAME:
-           memcpy(data, &entry->value.u.fileval,
-                  sizeof(entry->value.u.fileval));
-           data += sizeof(entry->value.u.fileval);
+            data += filename_serialise(entry->value.u.fileval, data);
            break;
          case TYPE_FONT:
             data += fontspec_serialise(entry->value.u.fontval, data);
@@ -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:
@@ -580,16 +615,16 @@ int conf_deserialise(Conf *conf, void *vdata, int maxsize)
            data = zero + 1;
            break;
          case TYPE_FILENAME:
-           if (maxsize < sizeof(entry->value.u.fileval)) {
+            entry->value.u.fileval =
+                filename_deserialise(data, maxsize, &used);
+            if (!entry->value.u.fileval) {
                if (subkeytypes[entry->key.primary] == TYPE_STR)
                    sfree(entry->key.secondary.s);
                sfree(entry);
                goto done;
            }
-           memcpy(&entry->value.u.fileval, data,
-                  sizeof(entry->value.u.fileval));
-           data += sizeof(entry->value.u.fileval);
-           maxsize -= sizeof(entry->value.u.fileval);
+           data += used;
+           maxsize -= used;
            break;
          case TYPE_FONT:
             entry->value.u.fontval =