From 24967bd826ad5437a11b1431c8289b1881b52a17 Mon Sep 17 00:00:00 2001 From: Dmitri Pal Date: Fri, 10 Apr 2009 11:30:59 -0400 Subject: Added functions to create list of sections and attributes. --- common/collection/collection_tools.c | 100 +++++++++++++++++++++++++++++++++++ common/collection/collection_tools.h | 6 +++ common/ini/ini_config.c | 79 +++++++++++++++++++++++++++ common/ini/ini_config.h | 16 ++++++ common/ini/ini_config_ut.c | 44 +++++++++++++++ 5 files changed, 245 insertions(+) (limited to 'common') diff --git a/common/collection/collection_tools.c b/common/collection/collection_tools.c index cefe7ae4f..2fec6c558 100644 --- a/common/collection/collection_tools.c +++ b/common/collection/collection_tools.c @@ -638,4 +638,104 @@ int print_item(struct collection_item *handle, char *name) return error; } +/* Function to free the list of properties. */ +void free_property_list(char **str_list) +{ + int current = 0; + + TRACE_FLOW_STRING("free_property_list","Entry"); + + if (str_list != NULL) { + while(str_list[current]) { + free(str_list[current]); + current++; + } + free(str_list); + } + + TRACE_FLOW_STRING("free_property_list","Exit"); +} + + +/* Convert collection to list of properties */ +char **collection_to_list(struct collection_item *handle, int *size, int *error) +{ + struct collection_iterator *iterator; + struct collection_item *item = NULL; + char **list; + unsigned count; + int err; + int current = 0; + + TRACE_FLOW_STRING("collection_to_list","Entry"); + + /* Get number of the subsections */ + err = get_collection_count(handle,&count); + if (err) { + TRACE_ERROR_NUMBER("Failed to get count of items from collection.", err); + if (error) *error = err; + return NULL; + } + + /* Allocate memory for the sections */ + errno = 0; + list = (char **)calloc(count, sizeof(char *)); + if (list == NULL) { + err = errno; + TRACE_ERROR_NUMBER("Failed to get allocate memory.", err); + if (error) *error = ENOMEM; + return NULL; + } + + /* Now iterate to fill in the sections */ + /* Bind iterator */ + err = bind_iterator(&iterator, handle, COL_TRAVERSE_ONELEVEL); + if (err) { + TRACE_ERROR_NUMBER("Failed to bind.", err); + if (error) *error = err; + free(list); + return NULL; + } + + while(1) { + /* Loop through a collection */ + err = iterate_collection(iterator, &item); + if (err) { + TRACE_ERROR_NUMBER("Failed to iterate collection", err); + if (error) *error = err; + free_property_list(list); + unbind_iterator(iterator); + return NULL; + } + + /* Are we done ? */ + if (item == NULL) break; + + TRACE_INFO_STRING("Property:", get_item_property(item, NULL)); + + /* Skip head */ + if(get_item_type(item) == COL_TYPE_COLLECTION) continue; + + /* Allocate memory for the new string */ + errno = 0; + list[current] = strdup(get_item_property(item, NULL)); + if (list[current] == NULL) { + err = errno; + TRACE_ERROR_NUMBER("Failed to dup string.", err); + if (error) *error = ENOMEM; + free_property_list(list); + return NULL; + } + current++; + } + + /* Do not forget to unbind iterator - otherwise there will be a leak */ + unbind_iterator(iterator); + + if (size) *size = (int)(count - 1); + if (error) *error = EOK; + + TRACE_FLOW_STRING("collection_to_list returning", list == NULL ? "NULL" : list[0]); + return list; +} diff --git a/common/collection/collection_tools.h b/common/collection/collection_tools.h index defc4aa04..a8d13f749 100644 --- a/common/collection/collection_tools.h +++ b/common/collection/collection_tools.h @@ -98,4 +98,10 @@ int print_collection2(struct collection_item *handle); /* Find and print one item using default serialization */ int print_item(struct collection_item *handle, char *name); +/* Convert collection to list of properties */ +char **collection_to_list(struct collection_item *handle, int *size, int *error); + +/* Function to free the list of properties. */ +void free_property_list(char **str_list); + #endif diff --git a/common/ini/ini_config.c b/common/ini/ini_config.c index b4b4b25fd..8d19b272c 100644 --- a/common/ini/ini_config.c +++ b/common/ini/ini_config.c @@ -1443,3 +1443,82 @@ inline void free_double_config_array(double *array) { if (array != NULL) free(array); } + +/* The section array should be freed using this function */ +inline void free_section_list(char **section_list) +{ + TRACE_FLOW_STRING("free_section_list","Entry"); + + free_property_list(section_list); + + TRACE_FLOW_STRING("free_section_list","Exit"); +} + +/* The section array should be freed using this function */ +inline void free_attribute_list(char **section_list) +{ + TRACE_FLOW_STRING("free_section_list","Entry"); + + free_property_list(section_list); + + TRACE_FLOW_STRING("free_section_list","Exit"); +} + + +/* Get list of sections as an array of strings. + * Function allocates memory for the array of the sections. + */ +char **get_section_list(struct collection_item *ini_config, int *size, int *error) +{ + char **list; + + TRACE_FLOW_STRING("get_section_list","Entry"); + /* Do we have the item ? */ + if ((ini_config == NULL) || + !is_of_class(ini_config, COL_CLASS_INI_CONFIG)) { + TRACE_ERROR_NUMBER("Invalid argument.", EINVAL); + if (error) *error = EINVAL; + return NULL; + } + + /* Pass it to the function from collection API */ + list = collection_to_list(ini_config, size, error); + + TRACE_FLOW_STRING("get_section_list returning", list == NULL ? "NULL" : list[0]); + return list; +} + +/* Get list of attributes in a section as an array of strings. + * Function allocates memory for the array of the strings. + */ +char **get_attribute_list(struct collection_item *ini_config, const char *section, int *size, int *error) +{ + struct collection_item *subcollection = NULL; + char **list; + int err; + + TRACE_FLOW_STRING("get_attribute_list","Entry"); + /* Do we have the item ? */ + if ((ini_config == NULL) || + !is_of_class(ini_config, COL_CLASS_INI_CONFIG) || + (section == NULL)) { + TRACE_ERROR_NUMBER("Invalid argument.", EINVAL); + if (error) *error = EINVAL; + return NULL; + } + + /* Fetch section */ + err = get_collection_reference(ini_config, &subcollection, section); + /* Check error */ + if (err && (subcollection == NULL)) { + TRACE_ERROR_NUMBER("Failed to get section", err); + if (error) *error = EINVAL; + return NULL; + } + + /* Pass it to the function from collection API */ + list = collection_to_list(subcollection, size, error); + + TRACE_FLOW_STRING("get_attribute_list returning", list == NULL ? "NULL" : list[0]); + return list; +} diff --git a/common/ini/ini_config.h b/common/ini/ini_config.h index 2a9aa52a8..95cd52416 100644 --- a/common/ini/ini_config.h +++ b/common/ini/ini_config.h @@ -96,6 +96,22 @@ void print_file_parsing_errors(FILE *file, /* File to void print_config_parsing_errors(FILE *file, /* File to send errors to */ struct collection_item *error_list); /* Collection of collections of errors */ +/* Get list of sections from the config collection as an array of strings. + * Function allocates memory for the array of the sections. + */ +char **get_section_list(struct collection_item *ini_config, int *size, int *error); + +/* The section array should be freed using this function */ +void free_section_list(char **section_list); + +/* Get list of attributes in a section as an array of strings. + * Function allocates memory for the array of attributes. + */ +char **get_attribute_list(struct collection_item *ini_config, const char *section, int *size, int *error); + +/* The attribute array should be freed using this function */ +void free_attribute_list(char **attr_list); + /* Get a configuration item form the configuration */ int get_config_item(const char *section, /* Section. If NULL assumed default */ const char *name, /* Name of the property to look up */ diff --git a/common/ini/ini_config_ut.c b/common/ini/ini_config_ut.c index 4968a0ac2..28560e54d 100644 --- a/common/ini/ini_config_ut.c +++ b/common/ini/ini_config_ut.c @@ -227,6 +227,7 @@ int get_test() int size; long *array; double *darray; + char **prop_array; printf("\n\n===== GET TEST START ======\n"); printf("Reading collection\n"); @@ -712,6 +713,49 @@ int get_test() free_double_config_array(darray); + printf("\n\nSection list - no size\n"); + + /* Do not care about the error or size */ + prop_array = get_section_list(ini_config,NULL,NULL); + if (prop_array == NULL) { + printf("Expect success got error.\n"); + destroy_collection(ini_config); + return -1; + } + + i = 0; + while (prop_array[i]) { + printf("Section: [%s]\n", prop_array[i]); + i++; + } + free_section_list(prop_array); + + printf("\n\nSection list - with size\n"); + + /* Do not care about the error or size */ + prop_array = get_section_list(ini_config, &size, NULL); + if (prop_array == NULL) { + printf("Expect success got error.\n"); + destroy_collection(ini_config); + return -1; + } + + for (i=0;i