halcc: Make parser maintain hal to have the latest version 08/310508/2
authorYoungjae Cho <y0.cho@samsung.com>
Tue, 30 Apr 2024 04:44:38 +0000 (13:44 +0900)
committerYoungjae Cho <y0.cho@samsung.com>
Tue, 30 Apr 2024 05:46:53 +0000 (14:46 +0900)
If halcc parser picks a hal that can be covered by hal that has been
parsed before, put the hal back. Here 'cover' means that one can
supports the other in terms of backward compatibility, for example,
v2.3 covers v2.0~v2.3. On the other hand, if a hal being picked can
cover a hal that has been parsed before, the previous hal is replaced
with the newly picked one.

Change-Id: Ie273d5065e53cd541b5edb3138b97f3c3deb1ff7
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 a8bd8fbcec1cc96f4e0eb48bb6976af6bcd5de8d..57f0754c8dcb2cdec7e9704bdab49b27b23a7e75 100644 (file)
@@ -197,7 +197,8 @@ static halcc_hal* hashtable_hal_lookup(GHashTable *hal_table,
        return g_hash_table_lookup(hal_table, &key);
 }
 
-static halcc_hal* hashtable_hal_steal(GHashTable *hal_table, const char *name, int major, int minor)
+static halcc_hal* hashtable_hal_steal(GHashTable *hal_table,
+       const char *name, int major, int minor, halcc_hash_compare_type_e type)
 {
        hash_hal_key key;
        halcc_hal *hal = NULL;
@@ -207,7 +208,7 @@ static halcc_hal* hashtable_hal_steal(GHashTable *hal_table, const char *name, i
                return NULL;
        }
 
-       key = HASH_HAL_KEY(name, major, minor, HALCC_HASH_COMPARE_TYPE_EXACT_MINOR_VERSION);
+       key = HASH_HAL_KEY(name, major, minor, type);
 
        if (!g_hash_table_steal_extended(hal_table, &key, NULL, (gpointer*) &hal))
                return NULL;
@@ -530,26 +531,48 @@ int halcc_manifest_find_hal_forward_compatible_raw(halcc_manifest *manifest,
                raw->name, raw->version.major, raw->version.minor, hal);
 }
 
-int halcc_manifest_steal_hal(halcc_manifest *manifest,
-       const char *hal_name, int major, int minor, halcc_hal **hal)
+static int manifest_steal_hal(halcc_manifest *manifest,
+       const char *hal_name, int major, int minor, halcc_hal **hal,
+       halcc_hash_compare_type_e type)
 {
        halcc_hal *h = NULL;
 
-       if (!manifest || !hal_name) {
+       if (!manifest || !hal_name || !hal) {
                printf("Invalid parameter\n");
                return -EINVAL;
        }
 
-       h = hashtable_hal_steal(manifest->hals, hal_name, major, minor);
+       h = hashtable_hal_steal(manifest->hals, hal_name, major, minor, type);
        if (!h) {
-               printf("Failed to find hal=%s@%d.%d\n", hal_name, major, minor);
+               printf("Failed to find hal=%s@%d.%d, type=%d\n", hal_name, major, minor, type);
                return -ENOTSUP;
        }
 
-       if (hal)
-               *hal = g_steal_pointer(&h);
+       *hal = g_steal_pointer(&h);
 
        return 0;
+
+}
+
+int halcc_manifest_steal_hal(halcc_manifest *manifest,
+       const char *hal_name, int major, int minor, halcc_hal **hal)
+{
+       return manifest_steal_hal(manifest,
+               hal_name, major, minor, hal, HALCC_HASH_COMPARE_TYPE_EXACT_MINOR_VERSION);
+}
+
+int halcc_manifest_steal_hal_backward_compatible(halcc_manifest *manifest,
+       const char *hal_name, int major, int minor, halcc_hal **hal)
+{
+       return manifest_steal_hal(manifest,
+               hal_name, major, minor, hal, HALCC_HASH_COMPARE_TYPE_BACKWARD_MINOR_VERSION);
+}
+
+int halcc_manifest_steal_hal_forward_compatible(halcc_manifest *manifest,
+       const char *hal_name, int major, int minor, halcc_hal **hal)
+{
+       return manifest_steal_hal(manifest,
+               hal_name, major, minor, hal, HALCC_HASH_COMPARE_TYPE_FORWARD_MINOR_VERSION);
 }
 
 void halcc_manifest_remove_hal(halcc_manifest *manifest,
index e00c1a1b910c8ed7a4887a2a8650c919d872b361..c18fa9cd6a5820c1a0b36779d821807b1d7f971f 100644 (file)
@@ -70,6 +70,10 @@ int halcc_manifest_find_hal_forward_compatible_raw(halcc_manifest *manifest,
        halcc_hal *raw, halcc_hal **hal);
 int halcc_manifest_steal_hal(halcc_manifest *manifest,
        const char *hal_name, int major, int minor, halcc_hal **hal);
+int halcc_manifest_steal_hal_backward_compatible(halcc_manifest *manifest,
+       const char *hal_name, int major, int minor, halcc_hal **hal);
+int halcc_manifest_steal_hal_forward_compatible(halcc_manifest *manifest,
+       const char *hal_name, int major, int minor, halcc_hal **hal);
 void halcc_manifest_remove_hal(halcc_manifest *manifest,
        const char *hal_name, int major, int minor);
 void halcc_manifest_foreach_hal(halcc_manifest *manifest,
index f2e1f2c7eae8b75807a6f9c2728ce2efb9ad9c02..4146191c88a5272e7a427f0752bcf8da327d5bea 100644 (file)
@@ -224,6 +224,10 @@ static int parse_manifest(xmlNode *node, halcc_manifest *manifest)
 
        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;
@@ -242,6 +246,32 @@ static int parse_manifest(xmlNode *node, halcc_manifest *manifest)
                        continue;
                }
 
+               halcc_hal_get_name(h, &hal_name);
+               halcc_hal_get_version(h, &hal_major, &hal_minor, NULL);
+
+               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);
index 5198e27d8350467c36518d1da07f93f90eadca20..960629cc08a0eb0b6ffcf6ab9581edfd57087ba9 100644 (file)
@@ -69,6 +69,18 @@ static char g_manifest_xml[] =
 "                      </interface>"
 "              </hal>"
 "      </manifest>"
+"      <manifest version=\"1.0\" type=\"platform\">"
+"              <hal>"
+"                      <name>HAL_MODULE_BAR</name>"
+"                      <version>2.0</version>"
+"              </hal>"
+"      </manifest>"
+"      <manifest version=\"1.0\" type=\"platform\">"
+"              <hal>"
+"                      <name>HAL_MODULE_BAR</name>"
+"                      <version>2.2</version>"
+"              </hal>"
+"      </manifest>"
 "</root>";
 
 class HalccObjectTest : public ::testing::Test
@@ -223,3 +235,26 @@ 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, NULL);
+       ASSERT_EQ(ret, 0);
+       ASSERT_EQ(major, 2);
+       ASSERT_EQ(minor, 2);
+}