From 811255dc2c72a4f6218a42464dd6dee5b484a81d Mon Sep 17 00:00:00 2001 From: JakobDev Date: Fri, 3 Jun 2022 15:13:18 +0200 Subject: [PATCH 1/5] Update duplicate checking --- src/as-validator-issue-tag.h | 5 ++++ src/as-validator.c | 54 +++++++++++++++++++++++------------- 2 files changed, 39 insertions(+), 20 deletions(-) diff --git a/src/as-validator-issue-tag.h b/src/as-validator-issue-tag.h index dce04326..e957a170 100644 --- a/src/as-validator-issue-tag.h +++ b/src/as-validator-issue-tag.h @@ -91,6 +91,11 @@ AsValidatorIssueTag as_validator_issue_tag_list[] = { N_("The description contains a web URL in plain text. This is not allowed, please use the tag instead to share links.") }, + { "unsupported-translation", + AS_ISSUE_SEVERITY_ERROR, + N_("As per AppStream specification, the mention tag doesn't support translations.") + }, + { "tag-duplicated", AS_ISSUE_SEVERITY_ERROR, N_("As per AppStream specification, the mentioned tag must only appear once in this context. Having multiple tags of this kind is not valid.") diff --git a/src/as-validator.c b/src/as-validator.c index 41ccfb05..7dcfcbb3 100644 --- a/src/as-validator.c +++ b/src/as-validator.c @@ -882,7 +882,7 @@ as_validator_check_description_tag (AsValidator *validator, xmlNode* node, AsFor * as_validator_check_appear_once: **/ static void -as_validator_check_appear_once (AsValidator *validator, xmlNode *node, GHashTable *known_tags) +as_validator_check_appear_once (AsValidator *validator, xmlNode *node, GHashTable *known_tags, bool allowTranslations) { g_autofree gchar *lang = NULL; gchar *tag_id; @@ -893,8 +893,13 @@ as_validator_check_appear_once (AsValidator *validator, xmlNode *node, GHashTabl lang = as_xml_get_prop_value (node, "lang"); if (lang == NULL) tag_id = g_strdup (node_name); - else + else { + if (!allowTranslations) { + as_validator_add_issue (validator, node, "unsupported-translation", node_name); + } + tag_id = g_strdup_printf ("%s (lang=%s)", node_name, lang); + } if (g_hash_table_contains (known_tags, tag_id)) { as_validator_add_issue (validator, node, @@ -1960,9 +1965,11 @@ as_validator_validate_component_node (AsValidator *validator, AsContext *ctx, xm /* validate the AppStream ID */ as_validator_validate_component_id (validator, iter, cpt); + + as_validator_check_appear_once (validator, iter, found_tags, false); } else if (g_strcmp0 (node_name, "metadata_license") == 0) { has_metadata_license = TRUE; - as_validator_check_appear_once (validator, iter, found_tags); + as_validator_check_appear_once (validator, iter, found_tags, false); /* the license must allow easy mixing of metadata in metainfo files */ if (mode == AS_FORMAT_STYLE_METAINFO) @@ -1971,9 +1978,9 @@ as_validator_validate_component_node (AsValidator *validator, AsContext *ctx, xm if (g_hash_table_contains (found_tags, node_name)) as_validator_add_issue (validator, iter, "multiple-pkgname", NULL); } else if (g_strcmp0 (node_name, "source_pkgname") == 0) { - as_validator_check_appear_once (validator, iter, found_tags); + as_validator_check_appear_once (validator, iter, found_tags, false); } else if (g_strcmp0 (node_name, "name") == 0) { - as_validator_check_appear_once (validator, iter, found_tags); + as_validator_check_appear_once (validator, iter, found_tags, true); if (g_str_has_suffix (node_content, ".")) as_validator_add_issue (validator, iter, "name-has-dot-suffix", node_content); @@ -1981,7 +1988,7 @@ as_validator_validate_component_node (AsValidator *validator, AsContext *ctx, xm g_autofree gchar *lang = NULL; const gchar *summary = node_content; - as_validator_check_appear_once (validator, iter, found_tags); + as_validator_check_appear_once (validator, iter, found_tags, true); if (g_str_has_suffix (summary, ".")) as_validator_add_issue (validator, iter, "summary-has-dot-suffix", @@ -2004,7 +2011,7 @@ as_validator_validate_component_node (AsValidator *validator, AsContext *ctx, xm NULL); } else if (g_strcmp0 (node_name, "description") == 0) { - as_validator_check_appear_once (validator, iter, found_tags); + as_validator_check_appear_once (validator, iter, found_tags, true); as_validator_check_description_tag (validator, iter, mode, TRUE); } else if (g_strcmp0 (node_name, "icon") == 0) { g_autofree gchar *prop = as_validator_check_type_property (validator, cpt, iter); @@ -2051,36 +2058,37 @@ as_validator_validate_component_node (AsValidator *validator, AsContext *ctx, xm "url-not-reachable"); } else if (g_strcmp0 (node_name, "categories") == 0) { - as_validator_check_appear_once (validator, iter, found_tags); + as_validator_check_appear_once (validator, iter, found_tags, false); as_validator_check_children_quick (validator, iter, "category", FALSE); } else if (g_strcmp0 (node_name, "keywords") == 0) { as_validator_check_children_quick (validator, iter, "keyword", FALSE); if (mode == AS_FORMAT_STYLE_METAINFO) { - as_validator_check_appear_once (validator, iter, found_tags); + as_validator_check_appear_once (validator, iter, found_tags, true); as_validator_check_nolocalized (validator, iter, "metainfo-localized-keywords-tag", (const gchar*) iter->name); } } else if (g_strcmp0 (node_name, "mimetypes") == 0) { - as_validator_check_appear_once (validator, iter, found_tags); + as_validator_check_appear_once (validator, iter, found_tags, false); as_validator_check_children_quick (validator, iter, "mimetype", FALSE); as_validator_add_issue (validator, iter, "mimetypes-tag-deprecated", NULL); } else if (g_strcmp0 (node_name, "provides") == 0) { - as_validator_check_appear_once (validator, iter, found_tags); + as_validator_check_appear_once (validator, iter, found_tags, false); as_validator_check_provides (validator, iter, cpt); } else if (g_strcmp0 (node_name, "screenshots") == 0) { + as_validator_check_appear_once (validator, iter, found_tags, false); as_validator_check_screenshots (validator, iter, cpt); } else if (g_strcmp0 (node_name, "project_license") == 0) { - as_validator_check_appear_once (validator, iter, found_tags); + as_validator_check_appear_once (validator, iter, found_tags, false); as_validator_validate_project_license (validator, iter); } else if (g_strcmp0 (node_name, "project_group") == 0) { - as_validator_check_appear_once (validator, iter, found_tags); + as_validator_check_appear_once (validator, iter, found_tags, false); } else if (g_strcmp0 (node_name, "developer_name") == 0) { - as_validator_check_appear_once (validator, iter, found_tags); + as_validator_check_appear_once (validator, iter, found_tags, true); if (as_validate_has_hyperlink (node_content)) as_validator_add_issue (validator, iter, "developer-name-has-url", NULL); @@ -2092,10 +2100,11 @@ as_validator_validate_component_node (AsValidator *validator, AsContext *ctx, xm node_content); } } else if (g_strcmp0 (node_name, "releases") == 0) { + as_validator_check_appear_once (validator, iter, found_tags, false); as_validator_check_releases (validator, iter, mode); can_be_empty = TRUE; } else if (g_strcmp0 (node_name, "languages") == 0) { - as_validator_check_appear_once (validator, iter, found_tags); + as_validator_check_appear_once (validator, iter, found_tags, false); as_validator_check_children_quick (validator, iter, "lang", FALSE); } else if ((g_strcmp0 (node_name, "translation") == 0) && (mode == AS_FORMAT_STYLE_METAINFO)) { g_autofree gchar *prop = NULL; @@ -2127,27 +2136,32 @@ as_validator_validate_component_node (AsValidator *validator, AsContext *ctx, xm if (mode == AS_FORMAT_STYLE_COLLECTION) { as_validator_add_issue (validator, iter, "update-contact-in-collection-data", NULL); } else { - as_validator_check_appear_once (validator, iter, found_tags); + as_validator_check_appear_once (validator, iter, found_tags, false); as_validator_validate_update_contact (validator, iter); } } else if (g_strcmp0 (node_name, "suggests") == 0) { + as_validator_check_appear_once (validator, iter, found_tags, false); as_validator_check_children_quick (validator, iter, "id", FALSE); } else if (g_strcmp0 (node_name, "content_rating") == 0) { + as_validator_check_appear_once (validator, iter, found_tags, false); as_validator_check_children_quick (validator, iter, "content_attribute", TRUE); can_be_empty = TRUE; } else if (g_strcmp0 (node_name, "requires") == 0) { + as_validator_check_appear_once (validator, iter, found_tags, false); as_validator_check_relations (validator, iter, cpt, known_relation_items, AS_RELATION_KIND_REQUIRES); } else if (g_strcmp0 (node_name, "recommends") == 0) { + as_validator_check_appear_once (validator, iter, found_tags, false); as_validator_check_relations (validator, iter, cpt, known_relation_items, AS_RELATION_KIND_RECOMMENDS); } else if (g_strcmp0 (node_name, "supports") == 0) { + as_validator_check_appear_once (validator, iter, found_tags, false); as_validator_check_relations (validator, iter, cpt, @@ -2156,15 +2170,15 @@ as_validator_validate_component_node (AsValidator *validator, AsContext *ctx, xm } else if (g_strcmp0 (node_name, "agreement") == 0) { as_validator_check_children_quick (validator, iter, "agreement_section", FALSE); } else if (g_strcmp0 (node_name, "branding") == 0) { - as_validator_check_appear_once (validator, iter, found_tags); + as_validator_check_appear_once (validator, iter, found_tags, false); as_validator_check_branding (validator, iter); } else if (g_strcmp0 (node_name, "tags") == 0) { - as_validator_check_appear_once (validator, iter, found_tags); + as_validator_check_appear_once (validator, iter, found_tags, false); as_validator_check_tags (validator, iter); } else if (g_strcmp0 (node_name, "name_variant_suffix") == 0) { - as_validator_check_appear_once (validator, iter, found_tags); + as_validator_check_appear_once (validator, iter, found_tags, false); } else if (g_strcmp0 (node_name, "custom") == 0) { - as_validator_check_appear_once (validator, iter, found_tags); + as_validator_check_appear_once (validator, iter, found_tags, false); as_validator_check_children_quick (validator, iter, "value", FALSE); } else if ((g_strcmp0 (node_name, "metadata") == 0) || (g_strcmp0 (node_name, "kudos") == 0)) { /* these tags are GNOME / Fedora specific extensions and are therefore quite common. They shouldn't make the validation fail, From bd37e04bb0d3481a42279e955d96390e55dcaf44 Mon Sep 17 00:00:00 2001 From: JakobDev Date: Fri, 3 Jun 2022 15:29:08 +0200 Subject: [PATCH 2/5] Use gboolean instead of bool --- src/as-validator.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/as-validator.c b/src/as-validator.c index 7dcfcbb3..3ceb5e21 100644 --- a/src/as-validator.c +++ b/src/as-validator.c @@ -882,7 +882,7 @@ as_validator_check_description_tag (AsValidator *validator, xmlNode* node, AsFor * as_validator_check_appear_once: **/ static void -as_validator_check_appear_once (AsValidator *validator, xmlNode *node, GHashTable *known_tags, bool allowTranslations) +as_validator_check_appear_once (AsValidator *validator, xmlNode *node, GHashTable *known_tags, gboolean allowTranslations) { g_autofree gchar *lang = NULL; gchar *tag_id; From 80339943b0b009e28bb357ec5654e330347b4242 Mon Sep 17 00:00:00 2001 From: JakobDev Date: Fri, 3 Jun 2022 16:28:28 +0200 Subject: [PATCH 3/5] Uppercase true and false --- src/as-validator.c | 52 +++++++++++++++++++++++----------------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/src/as-validator.c b/src/as-validator.c index 3ceb5e21..1119b50c 100644 --- a/src/as-validator.c +++ b/src/as-validator.c @@ -1966,10 +1966,10 @@ as_validator_validate_component_node (AsValidator *validator, AsContext *ctx, xm /* validate the AppStream ID */ as_validator_validate_component_id (validator, iter, cpt); - as_validator_check_appear_once (validator, iter, found_tags, false); + as_validator_check_appear_once (validator, iter, found_tags, FALSE); } else if (g_strcmp0 (node_name, "metadata_license") == 0) { has_metadata_license = TRUE; - as_validator_check_appear_once (validator, iter, found_tags, false); + as_validator_check_appear_once (validator, iter, found_tags, FALSE); /* the license must allow easy mixing of metadata in metainfo files */ if (mode == AS_FORMAT_STYLE_METAINFO) @@ -1978,9 +1978,9 @@ as_validator_validate_component_node (AsValidator *validator, AsContext *ctx, xm if (g_hash_table_contains (found_tags, node_name)) as_validator_add_issue (validator, iter, "multiple-pkgname", NULL); } else if (g_strcmp0 (node_name, "source_pkgname") == 0) { - as_validator_check_appear_once (validator, iter, found_tags, false); + as_validator_check_appear_once (validator, iter, found_tags, FALSE); } else if (g_strcmp0 (node_name, "name") == 0) { - as_validator_check_appear_once (validator, iter, found_tags, true); + as_validator_check_appear_once (validator, iter, found_tags, TRUE); if (g_str_has_suffix (node_content, ".")) as_validator_add_issue (validator, iter, "name-has-dot-suffix", node_content); @@ -1988,7 +1988,7 @@ as_validator_validate_component_node (AsValidator *validator, AsContext *ctx, xm g_autofree gchar *lang = NULL; const gchar *summary = node_content; - as_validator_check_appear_once (validator, iter, found_tags, true); + as_validator_check_appear_once (validator, iter, found_tags, TRUE); if (g_str_has_suffix (summary, ".")) as_validator_add_issue (validator, iter, "summary-has-dot-suffix", @@ -2011,7 +2011,7 @@ as_validator_validate_component_node (AsValidator *validator, AsContext *ctx, xm NULL); } else if (g_strcmp0 (node_name, "description") == 0) { - as_validator_check_appear_once (validator, iter, found_tags, true); + as_validator_check_appear_once (validator, iter, found_tags, TRUE); as_validator_check_description_tag (validator, iter, mode, TRUE); } else if (g_strcmp0 (node_name, "icon") == 0) { g_autofree gchar *prop = as_validator_check_type_property (validator, cpt, iter); @@ -2058,37 +2058,37 @@ as_validator_validate_component_node (AsValidator *validator, AsContext *ctx, xm "url-not-reachable"); } else if (g_strcmp0 (node_name, "categories") == 0) { - as_validator_check_appear_once (validator, iter, found_tags, false); + as_validator_check_appear_once (validator, iter, found_tags, FALSE); as_validator_check_children_quick (validator, iter, "category", FALSE); } else if (g_strcmp0 (node_name, "keywords") == 0) { as_validator_check_children_quick (validator, iter, "keyword", FALSE); if (mode == AS_FORMAT_STYLE_METAINFO) { - as_validator_check_appear_once (validator, iter, found_tags, true); + as_validator_check_appear_once (validator, iter, found_tags, TRUE); as_validator_check_nolocalized (validator, iter, "metainfo-localized-keywords-tag", (const gchar*) iter->name); } } else if (g_strcmp0 (node_name, "mimetypes") == 0) { - as_validator_check_appear_once (validator, iter, found_tags, false); + as_validator_check_appear_once (validator, iter, found_tags, FALSE); as_validator_check_children_quick (validator, iter, "mimetype", FALSE); as_validator_add_issue (validator, iter, "mimetypes-tag-deprecated", NULL); } else if (g_strcmp0 (node_name, "provides") == 0) { - as_validator_check_appear_once (validator, iter, found_tags, false); + as_validator_check_appear_once (validator, iter, found_tags, FALSE); as_validator_check_provides (validator, iter, cpt); } else if (g_strcmp0 (node_name, "screenshots") == 0) { - as_validator_check_appear_once (validator, iter, found_tags, false); + as_validator_check_appear_once (validator, iter, found_tags, FALSE); as_validator_check_screenshots (validator, iter, cpt); } else if (g_strcmp0 (node_name, "project_license") == 0) { - as_validator_check_appear_once (validator, iter, found_tags, false); + as_validator_check_appear_once (validator, iter, found_tags, FALSE); as_validator_validate_project_license (validator, iter); } else if (g_strcmp0 (node_name, "project_group") == 0) { - as_validator_check_appear_once (validator, iter, found_tags, false); + as_validator_check_appear_once (validator, iter, found_tags, FALSE); } else if (g_strcmp0 (node_name, "developer_name") == 0) { - as_validator_check_appear_once (validator, iter, found_tags, true); + as_validator_check_appear_once (validator, iter, found_tags, TRUE); if (as_validate_has_hyperlink (node_content)) as_validator_add_issue (validator, iter, "developer-name-has-url", NULL); @@ -2100,11 +2100,11 @@ as_validator_validate_component_node (AsValidator *validator, AsContext *ctx, xm node_content); } } else if (g_strcmp0 (node_name, "releases") == 0) { - as_validator_check_appear_once (validator, iter, found_tags, false); + as_validator_check_appear_once (validator, iter, found_tags, FALSE); as_validator_check_releases (validator, iter, mode); can_be_empty = TRUE; } else if (g_strcmp0 (node_name, "languages") == 0) { - as_validator_check_appear_once (validator, iter, found_tags, false); + as_validator_check_appear_once (validator, iter, found_tags, FALSE); as_validator_check_children_quick (validator, iter, "lang", FALSE); } else if ((g_strcmp0 (node_name, "translation") == 0) && (mode == AS_FORMAT_STYLE_METAINFO)) { g_autofree gchar *prop = NULL; @@ -2136,32 +2136,32 @@ as_validator_validate_component_node (AsValidator *validator, AsContext *ctx, xm if (mode == AS_FORMAT_STYLE_COLLECTION) { as_validator_add_issue (validator, iter, "update-contact-in-collection-data", NULL); } else { - as_validator_check_appear_once (validator, iter, found_tags, false); + as_validator_check_appear_once (validator, iter, found_tags, FALSE); as_validator_validate_update_contact (validator, iter); } } else if (g_strcmp0 (node_name, "suggests") == 0) { - as_validator_check_appear_once (validator, iter, found_tags, false); + as_validator_check_appear_once (validator, iter, found_tags, FALSE); as_validator_check_children_quick (validator, iter, "id", FALSE); } else if (g_strcmp0 (node_name, "content_rating") == 0) { - as_validator_check_appear_once (validator, iter, found_tags, false); + as_validator_check_appear_once (validator, iter, found_tags, FALSE); as_validator_check_children_quick (validator, iter, "content_attribute", TRUE); can_be_empty = TRUE; } else if (g_strcmp0 (node_name, "requires") == 0) { - as_validator_check_appear_once (validator, iter, found_tags, false); + as_validator_check_appear_once (validator, iter, found_tags, FALSE); as_validator_check_relations (validator, iter, cpt, known_relation_items, AS_RELATION_KIND_REQUIRES); } else if (g_strcmp0 (node_name, "recommends") == 0) { - as_validator_check_appear_once (validator, iter, found_tags, false); + as_validator_check_appear_once (validator, iter, found_tags, FALSE); as_validator_check_relations (validator, iter, cpt, known_relation_items, AS_RELATION_KIND_RECOMMENDS); } else if (g_strcmp0 (node_name, "supports") == 0) { - as_validator_check_appear_once (validator, iter, found_tags, false); + as_validator_check_appear_once (validator, iter, found_tags, FALSE); as_validator_check_relations (validator, iter, cpt, @@ -2170,15 +2170,15 @@ as_validator_validate_component_node (AsValidator *validator, AsContext *ctx, xm } else if (g_strcmp0 (node_name, "agreement") == 0) { as_validator_check_children_quick (validator, iter, "agreement_section", FALSE); } else if (g_strcmp0 (node_name, "branding") == 0) { - as_validator_check_appear_once (validator, iter, found_tags, false); + as_validator_check_appear_once (validator, iter, found_tags, FALSE); as_validator_check_branding (validator, iter); } else if (g_strcmp0 (node_name, "tags") == 0) { - as_validator_check_appear_once (validator, iter, found_tags, false); + as_validator_check_appear_once (validator, iter, found_tags, FALSE); as_validator_check_tags (validator, iter); } else if (g_strcmp0 (node_name, "name_variant_suffix") == 0) { - as_validator_check_appear_once (validator, iter, found_tags, false); + as_validator_check_appear_once (validator, iter, found_tags, FALSE); } else if (g_strcmp0 (node_name, "custom") == 0) { - as_validator_check_appear_once (validator, iter, found_tags, false); + as_validator_check_appear_once (validator, iter, found_tags, FALSE); as_validator_check_children_quick (validator, iter, "value", FALSE); } else if ((g_strcmp0 (node_name, "metadata") == 0) || (g_strcmp0 (node_name, "kudos") == 0)) { /* these tags are GNOME / Fedora specific extensions and are therefore quite common. They shouldn't make the validation fail, From 76ac5c67d41efcebdfd3ac0ba533c6d0e26eac8b Mon Sep 17 00:00:00 2001 From: JakobDev Date: Tue, 14 Jun 2022 16:00:51 +0200 Subject: [PATCH 4/5] Do requested changes --- src/as-validator-issue-tag.h | 4 ++-- src/as-validator.c | 15 ++++++++------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/as-validator-issue-tag.h b/src/as-validator-issue-tag.h index e957a170..ad2ab09d 100644 --- a/src/as-validator-issue-tag.h +++ b/src/as-validator-issue-tag.h @@ -91,9 +91,9 @@ AsValidatorIssueTag as_validator_issue_tag_list[] = { N_("The description contains a web URL in plain text. This is not allowed, please use the tag instead to share links.") }, - { "unsupported-translation", + { "tag-not-translatable", AS_ISSUE_SEVERITY_ERROR, - N_("As per AppStream specification, the mention tag doesn't support translations.") + N_("This tag is not translatable.") }, { "tag-duplicated", diff --git a/src/as-validator.c b/src/as-validator.c index 1119b50c..c29d20ee 100644 --- a/src/as-validator.c +++ b/src/as-validator.c @@ -882,7 +882,7 @@ as_validator_check_description_tag (AsValidator *validator, xmlNode* node, AsFor * as_validator_check_appear_once: **/ static void -as_validator_check_appear_once (AsValidator *validator, xmlNode *node, GHashTable *known_tags, gboolean allowTranslations) +as_validator_check_appear_once (AsValidator *validator, xmlNode *node, GHashTable *known_tags, gboolean translatable) { g_autofree gchar *lang = NULL; gchar *tag_id; @@ -891,14 +891,16 @@ as_validator_check_appear_once (AsValidator *validator, xmlNode *node, GHashTabl /* generate tag-id to make a unique identifier for localized and unlocalized tags */ node_name = (const gchar*) node->name; lang = as_xml_get_prop_value (node, "lang"); - if (lang == NULL) + if (lang == NULL) { tag_id = g_strdup (node_name); + } else { - if (!allowTranslations) { - as_validator_add_issue (validator, node, "unsupported-translation", node_name); + if (translatable) { + tag_id = g_strdup_printf ("%s (lang=%s)", node_name, lang); + } else { + tag_id = g_strdup (node_name); + as_validator_add_issue (validator, node, "tag-not-translatable", node_name); } - - tag_id = g_strdup_printf ("%s (lang=%s)", node_name, lang); } if (g_hash_table_contains (known_tags, tag_id)) { @@ -1965,7 +1967,6 @@ as_validator_validate_component_node (AsValidator *validator, AsContext *ctx, xm /* validate the AppStream ID */ as_validator_validate_component_id (validator, iter, cpt); - as_validator_check_appear_once (validator, iter, found_tags, FALSE); } else if (g_strcmp0 (node_name, "metadata_license") == 0) { has_metadata_license = TRUE; From d407da368e00d5cef5edb6d09fc53bee6268d99a Mon Sep 17 00:00:00 2001 From: JakobDev Date: Tue, 14 Jun 2022 16:36:33 +0200 Subject: [PATCH 5/5] Put closing bracket and else in one line --- src/as-validator.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/as-validator.c b/src/as-validator.c index c29d20ee..01ea0a0e 100644 --- a/src/as-validator.c +++ b/src/as-validator.c @@ -893,8 +893,7 @@ as_validator_check_appear_once (AsValidator *validator, xmlNode *node, GHashTabl lang = as_xml_get_prop_value (node, "lang"); if (lang == NULL) { tag_id = g_strdup (node_name); - } - else { + } else { if (translatable) { tag_id = g_strdup_printf ("%s (lang=%s)", node_name, lang); } else {