From 3cefab742687dfc2a105a619ffcab934eeb1a5cf Mon Sep 17 00:00:00 2001
From: Dmitri Pal <dpal@redhat.com>
Date: Wed, 5 Dec 2012 11:29:39 -0500
Subject: [PATCH 04/10] [INI] Merge comments from different values

Patch allows merging comments that are part of the two different
value objects. The values are not merged.
---
 ini/ini_valueobj.c    |   77 ++++++++++++++++++++++++------------------
 ini/ini_valueobj.h    |    4 ++
 ini/ini_valueobj_ut.c |   88 +++++++++++++++++++++++++++++++++++++++++++++++-
 3 files changed, 134 insertions(+), 35 deletions(-)

diff --git a/ini/ini_valueobj.c b/ini/ini_valueobj.c
index fe6599c867623590a5b9170e6cecd74ffdd2f336..e0c8d9861ec71ccd6b9889dbda37bda67aa9220d 100644
--- a/ini/ini_valueobj.c
+++ b/ini/ini_valueobj.c
@@ -943,10 +943,8 @@ int value_serialize(struct value_obj *vo,
                     struct simplebuffer *sbobj)
 {
     int error = EOK;
-    uint32_t num = 0;
     uint32_t i = 0;
     uint32_t len = 0;
-    char *commentline = NULL;
     char *ptr = NULL;
     char *part = NULL;
     int sec = 0;
@@ -962,40 +960,11 @@ int value_serialize(struct value_obj *vo,
 
     /* Put comment first */
     if (vo->ic) {
-
-        /* Get number of lines in the comment */
-        error = ini_comment_get_numlines(vo->ic, &num);
+        error = ini_comment_serialize(vo->ic, sbobj);
         if (error) {
-            TRACE_ERROR_NUMBER("Failed to get number of lines", errno);
+            TRACE_ERROR_NUMBER("Failed serialize comment", error);
             return error;
         }
-
-        for (i = 0; i < num; i++) {
-
-            len = 0;
-            commentline = NULL;
-
-            error = ini_comment_get_line(vo->ic, i, &commentline, &len);
-            if (error) {
-                TRACE_ERROR_NUMBER("Failed to get number of lines", errno);
-                return error;
-            }
-
-            error = simplebuffer_add_raw(sbobj,
-                                         commentline,
-                                         len,
-                                         INI_VALUE_BLOCK);
-            if (error) {
-                TRACE_ERROR_NUMBER("Failed to add comment", error);
-                return error;
-            }
-
-            error = simplebuffer_add_cr(sbobj);
-            if (error) {
-                TRACE_ERROR_NUMBER("Failed to add CR", error);
-                return error;
-            }
-        }
     }
 
     if (strncmp(key, INI_SPECIAL_KEY, sizeof(INI_SPECIAL_KEY)) == 0) {
@@ -1120,6 +1089,48 @@ extern void ref_array_debug(struct ref_array *ra, int num);
     return error;
 }
 
+/* Merge comment from one value into another */
+int value_merge_comment(struct value_obj *vo_donor,
+                        struct value_obj *vo)
+{
+    int error = EOK;
+
+    TRACE_FLOW_ENTRY();
+
+    if ((!vo) || (!vo_donor)) {
+        TRACE_ERROR_NUMBER("Invalid input parameter", EINVAL);
+        return EINVAL;
+    }
+
+    if (vo_donor->ic) {
+
+        /* If there is something to add */
+
+        if (vo->ic) {
+
+            /* Merge comments if both present */
+            error = ini_comment_add(vo_donor->ic, vo->ic);
+            if (error) {
+                TRACE_ERROR_NUMBER("Failed to merge the comment", error);
+                return error;
+            }
+        }
+        else {
+
+            /* Copy comment if only donor present */
+            error = ini_comment_copy(vo_donor->ic, &(vo->ic));
+            if (error) {
+                TRACE_ERROR_NUMBER("Failed to merge the comment", error);
+                return error;
+            }
+        }
+    }
+
+    TRACE_FLOW_EXIT();
+    return error;
+}
+
+
 /* Print value */
 void value_print(const char *key, struct value_obj *vo)
 {
diff --git a/ini/ini_valueobj.h b/ini/ini_valueobj.h
index cbecc753ec1479510b37fece6885bc1d0b4b7a28..865c94b4ddef11807b54b5acc89da26232c9ad31 100644
--- a/ini/ini_valueobj.h
+++ b/ini/ini_valueobj.h
@@ -132,6 +132,10 @@ int value_extract_comment(struct value_obj *vo,
 int value_put_comment(struct value_obj *vo,
                       struct ini_comment *ic);
 
+/* Merge comment from one value into another */
+int value_merge_comment(struct value_obj *vo_donor,
+                        struct value_obj *vo);
+
 /* Serialize value */
 int value_serialize(struct value_obj *vo,
                     const char *key,
diff --git a/ini/ini_valueobj_ut.c b/ini/ini_valueobj_ut.c
index e4fc6b43c07eacfaf829df2e6294b4dae3be87fe..05f649b4455d76f295259889eedd535f074a0907 100644
--- a/ini/ini_valueobj_ut.c
+++ b/ini/ini_valueobj_ut.c
@@ -405,7 +405,7 @@ int vo_basic_test(void)
         ic = NULL;
         error = create_comment(wrap, &ic);
         if (error) {
-            printf("Failed to create a new value object %d.\n", error);
+            printf("Failed to create a new comment object %d.\n", error);
             fclose(ff);
             return error;
         }
@@ -461,7 +461,7 @@ int vo_basic_test(void)
     ic = NULL;
     error = create_comment(100, &ic);
     if (error) {
-        printf("Failed to create a new value object %d.\n", error);
+        printf("Failed to create a new comment object %d.\n", error);
         fclose(ff);
         return error;
     }
@@ -625,6 +625,89 @@ int vo_show_test(void)
     return EOK;
 }
 
+int vo_mc_test(void)
+{
+    int error = EOK;
+    struct value_obj *vo1 = NULL;
+    struct value_obj *vo2 = NULL;
+    struct ini_comment *ic = NULL;
+
+    TRACE_FLOW_ENTRY();
+
+    VOOUT(printf("<=== Merge Comment Test ===>\n"));
+
+    error = create_comment(1, &ic);
+    if (error) {
+        printf("Failed to create a new comment object %d.\n", error);
+        return error;
+    }
+
+    error = value_create_new("test1",
+                             5,
+                             INI_VALUE_CREATED,
+                             3,
+                             80,
+                             ic,
+                             &vo1);
+    if (error) {
+        printf("Failed to create the first value object %d.\n", error);
+        ini_comment_destroy(ic);
+        return error;
+    }
+
+    error = create_comment(2, &ic);
+    if (error) {
+        printf("Failed to create a new comment object %d.\n", error);
+        value_destroy(vo1);
+        return error;
+    }
+
+    error = value_create_new("test2",
+                             5,
+                             INI_VALUE_CREATED,
+                             3,
+                             80,
+                             ic,
+                             &vo2);
+    if (error) {
+        printf("Failed to create the second value object %d.\n", error);
+        ini_comment_destroy(ic);
+        value_destroy(vo1);
+        return error;
+    }
+
+    /* Merge comment from one value into another */
+    error = value_merge_comment(vo2, vo1);
+    if (error) {
+        printf("Failed to merge comments %d.\n", error);
+        value_destroy(vo1);
+        value_destroy(vo2);
+        return error;
+    }
+
+    value_destroy(vo2);
+
+    VOOUT(printf("<=== Key ===>\n"));
+    VOOUT(value_print("key", vo1));
+
+    error = value_extract_comment(vo1, &ic);
+    if (error) {
+        printf("Failed to extract comment %d.\n", error);
+        value_destroy(vo1);
+        return error;
+    }
+
+    value_destroy(vo1);
+
+    VOOUT(printf("<=== Comment ===>\n"));
+    VOOUT(ini_comment_print(ic, stdout));
+    ini_comment_destroy(ic);
+
+    TRACE_FLOW_EXIT();
+    return EOK;
+}
+
+
 /* Main function of the unit test */
 int main(int argc, char *argv[])
 {
@@ -632,6 +715,7 @@ int main(int argc, char *argv[])
     test_fn tests[] = { vo_basic_test,
                         vo_copy_test,
                         vo_show_test,
+                        vo_mc_test,
                         NULL };
     test_fn t;
     int i = 0;
-- 
1.7.1

