summaryrefslogtreecommitdiffstats
path: root/ini
diff options
context:
space:
mode:
authorDmitri Pal <dpal@redhat.com>2010-11-26 23:11:07 -0500
committerStephen Gallagher <sgallagh@redhat.com>2010-12-21 11:16:09 -0500
commit5dadfb4371b8ba694b8d9431cb6789bf6de485c4 (patch)
tree2b6843eb1b30a5aa4b23a77a74c7d0a797f9d464 /ini
parent500eaf3ef5d53a9961443d2f3ea0d7e8b01d4c1f (diff)
downloadding-libs2-5dadfb4371b8ba694b8d9431cb6789bf6de485c4.tar.gz
ding-libs2-5dadfb4371b8ba694b8d9431cb6789bf6de485c4.tar.xz
ding-libs2-5dadfb4371b8ba694b8d9431cb6789bf6de485c4.zip
New copy and folding functionality
* Added method to copy configuration. * Added unit test for it. * Added method to reset boandary for the whole configuration. * Added unit test for it. * Unit test now can read a file save it read again and save. Both saves produce same files! * Reworked the way the parser was dealing with empty lines. It was sutting off the value in the middle if the folded line consisted of just spaces.
Diffstat (limited to 'ini')
-rw-r--r--ini/ini_configobj.c141
-rw-r--r--ini/ini_configobj.h4
-rw-r--r--ini/ini_parse.c74
-rw-r--r--ini/ini_parse_ut.c129
4 files changed, 274 insertions, 74 deletions
diff --git a/ini/ini_configobj.c b/ini/ini_configobj.c
index 4da9a7c..3e5dec4 100644
--- a/ini/ini_configobj.c
+++ b/ini/ini_configobj.c
@@ -113,3 +113,144 @@ int ini_config_create(struct ini_cfgobj **ini_config)
TRACE_FLOW_EXIT();
return error;
}
+
+/* Callback to set the boundary */
+int ini_boundary_cb(const char *property,
+ int property_len,
+ int type,
+ void *data,
+ int length,
+ void *custom_data,
+ int *dummy)
+{
+ int error = EOK;
+ struct value_obj *vo = NULL;
+ uint32_t boundary;
+
+ TRACE_FLOW_ENTRY();
+
+ boundary = *((uint32_t *)(custom_data));
+ /* Banary items are the values */
+ if(type == COL_TYPE_BINARY) {
+ vo = *((struct value_obj **)(data));
+ error = value_set_boundary(vo, boundary);
+ }
+
+ TRACE_FLOW_EXIT();
+ return error;
+}
+
+/* Set the folding boundary for multiline values.
+ * Use before serializing and saving to a file if the
+ * default boundary of 80 characters does not work for you.
+ */
+int ini_config_set_wrap(struct ini_cfgobj *ini_config,
+ uint32_t boundary)
+{
+ int error = EOK;
+
+ TRACE_FLOW_ENTRY();
+
+ if (!ini_config) {
+ TRACE_ERROR_NUMBER("Invalid argument", EINVAL);
+ return EINVAL;
+ }
+
+ ini_config->boundary = boundary;
+ error = col_traverse_collection(ini_config->cfg,
+ COL_TRAVERSE_DEFAULT,
+ ini_boundary_cb,
+ (void *)(&(ini_config->boundary)));
+ if (error) {
+ TRACE_ERROR_NUMBER("Failed to set wrapping boundary", error);
+ return error;
+ }
+
+
+ TRACE_FLOW_EXIT();
+ return error;
+}
+
+/* Configuration copy callback */
+static int ini_copy_cb(struct collection_item *item,
+ void *ext_data,
+ int *skip)
+{
+ int error = EOK;
+ struct value_obj *vo = NULL;
+ struct value_obj *new_vo = NULL;
+
+ TRACE_FLOW_ENTRY();
+
+ ext_data = NULL;
+ *skip = 0;
+
+ /* Banary items are the values */
+ if(col_get_item_type(item) == COL_TYPE_BINARY) {
+ vo = *((struct value_obj **)(col_get_item_data(item)));
+
+ error = value_copy(vo, &new_vo);
+ if (error) {
+ TRACE_ERROR_NUMBER("Failed to copy value", error);
+ return error;
+ }
+
+ error = col_modify_binary_item(item,
+ NULL,
+ &new_vo,
+ sizeof(struct value_obj *));
+ if (error) {
+ TRACE_ERROR_NUMBER("Failed to copy value", error);
+ value_destroy(new_vo);
+ return error;
+ }
+ }
+
+ TRACE_FLOW_EXIT();
+ return error;
+}
+
+/* Copy configuration */
+int ini_config_copy(struct ini_cfgobj *ini_config,
+ struct ini_cfgobj **ini_new)
+{
+ int error = EOK;
+ struct ini_cfgobj *new_co;
+
+ TRACE_FLOW_ENTRY();
+
+ if ((!ini_config) ||
+ (!ini_new)) {
+ TRACE_ERROR_NUMBER("Invalid argument", EINVAL);
+ return EINVAL;
+ }
+
+ /* Create a new configuration object */
+ errno = 0;
+ new_co = malloc(sizeof(struct ini_cfgobj));
+ if (!new_co) {
+ error = errno;
+ TRACE_ERROR_NUMBER("Failed to allocate memory", ENOMEM);
+ return ENOMEM;
+ }
+
+ new_co->cfg = NULL;
+ new_co->boundary = ini_config->boundary;
+
+ error = col_copy_collection_with_cb(&(new_co->cfg),
+ ini_config->cfg,
+ INI_CONFIG_NAME,
+ COL_COPY_NORMAL,
+ ini_copy_cb,
+ NULL);
+ if (error) {
+ TRACE_ERROR_NUMBER("Failed to copy collection", error);
+ ini_config_destroy(new_co);
+ return error;
+ }
+
+ *ini_new = new_co;
+
+ TRACE_FLOW_EXIT();
+ return error;
+}
diff --git a/ini/ini_configobj.h b/ini/ini_configobj.h
index 81578c0..21198db 100644
--- a/ini/ini_configobj.h
+++ b/ini/ini_configobj.h
@@ -138,6 +138,10 @@ void ini_config_free_errors(char **errors);
int ini_config_parse(struct ini_cfgfile *file_ctx,
struct ini_cfgobj *ini_config);
+/* Copy configuration */
+int ini_config_copy(struct ini_cfgobj *ini_config,
+ struct ini_cfgobj **ini_new);
+
/* Function to print errors from the list */
void ini_print_errors(FILE *file, char **error_list);
diff --git a/ini/ini_parse.c b/ini/ini_parse.c
index 253b78b..c92a163 100644
--- a/ini/ini_parse.c
+++ b/ini/ini_parse.c
@@ -79,6 +79,20 @@ typedef int (*action_fn)(struct parser_obj *);
#define PARSE_DONE 4 /* We are done */
+int is_just_spaces(const char *str, uint32_t len)
+{
+ uint32_t i;
+
+ TRACE_FLOW_ENTRY();
+
+ for (i = 0; i < len; i++) {
+ if (!isspace(str[i])) return 0;
+ }
+
+ TRACE_FLOW_EXIT();
+ return 1;
+}
+
/* Destroy parser object */
void parser_destroy(struct parser_obj *po)
@@ -401,14 +415,24 @@ static int handle_space(struct parser_obj *po, uint32_t *action)
*action = PARSE_READ;
}
else {
- /* We do not have an active value
- * but have a line is starting with a space.
- * For now it is error.
- * We can change it in future if
- * people find it being too restrictive
- */
- *action = PARSE_ERROR;
- po->last_error = ERR_SPACE;
+ /* Check if this is a completely empty line */
+ if (is_just_spaces(po->last_read, po->last_read_len)) {
+ error = handle_comment(po, action);
+ if (error) {
+ TRACE_ERROR_NUMBER("Failed to process comment", error);
+ return error;
+ }
+ }
+ else {
+ /* We do not have an active value
+ * but have a line is starting with a space.
+ * For now it is error.
+ * We can change it in future if
+ * people find it being too restrictive
+ */
+ *action = PARSE_ERROR;
+ po->last_error = ERR_SPACE;
+ }
}
TRACE_FLOW_EXIT();
@@ -425,6 +449,8 @@ static int handle_kvp(struct parser_obj *po, uint32_t *action)
TRACE_FLOW_ENTRY();
+ TRACE_INFO_STRING("Last read:", po->last_read);
+
/* We got a line with KVP */
if (*(po->last_read) == '=') {
po->last_error = ERR_NOKEY;
@@ -681,20 +707,6 @@ static int handle_section(struct parser_obj *po, uint32_t *action)
}
-int is_just_spaces(const char *str, uint32_t len)
-{
- uint32_t i;
-
- TRACE_FLOW_ENTRY();
-
- for (i = 0; i < len; i++) {
- if (!isspace(str[i])) return 0;
- }
-
- TRACE_FLOW_EXIT();
- return 1;
-}
-
/* Inspect the line */
static int parser_inspect(struct parser_obj *po)
{
@@ -716,20 +728,10 @@ static int parser_inspect(struct parser_obj *po)
else if ((*(po->last_read) == ' ') ||
(*(po->last_read) == '\t')) {
- /* Check if this is a completely empty line */
- if (is_just_spaces(po->last_read, po->last_read_len)) {
- error = handle_comment(po, &action);
- if (error) {
- TRACE_ERROR_NUMBER("Failed to process comment", error);
- return error;
- }
- }
- else {
- error = handle_space(po, &action);
- if (error) {
- TRACE_ERROR_NUMBER("Failed to process line wrapping", error);
- return error;
- }
+ error = handle_space(po, &action);
+ if (error) {
+ TRACE_ERROR_NUMBER("Failed to process line wrapping", error);
+ return error;
}
}
else if (*(po->last_read) == '[') {
diff --git a/ini/ini_parse_ut.c b/ini/ini_parse_ut.c
index 01b7077..cc37c21 100644
--- a/ini/ini_parse_ut.c
+++ b/ini/ini_parse_ut.c
@@ -23,13 +23,16 @@
#include <string.h>
#include <errno.h>
#include <stdlib.h>
+#include <limits.h>
#include "ini_defines.h"
#include "ini_configobj.h"
+#include "ini_config_priv.h"
#include "simplebuffer.h"
#include "path_utils.h"
#include "config.h"
#define TRACE_HOME
#include "trace.h"
+#include "collection_tools.h"
int verbose = 0;
char *confdir = NULL;
@@ -41,19 +44,19 @@ char *confdir = NULL;
typedef int (*test_fn)(void);
-int test_one_file(const char *filename)
+int test_one_file(const char *in_filename,
+ const char *out_filename)
{
int error = EOK;
struct ini_cfgfile *file_ctx = NULL;
FILE *ff = NULL;
- char new_file[100];
struct ini_cfgobj *ini_config = NULL;
+ struct ini_cfgobj *ini_copy = NULL;
char **error_list = NULL;
struct simplebuffer *sbobj = NULL;
uint32_t left = 0;
- char filename_base[96];
- INIOUT(printf("<==== Testing file %s ====>\n", filename));
+ INIOUT(printf("<==== Testing file %s ====>\n", in_filename));
/* Create config collection */
error = ini_config_create(&ini_config);
@@ -62,7 +65,7 @@ int test_one_file(const char *filename)
return error;
}
- error = ini_config_file_open(filename,
+ error = ini_config_file_open(in_filename,
INI_STOP_ON_NONE,
0, /* TBD */
0, /* TBD */
@@ -83,12 +86,35 @@ int test_one_file(const char *filename)
ini_config_get_filename(file_ctx)));
ini_config_get_errors(file_ctx, &error_list);
INIOUT(ini_print_errors(stdout, error_list));
+ ini_config_free_errors(error_list);
}
/* We do not return here intentionally */
}
ini_config_file_close(file_ctx);
+ INIOUT(col_debug_collection(ini_config->cfg, COL_TRAVERSE_DEFAULT));
+
+ /* Copy configuration */
+ error = ini_config_copy(ini_config, &ini_copy);
+ if (error) {
+ printf("Failed to copy configuration. Error %d.\n", error);
+ ini_config_destroy(ini_config);
+ return error;
+ }
+
+ ini_config_destroy(ini_config);
+ ini_config = ini_copy;
+
+ INIOUT(col_debug_collection(ini_config->cfg, COL_TRAVERSE_DEFAULT));
+
+ error = ini_config_set_wrap(ini_config, 5);
+ if (error) {
+ printf("Failed to set custom wrapper. Error %d.\n", error);
+ ini_config_destroy(ini_config);
+ return error;
+ }
+
error = simplebuffer_alloc(&sbobj);
if (error) {
TRACE_ERROR_NUMBER("Failed to allocate dynamic string.", error);
@@ -104,11 +130,8 @@ int test_one_file(const char *filename)
return error;
}
- error = get_basename(filename_base, 96, filename);
- sprintf(new_file, "%s.out", filename_base);
-
errno = 0;
- ff = fopen(new_file, "w");
+ ff = fopen(out_filename, "w");
if(!ff) {
error = errno;
printf("Failed to open file for writing. Error %d.\n", error);
@@ -143,41 +166,79 @@ int read_save_test(void)
{
int error = EOK;
int i = 0;
- int lasterr = EOK;
- char *files[5];
-
- files[0] = malloc(sizeof(char)*512);
- sprintf(files[0], "%s/ini.d/real.conf", confdir);
- files[1] = malloc(sizeof(char)*512);
- sprintf(files[1], "%s/ini.d/mysssd.conf", confdir);
- files[2] = malloc(sizeof(char)*512);
- sprintf(files[2], "%s/ini.d/ipa.conf", confdir);
- files[3] = malloc(sizeof(char)*512);
- sprintf(files[3], "%s/ini.d/test.conf", confdir);
- files[4] = NULL;
+ char infile[PATH_MAX];
+ char outfile[PATH_MAX];
+ char *srcdir;
+ const char *files[] = { "real",
+ "mysssd",
+ "ipa",
+ "test",
+ NULL };
+
+
+ srcdir = getenv("srcdir");
while(files[i]) {
- error = test_one_file(files[i]);
- INIOUT(printf("Test fo file: %s returned %d\n", files[i], error));
- if (error) lasterr = error;
+
+ sprintf(infile, "%s/ini/ini.d/%s.conf", (srcdir == NULL) ? "." : srcdir,
+ files[i]);
+ sprintf(outfile, "%s/%s.conf.out", (srcdir == NULL) ? "." : srcdir,
+ files[i]);
+ error = test_one_file(infile, outfile);
+ INIOUT(printf("Test for file: %s returned %d\n", files[i], error));
i++;
}
- free(files[3]);
- free(files[2]);
- free(files[1]);
- free(files[0]);
+ return EOK;
+}
+
+/* Run tests for multiple files */
+int read_again_test(void)
+{
+ int error = EOK;
+ int i = 0;
+ char infile[PATH_MAX];
+ char outfile[PATH_MAX];
+ char *srcdir;
+ char command[PATH_MAX * 3];
+ const char *files[] = { "real",
+ "mysssd",
+ "ipa",
+ "test",
+ NULL };
+
- return lasterr;
+ srcdir = getenv("srcdir");
+
+ while(files[i]) {
+
+ sprintf(infile, "%s/%s.conf.out", (srcdir == NULL) ? "." : srcdir,
+ files[i]);
+ sprintf(outfile, "%s/%s.conf.2.out", (srcdir == NULL) ? "." : srcdir,
+ files[i]);
+ error = test_one_file(infile, outfile);
+ INIOUT(printf("Test for file: %s returned %d\n", files[i], error));
+ if (error) break;
+ sprintf(command,"diff -q %s %s", infile, outfile);
+ error = system(command);
+ INIOUT(printf("Comparison of %s %s returned: %d\n",
+ infile, outfile, error));
+ if (error) break;
+
+ i++;
+ }
+
+ return error;
}
+
/* Main function of the unit test */
int main(int argc, char *argv[])
{
int error = 0;
test_fn tests[] = { read_save_test,
+ read_again_test,
NULL };
- char *srcdir;
test_fn t;
int i = 0;
char *var;
@@ -190,14 +251,6 @@ int main(int argc, char *argv[])
INIOUT(printf("Start\n"));
- srcdir = getenv("srcdir");
- if(!srcdir) {
- confdir = strdup("./ini");
- } else {
- confdir = malloc(strlen(srcdir)+5*sizeof(char));
- sprintf(confdir, "%s/ini", srcdir);
- }
-
while ((t = tests[i++])) {
error = t();
if (error) {