diff options
Diffstat (limited to 'src/registry.c')
-rw-r--r-- | src/registry.c | 46 |
1 files changed, 42 insertions, 4 deletions
diff --git a/src/registry.c b/src/registry.c index dcaaa1b..dbaac2a 100644 --- a/src/registry.c +++ b/src/registry.c @@ -742,6 +742,10 @@ parse_config_item(struct rxkb_context *ctx, if (!*name || !strlen(*name)) { log_err(ctx, "xml:%d: missing required element 'name'\n", ci->line); + free(*name); + free(*description); + free(*brief); + free(*vendor); return false; } @@ -804,6 +808,11 @@ parse_language_list(xmlNode *language_list, struct rxkb_layout *layout) char *str = extract_text(node); struct rxkb_object *parent; + if (!str || strlen(str) != 3) { + free(str); + continue; + } + parent = &layout->base; code = rxkb_iso639_code_create(parent); code->code = str; @@ -823,6 +832,11 @@ parse_country_list(xmlNode *country_list, struct rxkb_layout *layout) char *str = extract_text(node); struct rxkb_object *parent; + if (!str || strlen(str) != 2) { + free(str); + continue; + } + parent = &layout->base; code = rxkb_iso3166_code_create(parent); code->code = str; @@ -856,7 +870,8 @@ parse_variant(struct rxkb_context *ctx, struct rxkb_layout *l, v->name = strdup(l->name); v->variant = name; v->description = description; - v->brief = brief; + // if variant omits brief, inherit from parent layout. + v->brief = brief == NULL ? strdup_safe(l->brief) : brief; v->popularity = popularity; list_append(&ctx->layouts, &v->base.link); @@ -866,11 +881,35 @@ parse_variant(struct rxkb_context *ctx, struct rxkb_layout *l, if (!is_node(ci, "configItem")) continue; + bool found_language_list = false; + bool found_country_list = false; for (node = ci->children; node; node = node->next) { - if (is_node(node, "languageList")) + if (is_node(node, "languageList")) { parse_language_list(node, v); - if (is_node(node, "countryList")) + found_language_list = true; + } + if (is_node(node, "countryList")) { parse_country_list(node, v); + found_country_list = true; + } + } + if (!found_language_list) { + // inherit from parent layout + struct rxkb_iso639_code* x; + list_for_each(x, &l->iso639s, base.link) { + struct rxkb_iso639_code* code = rxkb_iso639_code_create(&v->base); + code->code = strdup(x->code); + list_append(&v->iso639s, &code->base.link); + } + } + if (!found_country_list) { + // inherit from parent layout + struct rxkb_iso3166_code* x; + list_for_each(x, &l->iso3166s, base.link) { + struct rxkb_iso3166_code* code = rxkb_iso3166_code_create(&v->base); + code->code = strdup(x->code); + list_append(&v->iso3166s, &code->base.link); + } } } } else { @@ -1193,7 +1232,6 @@ parse(struct rxkb_context *ctx, const char *path, success = true; error: xmlFreeDoc(doc); - xmlCleanupParser(); return success; } |