summaryrefslogtreecommitdiffstats
path: root/ini/ini_parse_ut.c
diff options
context:
space:
mode:
authorDmitri Pal <dpal@redhat.com>2010-06-19 11:28:04 -0400
committerStephen Gallagher <sgallagh@redhat.com>2010-09-22 14:57:53 -0400
commitbcfbcf2e8d578580f308b5bdded49b166650f131 (patch)
treea1348fb14bf6a45bff16d668c1e083042252d569 /ini/ini_parse_ut.c
parent49ea94d1755e9003cbc2cba99c218cdd0a391813 (diff)
downloadding-libs-bcfbcf2e8d578580f308b5bdded49b166650f131.tar.gz
ding-libs-bcfbcf2e8d578580f308b5bdded49b166650f131.tar.xz
ding-libs-bcfbcf2e8d578580f308b5bdded49b166650f131.zip
New INI parser
The parser is added to the existing module. The old parsing functuion will be removed when we switch to the new interface. Parser logic: * There is one high level function that wraps the parser interface. It is at the bottom of the module. ini_parse_config(); * Internally it creates a perser object and then runs parser on it. * At the end parser object is destroyed. * This object stores the state of the parser. * The parser has an action queue * There are several actions that parser can perform - read line - inspect read line - record an error - process last comment in the file (POST) * Each action handler determines what to do next depending upon what has happened. * Read handler reads lines and enqueues inspection action in case of success or error action in case of failure. * Inspection action parses last read line and treats it either is a: * Comment * Section * New key + value * Continuation of the value In case of error the error action is enqueued. * Error can be fatal or non fatal. It depend on the error_level flag passed in. If the error is non fatal the read action is enqueued otherwise parser stops. * The POST action is a special action to handle comment at the bottom of the file. The comment is stored with the value it preceeds so in case there is a comment at the bottom of the file a special value needs to be created to hold just the comment.
Diffstat (limited to 'ini/ini_parse_ut.c')
-rw-r--r--ini/ini_parse_ut.c209
1 files changed, 209 insertions, 0 deletions
diff --git a/ini/ini_parse_ut.c b/ini/ini_parse_ut.c
new file mode 100644
index 0000000..08e55f6
--- /dev/null
+++ b/ini/ini_parse_ut.c
@@ -0,0 +1,209 @@
+/*
+ INI LIBRARY
+
+ Unit test for the parser object.
+
+ Copyright (C) Dmitri Pal <dpal@redhat.com> 2010
+
+ INI Library is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ INI Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with INI Library. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+#include "ini_defines.h"
+#include "ini_parse.h"
+#include "ini_config.h"
+#include "ini_configobj.h"
+#include "simplebuffer.h"
+#include "path_utils.h"
+#include "config.h"
+#define TRACE_HOME
+#include "trace.h"
+
+int verbose = 0;
+char *confdir = NULL;
+
+#define INIOUT(foo) \
+ do { \
+ if (verbose) foo; \
+ } while(0)
+
+typedef int (*test_fn)(void);
+
+int test_one_file(const char *filename)
+{
+ int error = EOK;
+ FILE *ff = NULL;
+ char new_file[100];
+ struct configobj *ini_config = NULL;
+ struct collection_item *error_list = NULL;
+ struct simplebuffer *sbobj = NULL;
+ uint32_t left = 0;
+ char filename_base[96];
+
+ INIOUT(printf("<==== Testing file %s ====>\n", filename));
+
+ /* Create config collection */
+ error = ini_config_create(&ini_config);
+ if (error != EOK) {
+ printf("Failed to create collection. Error %d.\n", error);
+ return error;
+ }
+
+ errno = 0;
+ ff = fopen(filename,"r");
+ if(!ff) {
+ error = errno;
+ printf("Failed to open file for reading. Error %d.\n", error);
+ ini_config_destroy(ini_config);
+ return error;
+ }
+
+ error = ini_parse_config(ff,
+ filename,
+ ini_config,
+ INI_STOP_ON_NONE,
+ &error_list,
+ 80);
+ fclose(ff);
+ if (error != EOK) {
+ INIOUT(printf("Failed to parse configuration. Error %d.\n", error));
+ INIOUT(print_file_parsing_errors(stdout, error_list));
+ col_destroy_collection(error_list);
+ }
+
+ error = simplebuffer_alloc(&sbobj);
+ if (error) {
+ TRACE_ERROR_NUMBER("Failed to allocate dynamic string.", error);
+ ini_config_destroy(ini_config);
+ return error;
+ }
+
+ error = ini_serialize_config(ini_config, sbobj);
+ if (error != EOK) {
+ printf("Failed to parse configuration. Error %d.\n", error);
+ ini_config_destroy(ini_config);
+ simplebuffer_free(sbobj);
+ return error;
+ }
+
+ error = get_basename(filename_base, 96, filename);
+ sprintf(new_file, "%s.out", filename_base);
+
+ errno = 0;
+ ff = fopen(new_file, "w");
+ if(!ff) {
+ error = errno;
+ printf("Failed to open file for writing. Error %d.\n", error);
+ ini_config_destroy(ini_config);
+ simplebuffer_free(sbobj);
+ return error;
+ }
+
+ /* Save */
+ left = simplebuffer_get_len(sbobj);
+ while (left > 0) {
+ error = simplebuffer_write(fileno(ff), sbobj, &left);
+ if (error) {
+ printf("Failed to write back the configuration %d.\n", error);
+ simplebuffer_free(sbobj);
+ ini_config_destroy(ini_config);
+ fclose(ff);
+ return error;
+ }
+ }
+
+ ini_config_destroy(ini_config);
+ simplebuffer_free(sbobj);
+ fclose(ff);
+
+ return EOK;
+}
+
+
+/* Run tests for multiple files */
+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;
+
+ 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;
+ i++;
+ }
+
+ free(files[3]);
+ free(files[2]);
+ free(files[1]);
+ free(files[0]);
+
+ return lasterr;
+}
+
+/* Main function of the unit test */
+int main(int argc, char *argv[])
+{
+ int error = 0;
+ test_fn tests[] = { read_save_test,
+ NULL };
+ char *srcdir;
+ test_fn t;
+ int i = 0;
+ char *var;
+
+ if ((argc > 1) && (strcmp(argv[1], "-v") == 0)) verbose = 1;
+ else {
+ var = getenv("COMMON_TEST_VERBOSE");
+ if (var) verbose = 1;
+ }
+
+ INIOUT(printf("Start\n"));
+
+ srcdir = getenv("srcdir");
+ if(!srcdir) {
+ confdir = malloc(sizeof(char)*3);
+ sprintf(confdir, "./ini");
+ } else {
+ confdir = malloc(strlen(srcdir)+4*sizeof(char));
+ sprintf(confdir, "%s/ini", srcdir);
+ }
+
+ while ((t = tests[i++])) {
+ error = t();
+ if (error) {
+ INIOUT(printf("Failed with error %d!\n", error));
+ return error;
+ }
+ }
+
+ INIOUT(printf("Success!\n"));
+
+ return 0;
+}