From: Youngjae Cho Date: Mon, 13 May 2024 05:49:01 +0000 (+0900) Subject: halcc: Fix parser to accept multiple version for hal X-Git-Tag: accepted/tizen/unified/20240611.122614~10 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=c089db2ff962d42c810bde5ed0ee75fa5e2fa26b;p=platform%2Fhal%2Fapi%2Fcommon.git halcc: Fix parser to accept multiple version for hal Make halcc_hal manage multiple version internally. The parser accepts versions whenever it meets element, consumes and updates version list of halcc_hal. Currently, the only first incoming version is set as version of a hal, and all of the version-related operations works on top if it. This is for making the whole code work in the current structure, but it will be fixed to take the entire version list into account when it counts compatibility. Change-Id: I6b95a7692fc2ffbe3630db04b94dd6dc0f3a66cc Signed-off-by: Youngjae Cho --- diff --git a/src/hal-api-compatibility-checker-object.c b/src/hal-api-compatibility-checker-object.c index d327425..7fc33c5 100644 --- a/src/hal-api-compatibility-checker-object.c +++ b/src/hal-api-compatibility-checker-object.c @@ -29,6 +29,7 @@ #include "hal-api-compatibility-checker-util.h" #define HALCC_TRANSPORT_DEFAULT HALCC_TRANSPORT_PASSTHROUGH +#define MAX_NUM_VERSION 8 typedef struct halcc_version { int major; @@ -42,6 +43,8 @@ typedef struct halcc_interface { typedef struct halcc_hal { char *name; + halcc_version version_list[MAX_NUM_VERSION]; + int num_version; halcc_version version; halcc_transport_e transport; GHashTable *interfaces; @@ -57,6 +60,7 @@ typedef enum halcc_hash_compare_type_e { HALCC_HASH_COMPARE_TYPE_BACKWARD_MINOR_VERSION, HALCC_HASH_COMPARE_TYPE_EXACT_MINOR_VERSION, HALCC_HASH_COMPARE_TYPE_FORWARD_MINOR_VERSION, + HALCC_HASH_COMPARE_TYPE_ANY_VERSION, } halcc_hash_compare_type_e; typedef struct hash_hal_key { @@ -118,11 +122,14 @@ static gboolean hal_hash_equal(gconstpointer a, gconstpointer b) if (strncmp(hal->name, key->hal.name, strlen(hal->name) + 1) != 0) return false; + compare_type = key->compare_type; + + if (compare_type == HALCC_HASH_COMPARE_TYPE_ANY_VERSION) + return true; + if (hal->version.major != key->hal.version.major) return false; - compare_type = key->compare_type; - switch (compare_type) { case HALCC_HASH_COMPARE_TYPE_EXACT_MINOR_VERSION: return hal->version.minor == key->hal.version.minor; @@ -454,6 +461,29 @@ int halcc_manifest_find_hal(halcc_manifest *manifest, return 0; } +int halcc_manifest_find_hal_by_name(halcc_manifest *manifest, + const char *hal_name, halcc_hal **hal) +{ + halcc_hal *h; + + if (!manifest || !hal_name) { + printf("Invalid parameter\n"); + return -EINVAL; + } + + h = hashtable_hal_lookup(manifest->hals, + hal_name, 0, 0, HALCC_HASH_COMPARE_TYPE_ANY_VERSION); + if (!h) { + printf("Failed to find hal=%s\n", hal_name); + return -ENOTSUP; + } + + if (hal) + *hal = g_steal_pointer(&h); + + return 0; +} + int halcc_manifest_find_hal_raw(halcc_manifest *manifest, halcc_hal *raw, halcc_hal **hal) { @@ -660,15 +690,51 @@ int halcc_hal_get_name(halcc_hal *hal, const char **hal_name) return 0; } + +/** + * FIXME: It manages list of versions internally, but it only + * exposes the first incoming version as a representative version for the hal, + * and the halcc_hal_get_version(), in turn, will return the version. + * This will be fixed to manage the entire list for counting compatibility. + */ int halcc_hal_set_version(halcc_hal *hal, int major, int minor) { + int i; + if (!hal) { printf("Invalid parameter\n"); return -EINVAL; } - hal->version.major = major; - hal->version.minor = minor; + assert(hal->num_version <= MAX_NUM_VERSION); + + + /* FIXME: Only the first incoming version sets hal version */ + if (hal->num_version == 0) { + hal->version.major = major; + hal->version.minor = minor; + } + + for (i = 0; i < hal->num_version; ++i) { + if (hal->version_list[i].major != major) + continue; + + if (hal->version_list[i].minor < minor) + hal->version_list[i].minor = minor; /* update */ + + break; + } + + if (hal->num_version > i) + return 0; + + if (hal->num_version >= MAX_NUM_VERSION) + return -EOVERFLOW; + + hal->version_list[hal->num_version].major = major; + hal->version_list[hal->num_version].minor = minor; + + hal->num_version += 1; return 0; } diff --git a/src/hal-api-compatibility-checker-object.h b/src/hal-api-compatibility-checker-object.h index bfd9f60..6206f92 100644 --- a/src/hal-api-compatibility-checker-object.h +++ b/src/hal-api-compatibility-checker-object.h @@ -51,6 +51,8 @@ int halcc_manifest_get_version(halcc_manifest *manifest, int *major, int *minor) int halcc_manifest_add_hal(halcc_manifest *manifest, halcc_hal *hal); int halcc_manifest_find_hal(halcc_manifest *manifest, const char *hal_name, int major, int minor, halcc_hal **hal); +int halcc_manifest_find_hal_by_name(halcc_manifest *manifest, + const char *hal_name, halcc_hal **hal); int halcc_manifest_find_hal_raw(halcc_manifest *manifest, halcc_hal *raw, halcc_hal **hal); int halcc_manifest_find_hal_backward_compatible(halcc_manifest *manifest, diff --git a/src/hal-api-compatibility-checker-parser.c b/src/hal-api-compatibility-checker-parser.c index 1075c78..9a4485b 100644 --- a/src/hal-api-compatibility-checker-parser.c +++ b/src/hal-api-compatibility-checker-parser.c @@ -58,12 +58,14 @@ static int parse_interface(xmlNode *node, halcc_interface *interface) return 0; } -static int parse_hal(xmlNode *node, halcc_hal *hal) +static int parse_hal(xmlNode *node, halcc_manifest *manifest) { int ret = 0; + halcc_hal *hal; + __xmlchar__ xmlChar *hal_name = NULL; assert(node); - assert(hal); + assert(manifest); if (!xmlStrEqual(node->name, "hal")) { printf("Invalid hal node, %s\n", node->name); @@ -72,12 +74,37 @@ static int parse_hal(xmlNode *node, halcc_hal *hal) for (xmlNode *child = node->children; child; child = child->next) { if (xmlStrEqual(child->name, "name")) { - __xmlchar__ xmlChar *name = xmlNodeGetContent(child); + hal_name = xmlNodeGetContent(child); + break; + } + } - ret = halcc_hal_set_name(hal, name); - if (ret != 0) - printf("Failed to halcc_hal_set_name(), name=%s, ret=%d\n", name, ret); - } else if (xmlStrEqual(child->name, "version")) { + if (!hal_name) { + printf("Invalid hal node, name is unspecified\n"); + return -EINVAL; + } + + ret = halcc_manifest_find_hal_by_name(manifest, hal_name, &hal); + if (ret != 0) { + ret = halcc_hal_new(&hal); + if (ret != 0) { + printf("Failed to halcc_hal_new(), ret=%d\n", ret); + return ret; + } + + halcc_hal_set_name(hal, hal_name); + + ret = halcc_manifest_add_hal(manifest, hal); + if (ret != 0) { + printf("Failed to halcc_manifest_add_hal(), ret=%d\n", ret); + halcc_hal_free(hal); + hal = NULL; + return ret; + } + } + + for (xmlNode *child = node->children; child; child = child->next) { + if (xmlStrEqual(child->name, "version")) { int major, minor; int scanned; __xmlchar__ xmlChar *version = xmlNodeGetContent(child); @@ -195,64 +222,11 @@ static int parse_manifest(xmlNode *node, halcc_manifest *manifest) return ret; for (xmlNode *child = node->children; child; child = child->next) { - halcc_hal *h; - const char *hal_name; - int hal_major; - int hal_minor; - halcc_hal *hal_backward_compatible = NULL; - - if (!xmlStrEqual(child->name, "hal")) - continue; - - ret = halcc_hal_new(&h); - if (ret != 0) { - printf("Failed to halcc_hal_new(), ret=%d\n", ret); - continue; - } + int ret; - ret = parse_hal(child, h); - if (ret != 0) { + ret = parse_hal(child, manifest); + if (ret != 0) printf("Failed to parse_hal(), ret=%d\n", ret); - halcc_hal_free(h); - h = NULL; - continue; - } - - halcc_hal_get_name(h, &hal_name); - halcc_hal_get_version(h, &hal_major, &hal_minor); - - if (halcc_manifest_find_hal(manifest, hal_name, hal_major, hal_minor, NULL) == 0) { - halcc_hal_free(h); - h = NULL; - continue; - } - - if (halcc_manifest_find_hal_forward_compatible(manifest, - hal_name, hal_major, hal_minor, NULL) == 0) { - halcc_hal_free(h); - h = NULL; - continue; - } - - /** - * Backward compatible hal can be covered by the current hal. - * Therefore, remove it from the manifest. - */ - if (halcc_manifest_steal_hal_backward_compatible(manifest, - hal_name, hal_major, hal_minor, &hal_backward_compatible) == 0) { - halcc_hal_free(hal_backward_compatible); - hal_backward_compatible = NULL; - } - - ret = halcc_manifest_add_hal(manifest, h); - if (ret != 0) { - printf("Failed to halcc_manifest_add_hal(), ret=%d\n", ret); - halcc_hal_free(h); - h = NULL; - continue; - } - - h = NULL; } return 0; diff --git a/tests/unittest/test-hal-compatibility-checker.cc b/tests/unittest/test-hal-compatibility-checker.cc index 914c589..d594926 100644 --- a/tests/unittest/test-hal-compatibility-checker.cc +++ b/tests/unittest/test-hal-compatibility-checker.cc @@ -217,26 +217,3 @@ TEST_F(HalccObjectTest, manifest_find_hal_steal_success) ASSERT_EQ(major, 2); ASSERT_EQ(minor, 34); } - -TEST_F(HalccObjectTest, manifest_find_multiple_hal_success) -{ - halcc_hal *hal = NULL; - const char *hal_name; - int major, minor; - int ret; - - ret = halcc_manifest_find_hal(g_manifest, "HAL_MODULE_BAR", 2, 0, &hal); - ASSERT_NE(ret, 0); // The 2.0 has been replaced with 2.2 - - ret = halcc_manifest_find_hal_forward_compatible(g_manifest, "HAL_MODULE_BAR", 2, 0, &hal); - ASSERT_EQ(ret, 0); // 2.0 is covered by 2.2 - - ret = halcc_hal_get_name(hal, &hal_name); - ASSERT_EQ(ret, 0); - ASSERT_STREQ(hal_name, "HAL_MODULE_BAR"); - - ret = halcc_hal_get_version(hal, &major, &minor); - ASSERT_EQ(ret, 0); - ASSERT_EQ(major, 2); - ASSERT_EQ(minor, 2); -}