X-Git-Url: https://asedeno.scripts.mit.edu/gitweb/?a=blobdiff_plain;f=conf.c;h=92341758abf89f5de29b7794b03b0a2230c1e968;hb=2247065d0fa88daf8499eb937ee60e8e3df22261;hp=326844995c4ad6a72b53dbb3ec731f8b7ac308e0;hpb=1aeaff47a9d93720df01a3657bbfe17cbb7b4995;p=PuTTY.git diff --git a/conf.c b/conf.c index 32684499..92341758 100644 --- a/conf.c +++ b/conf.c @@ -39,12 +39,22 @@ 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; - FontSpec fontval; + 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,10 @@ 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); } /* @@ -141,10 +178,10 @@ 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 = from->u.fontval; + to->u.fontval = fontspec_copy(from->u.fontval); break; } } @@ -282,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); @@ -293,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; @@ -303,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; @@ -311,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); @@ -330,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) @@ -343,7 +381,7 @@ FontSpec *conf_get_fontspec(Conf *conf, int primary) key.primary = primary; entry = find234(conf->tree, &key, NULL); assert(entry); - return &entry->value.u.fontval; + return entry->value.u.fontval; } void conf_set_int(Conf *conf, int primary, int value) @@ -416,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); } @@ -427,7 +465,7 @@ void conf_set_fontspec(Conf *conf, int primary, const FontSpec *value) assert(subkeytypes[primary] == TYPE_NONE); assert(valuetypes[primary] == TYPE_FONT); entry->key.primary = primary; - entry->value.u.fontval = *value; /* structure copy */ + entry->value.u.fontval = fontspec_copy(value); conf_insert(conf, entry); } @@ -455,10 +493,10 @@ 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 += sizeof(entry->value.u.fontval); + size += fontspec_serialise(entry->value.u.fontval, NULL); break; } } @@ -502,14 +540,10 @@ 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: - memcpy(data, &entry->value.u.fontval, - sizeof(entry->value.u.fontval)); - data += sizeof(entry->value.u.fontval); + data += fontspec_serialise(entry->value.u.fontval, data); break; } } @@ -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; + 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,28 +615,28 @@ 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: - if (maxsize < sizeof(entry->value.u.fontval)) { + entry->value.u.fontval = + fontspec_deserialise(data, maxsize, &used); + if (!entry->value.u.fontval) { if (subkeytypes[entry->key.primary] == TYPE_STR) sfree(entry->key.secondary.s); sfree(entry); goto done; } - memcpy(&entry->value.u.fontval, data, - sizeof(entry->value.u.fontval)); - data += sizeof(entry->value.u.fontval); - maxsize -= sizeof(entry->value.u.fontval); + data += used; + maxsize -= used; break; } conf_insert(conf, entry);