summaryrefslogtreecommitdiffstats
path: root/ini/ini_configobj.c
diff options
context:
space:
mode:
authorDmitri Pal <dpal@redhat.com>2012-12-24 17:45:00 -0500
committerOndrej Kos <okos@redhat.com>2013-01-24 08:34:51 +0100
commit6823d7104cca0f8ac22ed9432ee8a2f1a0d9124a (patch)
tree51c9c817e8335c0001f3c012819760bfcf6a1681 /ini/ini_configobj.c
parentfa00e2e16e5c1d3ac56f1bbd3a84875642d0bb39 (diff)
downloadding-libs-6823d7104cca0f8ac22ed9432ee8a2f1a0d9124a.tar.gz
ding-libs-6823d7104cca0f8ac22ed9432ee8a2f1a0d9124a.tar.xz
ding-libs-6823d7104cca0f8ac22ed9432ee8a2f1a0d9124a.zip
More interface refactoring
I also realized that error list processing should not be bound to the file object. This patch corrects that by moving the error_list and corresponding count from file object to the config object. Things updated by the patch: 1. The internal variables are moved from file obj to config obj. 2. The external header is updated to reflect the change 3. Functions are moved from file obj module to config obj module. 4. Parser code is updated because error validation was in the wrong place 5. Unit test is adjusted to get error list from the right object. I had to adjust the copy function for the config object. Copy function does not copy over the error list.
Diffstat (limited to 'ini/ini_configobj.c')
-rw-r--r--ini/ini_configobj.c141
1 files changed, 141 insertions, 0 deletions
diff --git a/ini/ini_configobj.c b/ini/ini_configobj.c
index 4a3e96d..603aaf4 100644
--- a/ini/ini_configobj.c
+++ b/ini/ini_configobj.c
@@ -24,8 +24,14 @@
#include <stdio.h>
#include <string.h>
#include <stdint.h>
+#include <stdlib.h>
+/* For error text */
+#include <libintl.h>
+#define _(String) gettext (String)
#include "trace.h"
#include "collection.h"
+#include "collection_tools.h"
+#include "ini_configobj.h"
#include "ini_config_priv.h"
#include "ini_defines.h"
#include "ini_valueobj.h"
@@ -99,6 +105,11 @@ void ini_config_destroy(struct ini_cfgobj *ini_config)
if (ini_config->last_comment) {
ini_comment_destroy(ini_config->last_comment);
}
+
+ if (ini_config->error_list) {
+ col_destroy_collection(ini_config->error_list);
+ }
+
free(ini_config);
}
@@ -132,6 +143,8 @@ int ini_config_create(struct ini_cfgobj **ini_config)
new_co->section_len = 0;
new_co->name_len = 0;
new_co->iterator = NULL;
+ new_co->error_list = NULL;
+ new_co->count = 0;
/* Create a collection to hold configuration data */
error = col_create_collection(&(new_co->cfg),
@@ -143,6 +156,16 @@ int ini_config_create(struct ini_cfgobj **ini_config)
return error;
}
+ /* Create error list collection */
+ error = col_create_collection(&(new_co->error_list),
+ INI_ERROR,
+ COL_CLASS_INI_PERROR);
+ if (error) {
+ TRACE_ERROR_NUMBER("Failed to create error list", error);
+ ini_config_destroy(new_co);
+ return error;
+ }
+
*ini_config = new_co;
TRACE_FLOW_EXIT();
@@ -274,6 +297,8 @@ int ini_config_copy(struct ini_cfgobj *ini_config,
new_co->section_len = 0;
new_co->name_len = 0;
new_co->iterator = NULL;
+ new_co->error_list = NULL;
+ new_co->count = 0;
error = col_copy_collection_with_cb(&(new_co->cfg),
ini_config->cfg,
@@ -898,3 +923,119 @@ int ini_config_merge(struct ini_cfgobj *first,
return error;
}
+
+/* How many errors do we have in the list ? */
+unsigned ini_config_error_count(struct ini_cfgobj *cfg_ctx)
+{
+ unsigned count = 0;
+
+ TRACE_FLOW_ENTRY();
+
+ count = cfg_ctx->count;
+
+ TRACE_FLOW_EXIT();
+ return count;
+
+}
+
+/* Free error strings */
+void ini_config_free_errors(char **errors)
+{
+ TRACE_FLOW_ENTRY();
+
+ col_free_property_list(errors);
+
+ TRACE_FLOW_EXIT();
+}
+
+/* Get the list of error strings */
+int ini_config_get_errors(struct ini_cfgobj *cfg_ctx,
+ char ***errors)
+{
+ char **errlist = NULL;
+ struct collection_iterator *iterator = NULL;
+ int error;
+ struct collection_item *item = NULL;
+ struct ini_parse_error *pe;
+ unsigned int count = 0;
+ char *line;
+
+ TRACE_FLOW_ENTRY();
+
+ /* If we have something to print print it */
+ if ((!errors) || (!cfg_ctx)) {
+ TRACE_ERROR_NUMBER("Invalid parameter.", EINVAL);
+ return EINVAL;
+ }
+
+ errlist = calloc(cfg_ctx->count + 1, sizeof(char *));
+ if (!errlist) {
+ TRACE_ERROR_NUMBER("Failed to allocate memory for errors.", ENOMEM);
+ return ENOMEM;
+ }
+
+ /* Bind iterator */
+ error = col_bind_iterator(&iterator,
+ cfg_ctx->error_list,
+ COL_TRAVERSE_DEFAULT);
+ if (error) {
+ TRACE_ERROR_NUMBER("Faile to bind iterator:", error);
+ ini_config_free_errors(errlist);
+ return error;
+ }
+
+ while(1) {
+ /* Loop through a collection */
+ error = col_iterate_collection(iterator, &item);
+ if (error) {
+ TRACE_ERROR_NUMBER("Error iterating collection", error);
+ col_unbind_iterator(iterator);
+ ini_config_free_errors(errlist);
+ return error;
+ }
+
+ /* Are we done ? */
+ if (item == NULL) break;
+
+ /* Process collection header */
+ if (col_get_item_type(item) == COL_TYPE_COLLECTION) {
+ continue;
+ }
+ else {
+ /* Put error into provided format */
+ pe = (struct ini_parse_error *)(col_get_item_data(item));
+
+ /* Would be nice to have asprintf function...
+ * ...but for now we know that all the errors
+ * are pretty short and will fir into the predefined
+ * error length buffer.
+ */
+ line = malloc(MAX_ERROR_LINE + 1);
+ if (!line) {
+ TRACE_ERROR_NUMBER("Failed to get memory for error.", ENOMEM);
+ col_unbind_iterator(iterator);
+ ini_config_free_errors(errlist);
+ return ENOMEM;
+ }
+
+ snprintf(line, MAX_ERROR_LINE, LINE_FORMAT,
+ col_get_item_property(item, NULL),
+ pe->error,
+ pe->line,
+ ini_get_error_str(pe->error,
+ INI_FAMILY_PARSING));
+
+ errlist[count] = line;
+ count++;
+ }
+
+ }
+
+ /* Do not forget to unbind iterator - otherwise there will be a leak */
+ col_unbind_iterator(iterator);
+
+ *errors = errlist;
+
+ TRACE_FLOW_EXIT();
+ return error;
+}