From 0c39a8b6d1a1473495da1e8e9da60f6f4fb88134 Mon Sep 17 00:00:00 2001
From: Dmitri Pal <dpal@redhat.com>
Date: Sat, 27 Nov 2010 23:51:40 -0500
Subject: [PATCH] [INI] Preparing to merge sections

* Rearranged code in parser module and
  created a skeleton of the function that will
  be responcible for merging sections.
* Added missing static declarations to some functions.
---
 ini/ini_parse.c |   97 +++++++++++++++++++++++++++++++++++-------------------
 1 files changed, 63 insertions(+), 34 deletions(-)

diff --git a/ini/ini_parse.c b/ini/ini_parse.c
index acdb6081e734baec80967adb2a46c299c2d029fd..26dc43fe0ade0262455d8811d8375eef2fc6df56 100644
--- a/ini/ini_parse.c
+++ b/ini/ini_parse.c
@@ -110,7 +110,7 @@ int is_just_spaces(const char *str, uint32_t len)
 
 
 /* Destroy parser object */
-void parser_destroy(struct parser_obj *po)
+static void parser_destroy(struct parser_obj *po)
 {
     TRACE_FLOW_ENTRY();
 
@@ -133,14 +133,14 @@ void parser_destroy(struct parser_obj *po)
  * It assumes that the ini collection
  * has been precreated.
  */
-int parser_create(FILE *file,
-                  const char *config_filename,
-                  struct collection_item *ini_config,
-                  int error_level,
-                  uint32_t collision_flags,
-                  struct collection_item *error_list,
-                  uint32_t boundary,
-                  struct parser_obj **po)
+static int parser_create(FILE *file,
+                         const char *config_filename,
+                         struct collection_item *ini_config,
+                         int error_level,
+                         uint32_t collision_flags,
+                         struct collection_item *error_list,
+                         uint32_t boundary,
+                         struct parser_obj **po)
 {
     int error = EOK;
     struct parser_obj *new_po = NULL;
@@ -217,7 +217,7 @@ int parser_create(FILE *file,
 }
 
 /* Function to read next line from the file */
-int parser_read(struct parser_obj *po)
+static int parser_read(struct parser_obj *po)
 {
     int error = EOK;
     char *buffer = NULL;
@@ -299,6 +299,36 @@ int parser_read(struct parser_obj *po)
     return EOK;
 }
 
+/* Function to read next line from the file */
+static int parser_save_section(struct parser_obj *po)
+{
+    int error = EOK;
+
+    TRACE_FLOW_ENTRY();
+
+    if (po->sec) {
+
+        /* For now just add as we did.
+         * Add merge code here !!!!
+         */
+        error = col_add_collection_to_collection(po->top,
+                                                 NULL, NULL,
+                                                 po->sec,
+                                                 COL_ADD_MODE_EMBED);
+
+        if (error) {
+            TRACE_ERROR_NUMBER("Failed to embed section", error);
+            return error;
+        }
+
+        po->sec = NULL;
+    }
+
+    TRACE_FLOW_EXIT();
+    return EOK;
+
+}
+
 /* Complete value processing */
 static int complete_value_processing(struct parser_obj *po)
 {
@@ -721,18 +751,11 @@ static int handle_section(struct parser_obj *po, uint32_t *action)
         }
     }
 
-    /* Do we have an active section? */
-    if (po->sec) {
-        /* Save it */
-        error = col_add_collection_to_collection(po->top,
-                                                 NULL, NULL,
-                                                 po->sec,
-                                                 COL_ADD_MODE_EMBED);
-        if (error) {
-            TRACE_ERROR_NUMBER("Failed to save section", error);
-            return error;
-        }
-        po->sec = NULL;
+    /* Save section if we have one*/
+    error = parser_save_section(po);
+    if (error) {
+        TRACE_ERROR_NUMBER("Failed to save section", error);
+        return error;
     }
 
     /* Dup the name */
@@ -780,6 +803,9 @@ static int handle_section(struct parser_obj *po, uint32_t *action)
         return error;
     }
 
+    /* Save the line number of the last found key */
+    po->keylinenum = po->linenum;
+
     /* Complete processing of this value */
     error = complete_value_processing(po);
     if (error) {
@@ -887,17 +913,12 @@ static int parser_post(struct parser_obj *po)
     }
 
     /* If we are done save the section */
-    error = col_add_collection_to_collection(po->top,
-                                                NULL, NULL,
-                                                po->sec,
-                                                COL_ADD_MODE_EMBED);
+    error = parser_save_section(po);
     if (error) {
         TRACE_ERROR_NUMBER("Failed to save section", error);
         return error;
     }
 
-    po->sec = NULL;
-
     /* Move to the next action */
     error = col_enqueue_unsigned_property(po->queue,
                                           PARSE_ACTION,
@@ -973,15 +994,23 @@ static int parser_error(struct parser_obj *po)
     }
     else {
         /* If we are done save the section */
-        error = col_add_collection_to_collection(po->top,
-                                                 NULL, NULL,
-                                                 po->sec,
-                                                 COL_ADD_MODE_EMBED);
+        error = parser_save_section(po);
         if (error) {
             TRACE_ERROR_NUMBER("Failed to save section", error);
-            return error;
+            /* If merging sections should produce error and we got error
+             * or if we merge sections but dup values produce error and
+             * we got error then it is not a fatal error so we need to handle
+             * it nicely. We check for reverse condition and return error,
+             * otherwise fall through.
+             */
+            if (!((((po->collision_flags & INI_MS_MASK) == INI_MS_ERROR) &&
+                 (error == EEXIST)) ||
+                (((po->collision_flags & INI_MS_MASK) == INI_MS_MERGE) &&
+                 ((po->collision_flags & INI_MV2S_MASK) == INI_MV2S_ERROR) &&
+                 (error == EEXIST)))) {
+                return error;
+            }
         }
-        po->sec = NULL;
     }
 
     /* Move to the next action */
-- 
1.5.5.6

