diff options
author | Dmitri Pal <dpal@redhat.com> | 2010-12-25 23:56:51 -0500 |
---|---|---|
committer | Stephen Gallagher <sgallagh@redhat.com> | 2012-04-05 11:20:08 -0700 |
commit | f1a030e074610675f8b978aad30ad2fb1676dffc (patch) | |
tree | 6efa55e93db137d32197411dfc5b20cd86de6969 /ini | |
parent | 6c6fdda6b4353869fc2c4fc9c8bdc29badfd10d7 (diff) | |
download | ding-libs2-f1a030e074610675f8b978aad30ad2fb1676dffc.tar.gz ding-libs2-f1a030e074610675f8b978aad30ad2fb1676dffc.tar.xz ding-libs2-f1a030e074610675f8b978aad30ad2fb1676dffc.zip |
Preparing for merging sections
Patch implements three functions:
* Function to detect a collision between two section names.
* Function to empty section from all its keys
* Function to add values one by one from one section to
another.
Diffstat (limited to 'ini')
-rw-r--r-- | ini/ini_parse.c | 177 |
1 files changed, 177 insertions, 0 deletions
diff --git a/ini/ini_parse.c b/ini/ini_parse.c index 95c3d91..4dab4b6 100644 --- a/ini/ini_parse.c +++ b/ini/ini_parse.c @@ -318,6 +318,183 @@ static int parser_read(struct parser_obj *po) return EOK; } +/* Find if there is a collistion */ +static int check_section_collision(struct parser_obj *po) +{ + int error = EOK; + struct collection_item *item = NULL; + + TRACE_FLOW_ENTRY(); + + TRACE_INFO_STRING("Searching for:", col_get_item_property(po->sec, NULL)); + + error = col_get_item(po->top, + col_get_item_property(po->sec, NULL), + COL_TYPE_ANY, + COL_TRAVERSE_DEFAULT, + &item); + + if (error) { + TRACE_ERROR_NUMBER("Failed searching for dup", error); + return error; + } + + /* Check if there is a dup */ + if (item) { + TRACE_INFO_STRING("Collision found:", + col_get_item_property(item, NULL)); + /* Get the actual section collection instead of reference */ + po->merge_sec = *((struct collection_item **) + (col_get_item_data(item))); + } + else { + TRACE_INFO_STRING("Collision not found.", ""); + po->merge_sec = NULL; + } + + TRACE_FLOW_EXIT(); + return EOK; +} + +/* Clean all items in the section */ +static int empty_section(struct collection_item *sec) +{ + int error = EOK; + struct collection_item *item = NULL; + struct collection_item *save_item = NULL; + struct value_obj *vo = NULL; + int work_to_do = 1; + + TRACE_FLOW_ENTRY(); + + do { + item = NULL; + error = col_extract_item_from_current(sec, + COL_DSP_FRONT, + NULL, + 0, + COL_TYPE_ANY, + &item); + if ((error) && (error != ENOENT)) { + TRACE_ERROR_NUMBER("Failed to extract item.", error); + return error; + } + + if (item) { + TRACE_INFO_STRING("Item found:", + col_get_item_property(item, NULL)); + + if (strncmp(col_get_item_property(item, NULL), + INI_SECTION_KEY, 1) == 0) { + /* Just ignore the first item */ + save_item = item; + continue; + } + + vo = *((struct value_obj **)(col_get_item_data(item))); + value_destroy(vo); + col_delete_item(item); + } + else { + TRACE_INFO_STRING("No more items:", ""); + /* Restore saved item */ + error = col_insert_item(sec, + NULL, + save_item, + COL_DSP_END, + NULL, + 0, + COL_INSERT_NOCHECK); + if (error) { + TRACE_ERROR_NUMBER("Failed to restore item.", error); + return error; + } + + work_to_do = 0; + } + } + while (work_to_do); + + TRACE_FLOW_EXIT(); + return EOK; +} + +/* Merge contents of the section */ +static int merge_section(struct parser_obj *po) +{ + int error = EOK; + struct collection_item *item = NULL; + struct value_obj *vo = NULL; + int work_to_do = 1; + const char *key; + + TRACE_FLOW_ENTRY(); + + do { + TRACE_INFO_STRING("Top of the merge loop", ""); + + item = NULL; + error = col_extract_item_from_current(po->sec, + COL_DSP_FRONT, + NULL, + 0, + COL_TYPE_ANY, + &item); + if ((error) && (error != ENOENT)) { + TRACE_ERROR_NUMBER("Failed to extract item.", error); + return error; + } + + if (item) { + + TRACE_INFO_STRING("Item found:", col_get_item_property(item, NULL)); + + if (strncmp(col_get_item_property(item, NULL), + INI_SECTION_KEY, 1) == 0) { + /* Just ignore the first item */ + vo = *((struct value_obj **)(col_get_item_data(item))); + value_destroy(vo); + col_delete_item(item); + continue; + } + + po->merge_vo = *((struct value_obj **)(col_get_item_data(item))); + key = col_get_item_property(item, NULL); + /* To be able to use po->merge_key in the loop + * we have to overcome constraints imposed by + * the "const" declaration. + */ + memcpy(&(po->merge_key), &key, sizeof(char *)); + + /* Use the value processing function to inser the value */ + error = complete_value_processing(po); + + /* In case of error value is already cleaned */ + po->merge_vo = NULL; + po->merge_key = NULL; + col_delete_item(item); + /* Now we can check the error */ + if (error) { + TRACE_ERROR_NUMBER("Failed to merge item.", error); + return error; + } + } + else { + TRACE_INFO_STRING("No more items:", ""); + work_to_do = 0; + } + } + while (work_to_do); + + /* If we reached this place the incoming section is empty. + * but just to be safe clean with callback. */ + col_destroy_collection_with_cb(po->sec, ini_cleanup_cb, NULL); + po->sec = NULL; + + TRACE_FLOW_EXIT(); + return EOK; +} + /* Function to read next line from the file */ static int parser_save_section(struct parser_obj *po) { |