halcc: Fix parser to accept multiple version for hal 78/311178/1
authorYoungjae Cho <y0.cho@samsung.com>
Mon, 13 May 2024 05:49:01 +0000 (14:49 +0900)
committerYoungjae Cho <y0.cho@samsung.com>
Mon, 13 May 2024 07:57:50 +0000 (16:57 +0900)
 Make halcc_hal manage multiple version internally. The parser accepts
versions whenever it meets <version> 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 <y0.cho@samsung.com>
src/hal-api-compatibility-checker-object.c
src/hal-api-compatibility-checker-object.h
src/hal-api-compatibility-checker-parser.c
tests/unittest/test-hal-compatibility-checker.cc

index d327425713b1bd81e968018fd4935324595910cd..7fc33c5df20a7386e1804bd5eb5572f80377d614 100644 (file)
@@ -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;
 }
index bfd9f60023365cfad2e2597a29369395acbf6cb2..6206f92b8bb5689fb356fd3c52b36eb51eb01ba6 100644 (file)
@@ -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,
index 1075c784972094a5f2a94c835843251ab690833e..9a4485bfd72d48b2b0fa3ecd4f788f16c2d0af54 100644 (file)
@@ -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;
index 914c58942e702586f224e1a0ead82e3ca2bdd835..d594926a399be9d2800662d7eb6e32e014c161d5 100644 (file)
@@ -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);
-}