LCOV - code coverage report
Current view: top level - ini - ini_parse_ut.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 1013 1590 63.7 %
Date: 2014-04-01 Functions: 18 18 100.0 %

          Line data    Source code
       1             : /*
       2             :     INI LIBRARY
       3             : 
       4             :     Unit test for the parser object.
       5             : 
       6             :     Copyright (C) Dmitri Pal <dpal@redhat.com> 2010
       7             : 
       8             :     INI Library is free software: you can redistribute it and/or modify
       9             :     it under the terms of the GNU Lesser General Public License as published by
      10             :     the Free Software Foundation, either version 3 of the License, or
      11             :     (at your option) any later version.
      12             : 
      13             :     INI Library is distributed in the hope that it will be useful,
      14             :     but WITHOUT ANY WARRANTY; without even the implied warranty of
      15             :     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      16             :     GNU Lesser General Public License for more details.
      17             : 
      18             :     You should have received a copy of the GNU Lesser General Public License
      19             :     along with INI Library.  If not, see <http://www.gnu.org/licenses/>.
      20             : */
      21             : 
      22             : #include "config.h"
      23             : #include <stdio.h>
      24             : #include <string.h>
      25             : #include <errno.h>
      26             : #include <stdlib.h>
      27             : #include <limits.h>
      28             : #include <sys/stat.h>
      29             : #include "ini_defines.h"
      30             : #include "ini_configobj.h"
      31             : #include "ini_config_priv.h"
      32             : #include "simplebuffer.h"
      33             : #include "path_utils.h"
      34             : #define TRACE_HOME
      35             : #include "trace.h"
      36             : #include "collection_tools.h"
      37             : 
      38             : int verbose = 0;
      39             : char *confdir = NULL;
      40             : 
      41             : #define NUM_TESTS 14
      42             : #define VAL_SIZE 100
      43             : 
      44             : #define INIOUT(foo) \
      45             :     do { \
      46             :         if (verbose) foo; \
      47             :     } while(0)
      48             : 
      49             : typedef int (*test_fn)(void);
      50             : 
      51         158 : static int test_one_file(const char *in_filename,
      52             :                          const char *out_filename,
      53             :                          int edge,
      54             :                          int in_mem)
      55             : {
      56         158 :     int error = EOK;
      57         158 :     struct ini_cfgfile *file_ctx = NULL;
      58         158 :     FILE *ff = NULL;
      59         158 :     struct ini_cfgobj *ini_config = NULL;
      60         158 :     struct ini_cfgobj *ini_copy = NULL;
      61         158 :     char **error_list = NULL;
      62         158 :     struct simplebuffer *sbobj = NULL;
      63         158 :     uint32_t left = 0;
      64         158 :     uint32_t stream_len = 0;
      65         158 :     void *stream_data = NULL;
      66             :     struct stat file_stats;
      67         158 :     int stat_ret = 0;
      68         158 :     FILE *file = NULL;
      69             : 
      70         158 :     INIOUT(printf("<==== Testing file %s ====>\n", in_filename));
      71             : 
      72             :     /* Create config collection */
      73         158 :     error = ini_config_create(&ini_config);
      74         158 :     if (error) {
      75           0 :         printf("Failed to create collection. Error %d.\n", error);
      76           0 :         return error;
      77             :     }
      78             : 
      79         158 :     if (in_mem) {
      80             :         /* Get file stats */
      81          48 :         errno = 0;
      82          48 :         stat_ret = stat(in_filename, &file_stats);
      83          48 :         if (stat_ret == -1) {
      84           0 :             error = errno;
      85           0 :             printf("Failed to get file stats. Error %d.\n", error);
      86           0 :             ini_config_destroy(ini_config);
      87           0 :             return error;
      88             :         }
      89             :         /* Allocate memory to store file */
      90          48 :         errno = 0;
      91          48 :         stream_len = file_stats.st_size;
      92          48 :         stream_data = malloc(file_stats.st_size + 1);
      93          48 :         if (!stream_data) {
      94           0 :             error = errno;
      95           0 :             printf("Failed to allocate memory for stream. Error %d.\n", error);
      96           0 :             ini_config_destroy(ini_config);
      97           0 :             return error;
      98             :         }
      99          48 :         *((unsigned char *)(stream_data) + stream_len) = '\0';
     100             :         /* Open file */
     101          48 :         errno = 0;
     102          48 :         file = fopen(in_filename, "r");
     103          48 :         if (!stream_data) {
     104           0 :             error = errno;
     105           0 :             printf("Failed to open file to prepare stream. Error %d.\n", error);
     106           0 :             free(stream_data);
     107           0 :             ini_config_destroy(ini_config);
     108           0 :             return error;
     109             :         }
     110             :         /* Read file into memory */
     111          48 :         errno = 0;
     112          48 :         fread(stream_data, stream_len, 1, file);
     113          48 :         error = ferror(file);
     114          48 :         if (error) {
     115           0 :             printf("Failed to read stream data. Error %d.\n", error);
     116           0 :             free(stream_data);
     117           0 :             fclose(file);
     118           0 :             ini_config_destroy(ini_config);
     119           0 :             return error;
     120             :         }
     121          48 :         fclose(file);
     122             : 
     123          48 :         INIOUT(printf("Data len %u\n", stream_len));
     124          48 :         INIOUT(printf("Data:\n%s\n", (char *)stream_data));
     125             : 
     126          48 :         error = ini_config_file_from_mem(stream_data,
     127             :                                          stream_len,
     128             :                                          &file_ctx);
     129          48 :         if (error) {
     130           0 :             printf("Failed to open from memory. Error %d.\n", error);
     131           0 :             free(stream_data);
     132           0 :             ini_config_destroy(ini_config);
     133           0 :             return error;
     134             :         }
     135             :     }
     136             :     else {
     137         110 :         error = ini_config_file_open(in_filename,
     138             :                                      0, /* TBD */
     139             :                                      &file_ctx);
     140         110 :         if (error) {
     141           0 :             printf("Failed to open file %s for reading. Error %d.\n",
     142             :                    in_filename, error);
     143           0 :             ini_config_destroy(ini_config);
     144           0 :             return error;
     145             :         }
     146             :     }
     147             : 
     148         158 :     error = ini_config_parse(file_ctx,
     149             :                              INI_STOP_ON_NONE,
     150             :                              0, /* TBD */
     151             :                              0,
     152             :                              ini_config);
     153         158 :     if (error) {
     154          14 :         INIOUT(printf("Failed to parse configuration. Error %d.\n", error));
     155             : 
     156          14 :         if (ini_config_error_count(ini_config)) {
     157          14 :             if (in_mem) {
     158           4 :                 INIOUT(printf("Errors detected while parsing"
     159             :                               " configuration stored in memory: %s\n",
     160             :                               in_filename));
     161             :             }
     162             :             else {
     163          10 :                 INIOUT(printf("Errors detected while parsing: %s\n",
     164             :                         ini_config_get_filename(file_ctx)));
     165             :             }
     166          14 :             ini_config_get_errors(ini_config, &error_list);
     167          14 :             INIOUT(ini_config_print_errors(stdout, error_list));
     168          14 :             ini_config_free_errors(error_list);
     169             :         }
     170             :         /* If we are testing memory mapped, return error */
     171          14 :         if (in_mem) {
     172           4 :             free(stream_data);
     173           4 :             ini_config_file_destroy(file_ctx);
     174           4 :             ini_config_destroy(ini_config);
     175           4 :             return error;
     176             :         }
     177             :     }
     178             : 
     179         154 :     if (in_mem) free(stream_data);
     180         154 :     ini_config_file_destroy(file_ctx);
     181             : 
     182         154 :     INIOUT(col_debug_collection(ini_config->cfg, COL_TRAVERSE_DEFAULT));
     183             : 
     184             :     /* Copy configuration */
     185         154 :     error = ini_config_copy(ini_config, &ini_copy);
     186         154 :     if (error) {
     187           0 :         printf("Failed to copy configuration. Error %d.\n", error);
     188           0 :         ini_config_destroy(ini_config);
     189           0 :         return error;
     190             :     }
     191             : 
     192         154 :     ini_config_destroy(ini_config);
     193         154 :     ini_config = ini_copy;
     194             : 
     195         154 :     INIOUT(col_debug_collection(ini_config->cfg, COL_TRAVERSE_DEFAULT));
     196             : 
     197         154 :     error = ini_config_set_wrap(ini_config, edge);
     198         154 :     if (error) {
     199           0 :         printf("Failed to set custom wrapper. Error %d.\n", error);
     200           0 :         ini_config_destroy(ini_config);
     201           0 :         return error;
     202             :     }
     203             : 
     204         154 :     error = simplebuffer_alloc(&sbobj);
     205         154 :     if (error) {
     206             :         TRACE_ERROR_NUMBER("Failed to allocate dynamic string.", error);
     207           0 :         ini_config_destroy(ini_config);
     208           0 :         return error;
     209             :     }
     210             : 
     211         154 :     error = ini_config_serialize(ini_config, sbobj);
     212         154 :     if (error != EOK) {
     213           0 :         printf("Failed to serialize configuration. Error %d.\n", error);
     214           0 :         ini_config_destroy(ini_config);
     215           0 :         simplebuffer_free(sbobj);
     216           0 :         return error;
     217             :     }
     218             : 
     219         154 :     errno = 0;
     220         154 :     ff = fopen(out_filename, "w");
     221         154 :     if(!ff) {
     222           0 :         error = errno;
     223           0 :         printf("Failed to open file [%s] for writing. Error %d.\n",
     224             :                out_filename, error);
     225           0 :         ini_config_destroy(ini_config);
     226           0 :         simplebuffer_free(sbobj);
     227           0 :         return error;
     228             :     }
     229             : 
     230             :     /* Save */
     231         154 :     left = simplebuffer_get_len(sbobj);
     232         448 :     while (left > 0) {
     233         140 :         error = simplebuffer_write(fileno(ff), sbobj, &left);
     234         140 :         if (error) {
     235           0 :             printf("Failed to write back the configuration %d.\n", error);
     236           0 :             simplebuffer_free(sbobj);
     237           0 :             ini_config_destroy(ini_config);
     238           0 :             fclose(ff);
     239           0 :             return error;
     240             :         }
     241             :     }
     242             : 
     243         154 :     ini_config_destroy(ini_config);
     244         154 :     simplebuffer_free(sbobj);
     245         154 :     fclose(ff);
     246             : 
     247         154 :     return EOK;
     248             : }
     249             : 
     250             : 
     251             : /* Run tests for multiple files */
     252           1 : static int read_save_test(void)
     253             : {
     254           1 :     int error = EOK;
     255           1 :     int i = 0;
     256           1 :     int edge = 5;
     257             :     char infile[PATH_MAX];
     258             :     char outfile[PATH_MAX];
     259           1 :     char *srcdir = NULL;
     260           1 :     const char *files[] = { "real",
     261             :                             "mysssd",
     262             :                             "ipa",
     263             :                             "test",
     264             :                             "smerge",
     265             :                             "real8",
     266             :                             "real16be",
     267             :                             "real16le",
     268             :                             "real32be",
     269             :                             "real32le",
     270             :                             "symbols",
     271             :                             NULL };
     272             : 
     273           1 :     INIOUT(printf("<==== Read save test ====>\n"));
     274             : 
     275           1 :     srcdir = getenv("srcdir");
     276             : 
     277          13 :     while(files[i]) {
     278          55 :         for ( edge = 10; edge < 100; edge +=19) {
     279          55 :             snprintf(infile, PATH_MAX, "%s/ini/ini.d/%s.conf",
     280             :                     (srcdir == NULL) ? "." : srcdir, files[i]);
     281          55 :             snprintf(outfile, PATH_MAX, "./%s_%d.conf.out", files[i], edge);
     282          55 :             error = test_one_file(infile, outfile, edge, 0);
     283          55 :             INIOUT(printf("Test for file: %s returned %d\n", files[i], error));
     284          55 :             if (error) return error;
     285             :         }
     286          11 :         i++;
     287             :     }
     288             : 
     289           1 :     INIOUT(printf("<==== Read save test end ====>\n"));
     290             : 
     291             :     return EOK;
     292             : }
     293             : 
     294             : 
     295             : /* Run tests for multiple files */
     296           1 : static int read_mem_test(void)
     297             : {
     298           1 :     int error = EOK;
     299           1 :     int i = 0;
     300           1 :     int edge = 5;
     301             :     char infile[PATH_MAX];
     302             :     char outfile[PATH_MAX];
     303           1 :     char *srcdir = NULL;
     304           1 :     const char *files[] = { "real",
     305             :                             "mysssd",
     306             :                             "ipa",
     307             :                             "test",
     308             :                             "smerge",
     309             :                             "real8",
     310             :                             "real16be",
     311             :                             "real16le",
     312             :                             "real32be",
     313             :                             "real32le",
     314             :                             "symbols",
     315             :                             "new_line",
     316             :                             NULL };
     317             : 
     318           1 :     INIOUT(printf("<==== Read mem test ====>\n"));
     319             : 
     320           1 :     srcdir = getenv("srcdir");
     321             : 
     322          14 :     while(files[i]) {
     323          48 :         for ( edge = 15; edge < 100; edge +=25) {
     324          48 :             snprintf(infile, PATH_MAX, "%s/ini/ini.d/%s.conf",
     325             :                     (srcdir == NULL) ? "." : srcdir, files[i]);
     326          48 :             snprintf(outfile, PATH_MAX, "./%s_%d.conf.mem.out", files[i], edge);
     327          48 :             error = test_one_file(infile, outfile, edge, 1);
     328          48 :             INIOUT(printf("Test for file: %s returned %d\n", files[i], error));
     329          48 :             if ((error) && (strncmp(files[i], "test", 4) != 0)) return error;
     330             :         }
     331          12 :         i++;
     332             :     }
     333             : 
     334           1 :     INIOUT(printf("<==== Read mem test end ====>\n"));
     335             : 
     336             :     return EOK;
     337             : }
     338             : 
     339             : 
     340             : /* Run tests for multiple files */
     341           1 : static int read_again_test(void)
     342             : {
     343           1 :     int error = EOK;
     344           1 :     int i = 0;
     345           1 :     int edge = 5;
     346             :     char infile[PATH_MAX];
     347             :     char outfile[PATH_MAX];
     348             :     char command[PATH_MAX * 3];
     349           1 :     const char *files[] = { "real",
     350             :                             "mysssd",
     351             :                             "ipa",
     352             :                             "test",
     353             :                             "smerge",
     354             :                             "real8",
     355             :                             "real16be",
     356             :                             "real16le",
     357             :                             "real32be",
     358             :                             "real32le",
     359             :                             "symbols",
     360             :                             NULL };
     361             : 
     362           1 :     INIOUT(printf("<==== Read again test ====>\n"));
     363             : 
     364          12 :     while(files[i]) {
     365          55 :         for ( edge = 10; edge < 100; edge +=19) {
     366             : 
     367          55 :             snprintf(infile, PATH_MAX, "./%s_%d.conf.out", files[i], edge);
     368          55 :             snprintf(outfile, PATH_MAX, "./%s_%d.conf.2.out", files[i], edge);
     369             : 
     370          55 :             error = test_one_file(infile, outfile, edge, 0);
     371          55 :             INIOUT(printf("Test for file: %s returned %d\n", files[i], error));
     372          55 :             if (error) break;
     373          55 :             snprintf(command, PATH_MAX * 3, "diff -q %s %s", infile, outfile);
     374          55 :             error = system(command);
     375          55 :             INIOUT(printf("Comparison of %s %s returned: %d\n",
     376             :                           infile, outfile, error));
     377          55 :             if ((error) || (WEXITSTATUS(error))) {
     378           0 :                 printf("Failed to run copy command %d %d.\n",  error,
     379           0 :                        WEXITSTATUS(error));
     380           0 :                 error = -1;
     381           0 :                 break;
     382             :             }
     383             :         }
     384             : 
     385          11 :         i++;
     386             :     }
     387             : 
     388           1 :     INIOUT(printf("<==== Read again test end ====>\n"));
     389             : 
     390           1 :     return error;
     391             : }
     392             : 
     393           1 : static int create_expect(const char *checkname)
     394             : {
     395             :     FILE *ff;
     396           1 :     int error = EOK;
     397             : 
     398           1 :     errno = 0;
     399           1 :     ff = fopen(checkname, "w");
     400           1 :     if(!ff) {
     401           0 :         error = errno;
     402           0 :         printf("Failed to open file %s for writing. Error %d.\n",
     403             :                checkname, error);
     404           0 :         return error;
     405             :     }
     406             : 
     407             :     /* Ovewrite */
     408           1 :     fprintf(ff,"#Hoho section\n");
     409           1 :     fprintf(ff,"[hoho]\n");
     410           1 :     fprintf(ff,"#Hoho value\n");
     411           1 :     fprintf(ff,"val = hoho\n");
     412           1 :     fprintf(ff,"#End of hoho\n");
     413           1 :     fprintf(ff,"#Start of section\n");
     414           1 :     fprintf(ff,"[foo]\n");
     415           1 :     fprintf(ff,"#Second value\n");
     416           1 :     fprintf(ff,"bar = second value\n");
     417           1 :     fprintf(ff,"#End of section\n");
     418             :     /* Preserve */
     419           1 :     fprintf(ff,"#Hoho section\n");
     420           1 :     fprintf(ff,"[hoho]\n");
     421           1 :     fprintf(ff,"#Hoho value\n");
     422           1 :     fprintf(ff,"val = hoho\n");
     423           1 :     fprintf(ff,"#End of hoho\n");
     424           1 :     fprintf(ff,"#Start of section\n");
     425           1 :     fprintf(ff,"[foo]\n");
     426           1 :     fprintf(ff,"#First value\n");
     427           1 :     fprintf(ff,"bar = first value\n");
     428           1 :     fprintf(ff,"#End of section\n");
     429             :     /* Allow */
     430           1 :     fprintf(ff,"#Hoho section\n");
     431           1 :     fprintf(ff,"[hoho]\n");
     432           1 :     fprintf(ff,"#Hoho value\n");
     433           1 :     fprintf(ff,"val = hoho\n");
     434           1 :     fprintf(ff,"#End of hoho\n");
     435           1 :     fprintf(ff,"#Start of section\n");
     436           1 :     fprintf(ff,"[foo]\n");
     437           1 :     fprintf(ff,"#First value\n");
     438           1 :     fprintf(ff,"bar = first value\n");
     439           1 :     fprintf(ff,"#Second value\n");
     440           1 :     fprintf(ff,"bar = second value\n");
     441           1 :     fprintf(ff,"#End of section\n");
     442             :     /* Detect */
     443           1 :     fprintf(ff,"#Hoho section\n");
     444           1 :     fprintf(ff,"[hoho]\n");
     445           1 :     fprintf(ff,"#Hoho value\n");
     446           1 :     fprintf(ff,"val = hoho\n");
     447           1 :     fprintf(ff,"#End of hoho\n");
     448           1 :     fprintf(ff,"#Start of section\n");
     449           1 :     fprintf(ff,"[foo]\n");
     450           1 :     fprintf(ff,"#First value\n");
     451           1 :     fprintf(ff,"bar = first value\n");
     452           1 :     fprintf(ff,"#Second value\n");
     453           1 :     fprintf(ff,"bar = second value\n");
     454           1 :     fprintf(ff,"#End of section\n");
     455             : 
     456           1 :     fclose(ff);
     457             : 
     458           1 :     return EOK;
     459             : }
     460             : 
     461             : /* Check merge modes */
     462           1 : static int merge_values_test(void)
     463             : {
     464           1 :     int error = EOK;
     465             :     int i;
     466           1 :     struct ini_cfgfile *file_ctx = NULL;
     467           1 :     FILE *ff = NULL;
     468           1 :     struct ini_cfgobj *ini_config = NULL;
     469           1 :     char **error_list = NULL;
     470           1 :     struct simplebuffer *sbobj = NULL;
     471           1 :     uint32_t left = 0;
     472           1 :     uint32_t mflags[] = { INI_MV1S_OVERWRITE,
     473             :                           INI_MV1S_ERROR,
     474             :                           INI_MV1S_PRESERVE,
     475             :                           INI_MV1S_ALLOW,
     476             :                           INI_MV1S_DETECT };
     477             : 
     478           1 :     const char *mstr[] = { "OVERWRITE",
     479             :                            "ERROR",
     480             :                            "PRESERVE",
     481             :                            "ALLOW",
     482             :                            "DETECT" };
     483             : 
     484             :     char filename[PATH_MAX];
     485           1 :     const char *resname = "./merge.conf.out";
     486           1 :     const char *checkname = "./expect.conf.out";
     487             :     char command[PATH_MAX * 3];
     488           1 :     char *srcdir = NULL;
     489             : 
     490           1 :     INIOUT(printf("<==== Merge values test ====>\n"));
     491             : 
     492           1 :     srcdir = getenv("srcdir");
     493             : 
     494           1 :     snprintf(filename, PATH_MAX, "%s/ini/ini.d/foo.conf.in",
     495             :             (srcdir == NULL) ? "." : srcdir);
     496             : 
     497           1 :     error = simplebuffer_alloc(&sbobj);
     498           1 :     if (error) {
     499             :         TRACE_ERROR_NUMBER("Failed to allocate dynamic string.", error);
     500             :         return error;
     501             :     }
     502             : 
     503           5 :     for (i = 0; i < 5; i++) {
     504             : 
     505           5 :         INIOUT(printf("<==== Testing mode %s  ====>\n", mstr[i]));
     506             : 
     507             :         /* Create config collection */
     508           5 :         ini_config = NULL;
     509           5 :         error = ini_config_create(&ini_config);
     510           5 :         if (error) {
     511           0 :             printf("Failed to create collection. Error %d.\n", error);
     512           0 :             simplebuffer_free(sbobj);
     513           0 :             return error;
     514             :         }
     515             : 
     516           5 :         file_ctx = NULL;
     517           5 :         error = ini_config_file_open(filename,
     518             :                                      0, /* TBD */
     519             :                                      &file_ctx);
     520           5 :         if (error) {
     521           0 :             printf("Failed to open file %s for reading. Error %d.\n",
     522             :                    filename, error);
     523           0 :             printf("Src dir is [%s].\n", (srcdir == NULL) ?
     524             :                    "NOT DEFINED" : srcdir);
     525           0 :             ini_config_destroy(ini_config);
     526           0 :             simplebuffer_free(sbobj);
     527           0 :             return error;
     528             :         }
     529             : 
     530           5 :         error = ini_config_parse(file_ctx,
     531             :                                  INI_STOP_ON_ANY,
     532             :                                  mflags[i],
     533             :                                  0,
     534             :                                  ini_config);
     535           5 :         if (error) {
     536           2 :             INIOUT(printf("Failed to parse configuration. Error %d.\n",
     537             :                           error));
     538             : 
     539           2 :             if (ini_config_error_count(ini_config)) {
     540           1 :                 INIOUT(printf("Errors detected while parsing: %s\n",
     541             :                        ini_config_get_filename(file_ctx)));
     542           1 :                 ini_config_get_errors(ini_config, &error_list);
     543           1 :                 INIOUT(ini_config_print_errors(stdout, error_list));
     544           1 :                 ini_config_free_errors(error_list);
     545             :             }
     546             : 
     547           2 :             if (((mflags[i] != INI_MV1S_ERROR) &&
     548             :                  (mflags[i]!= INI_MV1S_DETECT)) ||
     549           2 :                 ((mflags[i] = INI_MV1S_ERROR) && (error != EEXIST)) ||
     550           2 :                 ((mflags[i] = INI_MV1S_DETECT) && (error != EEXIST))) {
     551           0 :                 printf("This is unexpected error %d in mode %d\n",
     552             :                        error, mflags[i]);
     553           0 :                 ini_config_destroy(ini_config);
     554           0 :                 simplebuffer_free(sbobj);
     555           0 :                 ini_config_file_destroy(file_ctx);
     556           0 :                 return error;
     557             :             }
     558             :             /* We do not return here intentionally */
     559             :         }
     560             : 
     561           5 :         ini_config_file_destroy(file_ctx);
     562             : 
     563           5 :         INIOUT(col_debug_collection(ini_config->cfg, COL_TRAVERSE_DEFAULT));
     564             : 
     565           5 :         error = ini_config_serialize(ini_config, sbobj);
     566           5 :         if (error != EOK) {
     567           0 :             printf("Failed to serialize configuration. Error %d.\n", error);
     568           0 :             ini_config_destroy(ini_config);
     569           0 :             simplebuffer_free(sbobj);
     570           0 :             return error;
     571             :         }
     572             : 
     573           5 :         ini_config_destroy(ini_config);
     574             :     }
     575             : 
     576           1 :     errno = 0;
     577           1 :     ff = fopen(resname, "w");
     578           1 :     if(!ff) {
     579           0 :         error = errno;
     580           0 :         printf("Failed to open file for writing. Error %d.\n", error);
     581           0 :         simplebuffer_free(sbobj);
     582           0 :         return error;
     583             :     }
     584             : 
     585             :     /* Save */
     586           1 :     left = simplebuffer_get_len(sbobj);
     587           3 :     while (left > 0) {
     588           1 :         error = simplebuffer_write(fileno(ff), sbobj, &left);
     589           1 :         if (error) {
     590           0 :             printf("Failed to write back the configuration %d.\n", error);
     591           0 :             simplebuffer_free(sbobj);
     592           0 :             fclose(ff);
     593           0 :             return error;
     594             :         }
     595             :     }
     596             : 
     597           1 :     simplebuffer_free(sbobj);
     598           1 :     fclose(ff);
     599             : 
     600           1 :     error = create_expect(checkname);
     601           1 :     if (error) {
     602           0 :         printf("Failed to create file with expected contents %d.\n",  error);
     603           0 :         return error;
     604             :     }
     605             : 
     606           1 :     snprintf(command, PATH_MAX * 3, "diff -q %s %s", resname, checkname);
     607           1 :     error = system(command);
     608           1 :     INIOUT(printf("Comparison of %s %s returned: %d\n",
     609             :                   resname, checkname, error));
     610           1 :     if ((error) || (WEXITSTATUS(error))) {
     611           0 :         printf("Failed to run copy command %d %d.\n",  error,
     612           0 :                WEXITSTATUS(error));
     613           0 :         return -1;
     614             :     }
     615             : 
     616           1 :     INIOUT(printf("<==== Merge values test end ====>\n"));
     617             : 
     618           1 :     return error;
     619             : }
     620             : 
     621             : /* Check merge modes */
     622           1 : static int merge_section_test(void)
     623             : {
     624           1 :     int error = EOK;
     625             :     int i, j;
     626           1 :     struct ini_cfgfile *file_ctx = NULL;
     627           1 :     FILE *ff = NULL;
     628           1 :     struct ini_cfgobj *ini_config = NULL;
     629           1 :     char **error_list = NULL;
     630           1 :     struct simplebuffer *sbobj = NULL;
     631           1 :     uint32_t left = 0;
     632           1 :     uint32_t msecflags[] = { INI_MS_MERGE,
     633             :                              INI_MS_ERROR,
     634             :                              INI_MS_OVERWRITE,
     635             :                              INI_MS_PRESERVE,
     636             :                              INI_MS_DETECT };
     637             : 
     638           1 :     uint32_t mflags[] = { INI_MV2S_OVERWRITE,
     639             :                           INI_MV2S_ERROR,
     640             :                           INI_MV2S_PRESERVE,
     641             :                           INI_MV2S_ALLOW,
     642             :                           INI_MV2S_DETECT };
     643             : 
     644           1 :     const char *secmstr[] = { "MERGE",
     645             :                               "ERROR",
     646             :                               "OVERWRITE",
     647             :                               "PRESERVE",
     648             :                               "DETECT" };
     649             : 
     650           1 :     const char *mstr[] = { "OVERWRITE",
     651             :                            "ERROR",
     652             :                            "PRESERVE",
     653             :                            "ALLOW",
     654             :                            "DETECT" };
     655             : 
     656             :     char filename[PATH_MAX];
     657             :     char checkname[PATH_MAX];
     658             :     char resname[PATH_MAX];
     659             :     char command[PATH_MAX * 3];
     660             :     char mode[VAL_SIZE];
     661           1 :     char *srcdir = NULL;
     662           1 :     char *builddir = NULL;
     663             : 
     664             : 
     665           1 :     INIOUT(printf("<==== Merge section test ====>\n"));
     666             : 
     667           1 :     srcdir = getenv("srcdir");
     668           1 :     builddir = getenv("builddir");
     669           1 :     snprintf(filename, PATH_MAX, "%s/ini/ini.d/smerge.conf",
     670             :                       (srcdir == NULL) ? "." : srcdir);
     671           1 :     snprintf(checkname, PATH_MAX, "%s/ini/ini.d/sexpect.conf",
     672             :                       (srcdir == NULL) ? "." : srcdir);
     673           1 :     snprintf(resname, PATH_MAX, "%s/smerge.conf.out",
     674             :                       (builddir == NULL) ? "." : builddir);
     675             : 
     676           1 :     error = simplebuffer_alloc(&sbobj);
     677           1 :     if (error) {
     678             :         TRACE_ERROR_NUMBER("Failed to allocate dynamic string.", error);
     679             :         return error;
     680             :     }
     681             : 
     682           5 :     for (i = 0; i < 5; i++) {
     683          25 :         for (j = 0; j < 5; j++) {
     684             : 
     685          25 :             INIOUT(printf("<==== Testing mode %s + %s ====>\n",
     686             :                           secmstr[i], mstr[j]));
     687             : 
     688          25 :             snprintf(mode, VAL_SIZE, "# Section mode: %s, value mode: %s\n",
     689             :                           secmstr[i], mstr[j]);
     690             : 
     691          25 :             error = simplebuffer_add_str(sbobj,
     692             :                                          mode,
     693          25 :                                          strlen(mode),
     694             :                                          VAL_SIZE);
     695          25 :             if (error) {
     696             :                 TRACE_ERROR_NUMBER("Failed to add string.",
     697             :                                    error);
     698           0 :                 simplebuffer_free(sbobj);
     699           0 :                 return error;
     700             :             }
     701             : 
     702             :             /* Create config collection */
     703          25 :             ini_config = NULL;
     704          25 :             error = ini_config_create(&ini_config);
     705          25 :             if (error) {
     706           0 :                 printf("Failed to create collection. "
     707             :                        "Error %d.\n", error);
     708           0 :                 simplebuffer_free(sbobj);
     709           0 :                 return error;
     710             :             }
     711             : 
     712          25 :             file_ctx = NULL;
     713          25 :             error = ini_config_file_open(filename,
     714             :                                          0, /* TBD */
     715             :                                          &file_ctx);
     716          25 :             if (error) {
     717           0 :                 printf("Failed to open file %s for reading. "
     718             :                        "Error %d.\n", filename, error);
     719           0 :                 printf("Source is %s.\n", (srcdir == NULL) ?
     720             :                        "NOT Defined" : srcdir);
     721           0 :                 ini_config_destroy(ini_config);
     722           0 :                 simplebuffer_free(sbobj);
     723           0 :                 return error;
     724             :             }
     725             : 
     726          50 :             error = ini_config_parse(file_ctx,
     727             :                                      INI_STOP_ON_ANY,
     728          25 :                                      msecflags[i] | mflags[j],
     729             :                                      0,
     730             :                                      ini_config);
     731          25 :             if (error) {
     732          12 :                 INIOUT(printf("Failed to parse configuration. "
     733             :                               "Error %d.\n", error));
     734             : 
     735          12 :                 if (ini_config_error_count(ini_config)) {
     736           7 :                     INIOUT(printf("Errors detected while parsing: %s\n",
     737             :                            ini_config_get_filename(file_ctx)));
     738           7 :                     ini_config_get_errors(ini_config, &error_list);
     739           7 :                     INIOUT(ini_config_print_errors(stdout, error_list));
     740           7 :                     ini_config_free_errors(error_list);
     741             :                 }
     742             : 
     743          12 :                 if (((msecflags[i] == INI_MS_ERROR) &&
     744          22 :                      (error == EEXIST)) ||
     745             :                     ((msecflags[i] == INI_MS_DETECT) &&
     746           2 :                      (error == EEXIST)) ||
     747           2 :                     ((msecflags[i] == INI_MS_MERGE) &&
     748           2 :                      ((mflags[j] == INI_MV2S_ERROR) ||
     749           2 :                       (mflags[j] == INI_MV2S_DETECT)) &&
     750             :                       (error == EEXIST))) {
     751          12 :                     INIOUT(printf("This is an expected error "
     752             :                                   "%d in mode %d + %d\n",
     753             :                                   error,
     754             :                                   msecflags[i],
     755             :                                   mflags[j]));
     756             :                     /* We do not return here intentionally */
     757             :                 }
     758             :                 else {
     759           0 :                     printf("This is unexpected error %d in mode %d + %d\n",
     760             :                             error, msecflags[i], mflags[j]);
     761           0 :                     ini_config_destroy(ini_config);
     762           0 :                     simplebuffer_free(sbobj);
     763           0 :                     ini_config_file_destroy(file_ctx);
     764           0 :                     return error;
     765             :                 }
     766             :             }
     767             : 
     768          25 :             ini_config_file_destroy(file_ctx);
     769             : 
     770          25 :             INIOUT(col_debug_collection(ini_config->cfg,
     771             :                    COL_TRAVERSE_DEFAULT));
     772             : 
     773          25 :             error = ini_config_serialize(ini_config, sbobj);
     774          25 :             if (error != EOK) {
     775           0 :                 printf("Failed to serialize configuration. "
     776             :                        "Error %d.\n", error);
     777           0 :                 ini_config_destroy(ini_config);
     778           0 :                 simplebuffer_free(sbobj);
     779           0 :                 return error;
     780             :             }
     781             : 
     782          25 :             ini_config_destroy(ini_config);
     783             :         }
     784             :     }
     785             : 
     786           1 :     errno = 0;
     787           1 :     ff = fopen(resname, "w");
     788           1 :     if(!ff) {
     789           0 :         error = errno;
     790           0 :         printf("Failed to open file for writing. Error %d.\n", error);
     791           0 :         simplebuffer_free(sbobj);
     792           0 :         return error;
     793             :     }
     794             : 
     795             :     /* Save */
     796           1 :     left = simplebuffer_get_len(sbobj);
     797           3 :     while (left > 0) {
     798           1 :         error = simplebuffer_write(fileno(ff), sbobj, &left);
     799           1 :         if (error) {
     800           0 :             printf("Failed to write back the configuration %d.\n", error);
     801           0 :             simplebuffer_free(sbobj);
     802           0 :             fclose(ff);
     803           0 :             return error;
     804             :         }
     805             :     }
     806             : 
     807           1 :     simplebuffer_free(sbobj);
     808           1 :     fclose(ff);
     809             : 
     810           1 :     snprintf(command, PATH_MAX * 3, "diff -q %s %s", resname, checkname);
     811           1 :     error = system(command);
     812           1 :     INIOUT(printf("Comparison of %s %s returned: %d\n",
     813             :                   resname, checkname, error));
     814             : 
     815           1 :     if ((error) || (WEXITSTATUS(error))) {
     816           0 :         printf("Failed to run diff command %d %d.\n",  error,
     817           0 :                WEXITSTATUS(error));
     818           0 :         return -1;
     819             :     }
     820             : 
     821           1 :     INIOUT(printf("<==== Merge section test end ====>\n"));
     822             : 
     823           1 :     return error;
     824             : }
     825             : 
     826          50 : static int read_one_file(char *name,
     827             :                          struct ini_cfgobj *ini_config,
     828             :                          uint32_t collision_flags)
     829             : {
     830          50 :     int error = EOK;
     831          50 :     struct ini_cfgfile *file_ctx = NULL;
     832          50 :     char **error_list = NULL;
     833             : 
     834          50 :     INIOUT(printf("Reading file %s\n", name));
     835             : 
     836          50 :     file_ctx = NULL;
     837          50 :     error = ini_config_file_open(name,
     838             :                                  0,
     839             :                                  &file_ctx);
     840          50 :     if (error) {
     841           0 :         printf("Failed to open file %s for reading. "
     842             :                 "Error %d.\n", name, error);
     843           0 :         return error;
     844             :     }
     845             : 
     846          50 :     INIOUT(printf("Parsing file %s\n", name));
     847             : 
     848          50 :     error = ini_config_parse(file_ctx,
     849             :                              INI_STOP_ON_ANY,
     850             :                              collision_flags,
     851             :                              0,
     852             :                              ini_config);
     853          50 :     if (error) {
     854           0 :         INIOUT(printf("Failed to parse configuration. "
     855             :                       "Error %d.\n", error));
     856             : 
     857           0 :         if (ini_config_error_count(ini_config)) {
     858           0 :             INIOUT(printf("Errors detected while parsing: %s\n",
     859             :                    ini_config_get_filename(file_ctx)));
     860           0 :             ini_config_get_errors(ini_config, &error_list);
     861           0 :             INIOUT(ini_config_print_errors(stdout, error_list));
     862           0 :             ini_config_free_errors(error_list);
     863             :         }
     864           0 :         ini_config_file_destroy(file_ctx);
     865           0 :         return error;
     866             :     }
     867             : 
     868          50 :     ini_config_file_destroy(file_ctx);
     869             : 
     870          50 :     INIOUT(printf("Successfully parsed file %s\n", name));
     871             :     return EOK;
     872             : }
     873             : 
     874             : /* Check merge modes */
     875           1 : static int merge_file_test(void)
     876             : {
     877           1 :     int error = EOK;
     878             :     int i, j;
     879           1 :     struct ini_cfgobj *ini_config_first = NULL;
     880           1 :     struct ini_cfgobj *ini_config_second = NULL;
     881           1 :     struct ini_cfgobj *ini_config_result = NULL;
     882           1 :     struct simplebuffer *sbobj = NULL;
     883           1 :     uint32_t left = 0;
     884           1 :     FILE *ff = NULL;
     885           1 :     uint32_t msecflags[] = { INI_MS_MERGE,
     886             :                              INI_MS_ERROR,
     887             :                              INI_MS_OVERWRITE,
     888             :                              INI_MS_PRESERVE,
     889             :                              INI_MS_DETECT };
     890             : 
     891           1 :     uint32_t m2flags[] = { INI_MV2S_OVERWRITE,
     892             :                            INI_MV2S_ERROR,
     893             :                            INI_MV2S_PRESERVE,
     894             :                            INI_MV2S_ALLOW,
     895             :                            INI_MV2S_DETECT };
     896             : 
     897           1 :     uint32_t m1flags[] = { INI_MV1S_OVERWRITE,
     898             :                            INI_MV1S_ERROR,
     899             :                            INI_MV1S_PRESERVE,
     900             :                            INI_MV1S_ALLOW,
     901             :                            INI_MV1S_DETECT };
     902             : 
     903           1 :     const char *secmstr[] = { "MERGE",
     904             :                               "ERROR",
     905             :                               "OVERWRITE",
     906             :                               "PRESERVE",
     907             :                               "DETECT" };
     908             : 
     909           1 :     const char *mstr[] = { "OVERWRITE",
     910             :                            "ERROR",
     911             :                            "PRESERVE",
     912             :                            "ALLOW",
     913             :                            "DETECT" };
     914             : 
     915             :     char firstname[PATH_MAX];
     916             :     char secondname[PATH_MAX];
     917             :     char resname[PATH_MAX];
     918             :     char checkname[PATH_MAX];
     919             :     char command[PATH_MAX * 3];
     920             :     char msg[VAL_SIZE];
     921             :     char mode[VAL_SIZE];
     922           1 :     char *srcdir = NULL;
     923           1 :     char *builddir = NULL;
     924             :     uint32_t collision_flags;
     925             :     uint32_t ms_subst;
     926             :     uint32_t mv1s_subst;
     927             :     uint32_t mv2s_subst;
     928             : 
     929           1 :     INIOUT(printf("<==== Merge file test ====>\n"));
     930             : 
     931           1 :     srcdir = getenv("srcdir");
     932           1 :     builddir = getenv("builddir");
     933           1 :     snprintf(firstname, PATH_MAX, "%s/ini/ini.d/first.conf",
     934             :                       (srcdir == NULL) ? "." : srcdir);
     935             : 
     936           1 :     snprintf(secondname, PATH_MAX, "%s/ini/ini.d/second.conf",
     937             :                       (srcdir == NULL) ? "." : srcdir);
     938             : 
     939           1 :     snprintf(checkname, PATH_MAX, "%s/ini/ini.d/mergecheck.conf",
     940             :                       (srcdir == NULL) ? "." : srcdir);
     941             : 
     942           1 :     snprintf(resname, PATH_MAX, "%s/mergecheck.conf.out",
     943             :                       (builddir == NULL) ? "." : builddir);
     944             : 
     945           1 :     error = simplebuffer_alloc(&sbobj);
     946           1 :     if (error) {
     947             :         TRACE_ERROR_NUMBER("Failed to allocate dynamic string.", error);
     948             :         return error;
     949             :     }
     950             : 
     951           5 :     for (i = 0; i < 5; i++) {
     952          25 :         for (j = 0; j < 5; j++) {
     953             : 
     954          25 :             INIOUT(printf("<==== Testing mode %s + %s ====>\n",
     955             :                           secmstr[i], mstr[j]));
     956             : 
     957          25 :             snprintf(mode, VAL_SIZE, "# Section mode: %s, value mode: %s\n",
     958             :                           secmstr[i], mstr[j]);
     959             : 
     960          25 :             error = simplebuffer_add_str(sbobj,
     961             :                                          mode,
     962          25 :                                          strlen(mode),
     963             :                                          VAL_SIZE);
     964          25 :             if (error) {
     965             :                 TRACE_ERROR_NUMBER("Failed to add string.",
     966             :                                    error);
     967           0 :                 simplebuffer_free(sbobj);
     968           0 :                 return error;
     969             :             }
     970             : 
     971             :             /* Create first config collection */
     972          25 :             ini_config_first = NULL;
     973          25 :             error = ini_config_create(&ini_config_first);
     974          25 :             if (error) {
     975           0 :                 printf("Failed to create collection. "
     976             :                        "Error %d.\n", error);
     977           0 :                 simplebuffer_free(sbobj);
     978           0 :                 return error;
     979             :             }
     980             : 
     981             :             /* Create second config collection */
     982          25 :             ini_config_second = NULL;
     983          25 :             error = ini_config_create(&ini_config_second);
     984          25 :             if (error) {
     985           0 :                 printf("Failed to create collection. "
     986             :                        "Error %d.\n", error);
     987           0 :                 ini_config_destroy(ini_config_first);
     988           0 :                 simplebuffer_free(sbobj);
     989           0 :                 return error;
     990             :             }
     991             : 
     992             :             /* IMPORTANT: Use same collision flags for reading
     993             :              * of the files and then merging.
     994             :              * Mixing the flags would lead to strange results
     995             :              * that would be hard to debug.
     996             :              */
     997             :             /* However here for purely testing purposes
     998             :              * we will not use error modes in parsing
     999             :              * otherwise we will not be able to try to merge.
    1000             :              * Instead we replace the error and detect modes
    1001             :              * with allow or merge mode.
    1002             :              */
    1003             :             /* The test actually does not fail in the case of
    1004             :              * PRESERVE + ERROR becuase it should fail at
    1005             :              * the stage of reading file but we suppress
    1006             :              * it so we can try the merge.
    1007             :              * As a result the mode PRESERVE + ERROR
    1008             :              * acts as PRESERVE + ALLOW and does not return an error.
    1009             :              * The same thing happens with PRESERVE + DETECT mode.
    1010             :              * It might be confusing if someone tries to decipher
    1011             :              * the tests, so this comment should help.
    1012             :              */
    1013          25 :             if ((msecflags[i] == INI_MS_ERROR) ||
    1014             :                 (msecflags[i] == INI_MS_DETECT)) {
    1015          10 :                 ms_subst = msecflags[i];
    1016             :             }
    1017             :             else {
    1018             :                 ms_subst = INI_MS_MERGE;
    1019             :             }
    1020             : 
    1021          25 :             if ((m2flags[j] == INI_MV2S_ERROR) ||
    1022             :                 (m2flags[j] == INI_MV2S_DETECT)) {
    1023             :                 mv1s_subst = INI_MV1S_ALLOW;
    1024             :                 mv2s_subst = INI_MV2S_ALLOW;
    1025             :             }
    1026             :             else {
    1027          15 :                 mv1s_subst = m1flags[j];
    1028          15 :                 mv2s_subst = m2flags[j];
    1029             :             }
    1030             : 
    1031          25 :             collision_flags = mv1s_subst | mv2s_subst | ms_subst;
    1032             : 
    1033          25 :             error = read_one_file(firstname,
    1034             :                                   ini_config_first,
    1035             :                                   collision_flags);
    1036          25 :             if (error) {
    1037           0 :                 printf("Failed to read %s. "
    1038             :                        "Error %d.\n", firstname, error);
    1039           0 :                 printf("Source is %s.\n", (srcdir == NULL) ?
    1040             :                         "NOT Defined" : srcdir);
    1041           0 :                 ini_config_destroy(ini_config_first);
    1042           0 :                 ini_config_destroy(ini_config_second);
    1043           0 :                 simplebuffer_free(sbobj);
    1044           0 :                 return error;
    1045             :             }
    1046             : 
    1047          25 :             error = read_one_file(secondname,
    1048             :                                   ini_config_second,
    1049             :                                   collision_flags);
    1050          25 :             if (error) {
    1051           0 :                 printf("Failed to read %s. "
    1052             :                        "Error %d.\n", secondname, error);
    1053           0 :                 printf("Source is %s.\n", (srcdir == NULL) ?
    1054             :                         "NOT Defined" : srcdir);
    1055           0 :                 ini_config_destroy(ini_config_first);
    1056           0 :                 ini_config_destroy(ini_config_second);
    1057           0 :                 simplebuffer_free(sbobj);
    1058           0 :                 return error;
    1059             :             }
    1060             : 
    1061          25 :             INIOUT(col_debug_collection(ini_config_first->cfg,
    1062             :                    COL_TRAVERSE_ONELEVEL));
    1063          25 :             INIOUT(col_debug_collection(ini_config_second->cfg,
    1064             :                    COL_TRAVERSE_ONELEVEL));
    1065             : 
    1066          25 :             ini_config_result = NULL;
    1067          25 :             error = ini_config_merge(ini_config_first,
    1068             :                                      ini_config_second,
    1069          25 :                                      msecflags[i] | m2flags[j] | m1flags[j],
    1070             :                                      &ini_config_result);
    1071          25 :             if (error) {
    1072          14 :                 if ((error == EEXIST) &&
    1073           9 :                     ((msecflags[i] == INI_MS_ERROR) ||
    1074             :                      (m2flags[j] == INI_MV2S_ERROR))) {
    1075           8 :                     snprintf(msg, sizeof(msg) -1,
    1076             :                                   "# This is an expected error "
    1077             :                                   "%d in mode %d + %d + %d\n\n",
    1078             :                                   error,
    1079             :                                   msecflags[i],
    1080             :                                   m2flags[j],
    1081             :                                   m1flags[j]);
    1082           8 :                     INIOUT(printf("%s", msg));
    1083           8 :                     error = simplebuffer_add_str(sbobj,
    1084             :                                                  msg,
    1085           8 :                                                  strlen(msg),
    1086             :                                                  VAL_SIZE);
    1087           8 :                     if (error) {
    1088             :                         TRACE_ERROR_NUMBER("Failed to add string.",
    1089             :                                            error);
    1090           0 :                         ini_config_destroy(ini_config_first);
    1091           0 :                         ini_config_destroy(ini_config_second);
    1092           0 :                         simplebuffer_free(sbobj);
    1093           0 :                         return error;
    1094             :                     }
    1095             : 
    1096           8 :                     ini_config_destroy(ini_config_first);
    1097           8 :                     ini_config_destroy(ini_config_second);
    1098           8 :                     continue;
    1099             :                 }
    1100           6 :                 else if ((error == EEXIST) &&
    1101           2 :                          ((msecflags[i] == INI_MS_DETECT) ||
    1102           2 :                           ((msecflags[i] != INI_MS_ERROR) &&
    1103             :                            (m2flags[j] == INI_MV2S_DETECT)))) {
    1104           6 :                     snprintf(msg, sizeof(msg) -1,
    1105             :                                   "# This is an expected error "
    1106             :                                   "%d in mode %d + %d + %d\n\n",
    1107             :                                   error,
    1108             :                                   msecflags[i],
    1109             :                                   m2flags[j],
    1110             :                                   m1flags[j]);
    1111           6 :                     INIOUT(printf("%s", msg));
    1112           6 :                     error = simplebuffer_add_str(sbobj,
    1113             :                                                  msg,
    1114           6 :                                                  strlen(msg),
    1115             :                                                  VAL_SIZE);
    1116           6 :                     if (error) {
    1117             :                         TRACE_ERROR_NUMBER("Failed to add string.",
    1118             :                                            error);
    1119           0 :                         ini_config_destroy(ini_config_first);
    1120           0 :                         ini_config_destroy(ini_config_second);
    1121           0 :                         simplebuffer_free(sbobj);
    1122           0 :                         return error;
    1123             :                     }
    1124             :                     /* Falling throught here */
    1125             :                 }
    1126             :                 else {
    1127             :                     TRACE_ERROR_NUMBER("Failed to merge.",
    1128             :                                        error);
    1129           0 :                     ini_config_destroy(ini_config_first);
    1130           0 :                     ini_config_destroy(ini_config_second);
    1131           0 :                     simplebuffer_free(sbobj);
    1132           0 :                     return error;
    1133             :                 }
    1134             :             }
    1135             : 
    1136          17 :             INIOUT(col_debug_collection(ini_config_result->cfg,
    1137             :                    COL_TRAVERSE_DEFAULT));
    1138             : 
    1139          17 :             error = ini_config_serialize(ini_config_result, sbobj);
    1140          17 :             if (error) {
    1141           0 :                 printf("Failed to serialize configuration. "
    1142             :                        "Error %d.\n", error);
    1143           0 :                 ini_config_destroy(ini_config_first);
    1144           0 :                 ini_config_destroy(ini_config_second);
    1145           0 :                 ini_config_destroy(ini_config_result);
    1146           0 :                 simplebuffer_free(sbobj);
    1147           0 :                 return error;
    1148             :             }
    1149             : 
    1150          17 :             ini_config_destroy(ini_config_first);
    1151          17 :             ini_config_destroy(ini_config_second);
    1152          17 :             ini_config_destroy(ini_config_result);
    1153             :         }
    1154             :     }
    1155             : 
    1156           1 :     errno = 0;
    1157           1 :     ff = fopen(resname, "w");
    1158           1 :     if(!ff) {
    1159           0 :         error = errno;
    1160           0 :         printf("Failed to open file for writing. Error %d.\n", error);
    1161           0 :         simplebuffer_free(sbobj);
    1162           0 :         return error;
    1163             :     }
    1164             : 
    1165             :     /* Save */
    1166           1 :     left = simplebuffer_get_len(sbobj);
    1167           3 :     while (left > 0) {
    1168           1 :         error = simplebuffer_write(fileno(ff), sbobj, &left);
    1169           1 :         if (error) {
    1170           0 :             printf("Failed to write back the configuration %d.\n", error);
    1171           0 :             simplebuffer_free(sbobj);
    1172           0 :             fclose(ff);
    1173           0 :             return error;
    1174             :         }
    1175             :     }
    1176             : 
    1177           1 :     simplebuffer_free(sbobj);
    1178           1 :     fclose(ff);
    1179             : 
    1180           1 :     snprintf(command,PATH_MAX * 3, "diff -q %s %s", resname, checkname);
    1181           1 :     error = system(command);
    1182           1 :     INIOUT(printf("Comparison of %s %s returned: %d\n",
    1183             :                   resname, checkname, error));
    1184             : 
    1185           1 :     if ((error) || (WEXITSTATUS(error))) {
    1186           0 :         printf("Failed to run diff command %d %d.\n",  error,
    1187           0 :                WEXITSTATUS(error));
    1188           0 :         return -1;
    1189             :     }
    1190             : 
    1191           1 :     INIOUT(printf("<==== Merge section file end ====>\n"));
    1192             : 
    1193             :     return EOK;
    1194             : }
    1195             : 
    1196           1 : static int startup_test(void)
    1197             : {
    1198           1 :     int error = EOK;
    1199           1 :     struct ini_cfgfile *file_ctx = NULL;
    1200           1 :     struct ini_cfgobj *ini_config = NULL;
    1201           1 :     char **error_list = NULL;
    1202             :     char infile[PATH_MAX];
    1203             :     char outfile[PATH_MAX];
    1204             :     char command[PATH_MAX * 3];
    1205           1 :     char *srcdir = NULL;
    1206             :     char *builddir;
    1207             :     const struct stat *file_stat;
    1208             : 
    1209           1 :     INIOUT(printf("<==== Startup test ====>\n"));
    1210             : 
    1211           1 :     srcdir = getenv("srcdir");
    1212           1 :     snprintf(infile, PATH_MAX, "%s/ini/ini.d/foo.conf.in",
    1213             :                      (srcdir == NULL) ? "." : srcdir);
    1214           1 :     builddir = getenv("builddir");
    1215           1 :     snprintf(outfile, PATH_MAX, "%s/foo.conf",
    1216             :                       (builddir == NULL) ? "." : builddir);
    1217             : 
    1218           1 :     snprintf(command, PATH_MAX * 3, "cp %s %s", infile, outfile);
    1219           1 :     INIOUT(printf("Running command '%s'\n", command));
    1220             : 
    1221           1 :     error = system(command);
    1222           1 :     if ((error) || (WEXITSTATUS(error))) {
    1223           0 :         printf("Failed to run copy command %d %d.\n",  error,
    1224           0 :                WEXITSTATUS(error));
    1225           0 :         return -1;
    1226             :     }
    1227             : 
    1228           1 :     INIOUT(printf("Running chmod 660 on file '%s'\n", outfile));
    1229           1 :     error = chmod(outfile, S_IRUSR | S_IWUSR);
    1230           1 :     if(error) {
    1231           0 :         error = errno;
    1232           0 :         printf("Failed to run chmod command %d.\n",  error);
    1233           0 :         return error;
    1234             :     }
    1235             : 
    1236             :     /* Open config file not collecting stats */
    1237           1 :     error = ini_config_file_open(outfile,
    1238             :                                  0,
    1239             :                                  &file_ctx);
    1240           1 :     if (error) {
    1241           0 :         printf("Failed to open file %s for reading. Error %d.\n",
    1242             :                outfile, error);
    1243           0 :         return error;
    1244             :     }
    1245             : 
    1246           1 :     file_stat = ini_config_get_stat(file_ctx);
    1247           1 :     if (file_stat) {
    1248           0 :         printf("Expected NULL got not NULL!\n");
    1249           0 :         return EINVAL;
    1250             :     }
    1251             : 
    1252             :     /* We will check just permissions here. */
    1253           1 :     error = ini_config_access_check(file_ctx,
    1254             :                                 INI_ACCESS_CHECK_MODE, /* add uid & gui flags
    1255             :                                                         * in real case
    1256             :                                                         */
    1257             :                                 0, /* <- will be real uid in real case */
    1258             :                                 0, /* <- will be real gid in real case */
    1259             :                                 0440, /* Checking for r--r----- */
    1260             :                                 0);
    1261             :     /* This check is expected to fail since
    1262             :      * we did not collect stats
    1263             :      */
    1264           1 :     ini_config_file_destroy(file_ctx);
    1265             : 
    1266           1 :     if (!error) {
    1267           0 :         printf("Expected error got success!\n");
    1268           0 :         return EACCES;
    1269             :     }
    1270             : 
    1271             : 
    1272             :     /* Open config file */
    1273           1 :     error = ini_config_file_open(outfile,
    1274             :                                  INI_META_STATS,
    1275             :                                  &file_ctx);
    1276           1 :     if (error) {
    1277           0 :         printf("Failed to open file %s for reading. Error %d.\n",
    1278             :                outfile, error);
    1279           0 :         return error;
    1280             :     }
    1281             : 
    1282             :     /* Get stats */
    1283           1 :     file_stat = ini_config_get_stat(file_ctx);
    1284           1 :     if (!file_stat) {
    1285           0 :         printf("Expected not NULL got NULL!\n");
    1286           0 :         return EINVAL;
    1287             :     }
    1288             : 
    1289           1 :     INIOUT(printf("File was modified at: %d seconds since Jan 1 1970.\n",
    1290             :                   (int)(file_stat->st_mtime)));
    1291             : 
    1292             :     /* We will check just permissions here. */
    1293           1 :     error = ini_config_access_check(file_ctx,
    1294             :                                 INI_ACCESS_CHECK_MODE, /* add uid & gui flags
    1295             :                                                         * in real case
    1296             :                                                         */
    1297             :                                 0, /* <- will be real uid in real case */
    1298             :                                 0, /* <- will be real gid in real case */
    1299             :                                 0440, /* Checking for r--r----- */
    1300             :                                 0);
    1301             :     /* This check is expected to fail since
    1302             :      * the actual permissions on the test file are: rw-------
    1303             :      */
    1304             : 
    1305           1 :     if (!error) {
    1306           0 :         printf("Expected error got success!\n");
    1307           0 :         ini_config_file_destroy(file_ctx);
    1308           0 :         return EACCES;
    1309             :     }
    1310             : 
    1311           1 :     error = ini_config_access_check(
    1312             :                         file_ctx,
    1313             :                         INI_ACCESS_CHECK_MODE, /* add uid & gui flags
    1314             :                                                 * in real case
    1315             :                                                 */
    1316             :                         0, /* <- will be real uid in real case */
    1317             :                         0, /* <- will be real gid in real case */
    1318             :                         0600, /* Checkling for rw------- */
    1319             :                         0);
    1320             : 
    1321           1 :     if (error) {
    1322           0 :         printf("Access check failed %d!\n", error);
    1323           0 :         ini_config_file_destroy(file_ctx);
    1324           0 :         return EACCES;
    1325             :     }
    1326             : 
    1327             :     /* Create config object */
    1328           1 :     error = ini_config_create(&ini_config);
    1329           1 :     if (error) {
    1330           0 :         printf("Failed to create collection. Error %d.\n", error);
    1331           0 :         ini_config_file_destroy(file_ctx);
    1332           0 :         return error;
    1333             :     }
    1334             : 
    1335           1 :     error = ini_config_parse(file_ctx,
    1336             :                              INI_STOP_ON_NONE,
    1337             :                              0,
    1338             :                              0,
    1339             :                              ini_config);
    1340           1 :     if (error) {
    1341           0 :         INIOUT(printf("Failed to parse configuration. Error %d.\n", error));
    1342             : 
    1343           0 :         if (ini_config_error_count(ini_config)) {
    1344           0 :             INIOUT(printf("Errors detected while parsing: %s\n",
    1345             :                    ini_config_get_filename(file_ctx)));
    1346           0 :             ini_config_get_errors(ini_config, &error_list);
    1347           0 :             INIOUT(ini_config_print_errors(stdout, error_list));
    1348           0 :             ini_config_free_errors(error_list);
    1349             :         }
    1350             :         /* We do not return here intentionally */
    1351             :     }
    1352             : 
    1353           1 :     ini_config_file_destroy(file_ctx);
    1354             : 
    1355           1 :     INIOUT(col_debug_collection(ini_config->cfg, COL_TRAVERSE_DEFAULT));
    1356             : 
    1357           1 :     ini_config_destroy(ini_config);
    1358             : 
    1359           1 :     INIOUT(printf("<==== Startup test end ====>\n"));
    1360             : 
    1361             :     return 0;
    1362             : }
    1363             : 
    1364           1 : static int reload_test(void)
    1365             : {
    1366           1 :     int error = EOK;
    1367           1 :     struct ini_cfgfile *file_ctx = NULL;
    1368           1 :     struct ini_cfgfile *file_ctx_new = NULL;
    1369             :     char infile[PATH_MAX];
    1370             :     char outfile[PATH_MAX];
    1371             :     char command[PATH_MAX * 3];
    1372             :     char *srcdir;
    1373             :     char *builddir;
    1374           1 :     int changed = 0;
    1375             : 
    1376           1 :     INIOUT(printf("<==== Reload test ====>\n"));
    1377             : 
    1378           1 :     srcdir = getenv("srcdir");
    1379           1 :     snprintf(infile, PATH_MAX, "%s/ini/ini.d/foo.conf.in",
    1380             :                    (srcdir == NULL) ? "." : srcdir);
    1381           1 :     builddir = getenv("builddir");
    1382           1 :     snprintf(outfile, PATH_MAX, "%s/foo.conf",
    1383             :                      (builddir == NULL) ? "." : builddir);
    1384             : 
    1385           1 :     snprintf(command, PATH_MAX * 3, "cp %s %s", infile, outfile);
    1386           1 :     INIOUT(printf("Running command '%s'\n", command));
    1387             : 
    1388           1 :     error = system(command);
    1389           1 :     if ((error) || (WEXITSTATUS(error))) {
    1390           0 :         printf("Failed to run copy command %d %d.\n",  error,
    1391           0 :                WEXITSTATUS(error));
    1392           0 :         return -1;
    1393             :     }
    1394             : 
    1395           1 :     INIOUT(printf("Running chmod 660 on file '%s'\n", outfile));
    1396           1 :     error = chmod(outfile, S_IRUSR | S_IWUSR);
    1397           1 :     if (error) {
    1398           0 :         error = errno;
    1399           0 :         printf("Failed to run chmod command %d.\n",  error);
    1400           0 :         return error;
    1401             :     }
    1402             : 
    1403           1 :     INIOUT(printf("About to open file: %s'\n", outfile));
    1404             : 
    1405             :     /* Open config file */
    1406           1 :     error = ini_config_file_open(outfile,
    1407             :                                  INI_META_STATS,
    1408             :                                  &file_ctx);
    1409           1 :     if (error) {
    1410           0 :         printf("Failed to open file %s for reading. Error %d.\n",
    1411             :                outfile, error);
    1412           0 :         return error;
    1413             :     }
    1414             : 
    1415           1 :     INIOUT(printf("About to check access to the file.\n"));
    1416             : 
    1417           1 :     error = ini_config_access_check(
    1418             :                     file_ctx,
    1419             :                     INI_ACCESS_CHECK_MODE, /* add uid & gui flags
    1420             :                                             * in real case
    1421             :                                             */
    1422             :                     0, /* <- will be real uid in real case */
    1423             :                     0, /* <- will be real gid in real case */
    1424             :                     0600, /* Checkling for rw------- */
    1425             :                     0);
    1426             : 
    1427           1 :     if (error) {
    1428           0 :         printf("Access check failed %d!\n", error);
    1429           0 :         ini_config_file_destroy(file_ctx);
    1430           0 :         return EACCES;
    1431             :     }
    1432             : 
    1433             :     /* ... Create config object and read configuration - not shown here.
    1434             :      *     See other examples ... */
    1435             : 
    1436           1 :     INIOUT(printf("About to close file.\n"));
    1437             : 
    1438             :     /* Now close file but leave the context around */
    1439           1 :     ini_config_file_close(file_ctx);
    1440             : 
    1441           1 :     INIOUT(printf("About to reopen file.\n"));
    1442             : 
    1443             :     /* Some time passed and we received a signal to reload... */
    1444           1 :     error = ini_config_file_reopen(file_ctx, &file_ctx_new);
    1445           1 :     if (error) {
    1446           0 :         printf("Failed to re-open file for reading. Error %d.\n", error);
    1447           0 :         ini_config_file_destroy(file_ctx);
    1448           0 :         return error;
    1449             :     }
    1450             : 
    1451           1 :     INIOUT(printf("About to check if the file changed.\n"));
    1452             : 
    1453           1 :     changed = 0;
    1454           1 :     error = ini_config_changed(file_ctx,
    1455             :                                file_ctx_new,
    1456             :                                &changed);
    1457           1 :     if (error) {
    1458           0 :         printf("Failed to compare files. Error %d.\n",  error);
    1459           0 :         ini_config_file_destroy(file_ctx);
    1460           0 :         ini_config_file_destroy(file_ctx_new);
    1461           0 :         return error;
    1462             :     }
    1463             : 
    1464             :     /* Check if file changed */
    1465           1 :     if (changed) {
    1466           0 :         printf("File changed when it shouldn't. This is unexpected error.\n");
    1467           0 :         ini_config_file_print(file_ctx);
    1468           0 :         ini_config_file_print(file_ctx_new);
    1469           0 :         ini_config_file_destroy(file_ctx);
    1470           0 :         ini_config_file_destroy(file_ctx_new);
    1471           0 :         return EINVAL;
    1472             :     }
    1473             : 
    1474           1 :     INIOUT(printf("File did not change - expected. Close and force the change!.\n"));
    1475             : 
    1476             :     /* Close file */
    1477           1 :     ini_config_file_destroy(file_ctx_new);
    1478             : 
    1479           1 :     INIOUT(printf("To force the change delete the file: %s\n", outfile));
    1480             : 
    1481             :     /* Emulate as if file changed */
    1482           1 :     errno = 0;
    1483           1 :     if (unlink(outfile)) {
    1484           0 :         error = errno;
    1485           0 :         printf("Failed to delete file %d.\n",  error);
    1486           0 :         ini_config_file_destroy(file_ctx);
    1487           0 :         return error;
    1488             :     }
    1489             : 
    1490           1 :     sleep(1);
    1491             : 
    1492           1 :     snprintf(command, PATH_MAX * 3, "cp %s %s", infile, outfile);
    1493           1 :     INIOUT(printf("Copy file again with command '%s'\n", command));
    1494             : 
    1495           1 :     error = system(command);
    1496           1 :     if ((error) || (WEXITSTATUS(error))) {
    1497           0 :         printf("Failed to run copy command %d %d.\n",  error, WEXITSTATUS(error));
    1498           0 :         ini_config_file_destroy(file_ctx);
    1499           0 :         return -1;
    1500             :     }
    1501             : 
    1502           1 :     INIOUT(printf("Read file again.\n"));
    1503             : 
    1504             :     /* Read again */
    1505           1 :     file_ctx_new = NULL;
    1506           1 :     error = ini_config_file_reopen(file_ctx, &file_ctx_new);
    1507           1 :     if (error) {
    1508           0 :         printf("Failed to re-open file for reading. Error %d.\n", error);
    1509           0 :         ini_config_file_destroy(file_ctx);
    1510           0 :         return error;
    1511             :     }
    1512             : 
    1513           1 :     INIOUT(printf("Check if it changed.\n"));
    1514             : 
    1515           1 :     changed = 0;
    1516           1 :     error = ini_config_changed(file_ctx,
    1517             :                                file_ctx_new,
    1518             :                                &changed);
    1519           1 :     if (error) {
    1520           0 :         printf("Failed to compare files. Error %d.\n",  error);
    1521           0 :         ini_config_file_destroy(file_ctx);
    1522           0 :         ini_config_file_destroy(file_ctx_new);
    1523           0 :         return error;
    1524             :     }
    1525             : 
    1526           1 :     INIOUT(printf("Changed value is %d.\n", changed));
    1527             : 
    1528             :     /* Check if file changed */
    1529           1 :     if (!changed) {
    1530           0 :         printf("File did not change when it should. This is an error.\n");
    1531           0 :         ini_config_file_print(file_ctx);
    1532           0 :         ini_config_file_print(file_ctx_new);
    1533           0 :         ini_config_file_destroy(file_ctx);
    1534           0 :         ini_config_file_destroy(file_ctx_new);
    1535           0 :         return EINVAL;
    1536             :     }
    1537             : 
    1538           1 :     INIOUT(printf("File changed!\n"));
    1539           1 :     INIOUT(ini_config_file_print(file_ctx));
    1540           1 :     INIOUT(ini_config_file_print(file_ctx_new));
    1541             : 
    1542             :     /* We do not need original context any more. */
    1543           1 :     ini_config_file_destroy(file_ctx);
    1544             : 
    1545             :     /* New context is now original context */
    1546           1 :     file_ctx = file_ctx_new;
    1547             : 
    1548             :     /* ... Create config object and read configuration - not shown here.
    1549             :      *     See other examples ... */
    1550             : 
    1551           1 :     ini_config_file_destroy(file_ctx);
    1552             : 
    1553           1 :     INIOUT(printf("<==== Reload test end ====>\n"));
    1554             :     return 0;
    1555             : }
    1556             : 
    1557          14 : static int test_one_array(struct ini_cfgobj *ini_config,
    1558             :                           const char *section,
    1559             :                           const char *value,
    1560             :                           int raw,
    1561             :                           int expect,
    1562             :                           const char *sep,
    1563             :                           const char *message)
    1564             : {
    1565          14 :     struct value_obj *vo = NULL;
    1566          14 :     int error = 0;
    1567          14 :     int size = 0;
    1568             :     char **strarray;
    1569             :     char **strptr;
    1570             :     int i;
    1571             : 
    1572          14 :     INIOUT(printf("%s",message));
    1573             : 
    1574          14 :     vo = NULL;
    1575          14 :     error = ini_get_config_valueobj(section,
    1576             :                                     value,
    1577             :                                     ini_config,
    1578             :                                     INI_GET_FIRST_VALUE,
    1579             :                                     &vo);
    1580          14 :     if(error) {
    1581           0 :         printf("Expected success but got error! %d\n",error);
    1582           0 :         return error;
    1583             :     }
    1584             : 
    1585             :     /* Value should be found */
    1586          14 :     if (vo == NULL) {
    1587           0 :         printf("Expected success but got NULL. Section %s value %s, %s\n", section, value, raw ? "raw" : "interpreted");
    1588           0 :         return -1;
    1589             :     }
    1590             : 
    1591          14 :     INIOUT(value_print(value, vo));
    1592             : 
    1593          14 :     INIOUT(printf("Get str array with size.\n"));
    1594             : 
    1595          14 :     error = 0;
    1596             : 
    1597          14 :     if (raw) strarray = ini_get_raw_string_config_array(vo, sep, &size, &error);
    1598           7 :     else strarray = ini_get_string_config_array(vo, sep, &size, &error);
    1599          14 :     if (error) {
    1600           0 :         printf("Expect success got error %d.\n", error);
    1601           0 :         return error;
    1602             :     }
    1603             : 
    1604             :     /* Can be used with this cycle */
    1605             :     strptr = strarray;
    1606          49 :     while (*strptr != NULL) {
    1607          35 :         INIOUT(printf("[%s]\n",*strptr));
    1608          35 :         strptr++;
    1609             :     }
    1610             : 
    1611          14 :     if (size != expect) {
    1612           0 :         printf("Expected %d but got %d.\n", expect, size);
    1613           0 :         ini_free_string_config_array(strarray);
    1614           0 :         return -1;
    1615             :     }
    1616             : 
    1617             :     /* Can be used with this cycle */
    1618          14 :     INIOUT(for (i=0; i<size; i++) printf("[%s]\n", *(strarray + i)));
    1619             : 
    1620          14 :     ini_free_string_config_array(strarray);
    1621             : 
    1622          14 :     return EOK;
    1623             : }
    1624             : 
    1625           1 : static int get_test(void)
    1626             : {
    1627             : 
    1628             :     int error;
    1629             :     int number;
    1630             :     long number_long;
    1631             :     double number_double;
    1632             :     unsigned number_unsigned;
    1633             :     unsigned long number_ulong;
    1634           1 :     unsigned char logical = 0;
    1635             :     char *str;
    1636             :     const char *cstr;
    1637             :     const char *cstrn;
    1638             :     void *binary;
    1639             :     int length;
    1640           1 :     int i = 0;
    1641             :     char **strarray;
    1642             :     char **strptr;
    1643             :     int size;
    1644             :     long *array;
    1645             :     double *darray;
    1646             :     char **prop_array;
    1647             :     int32_t val_int32;
    1648             :     uint32_t val_uint32;
    1649             :     int64_t val_int64;
    1650             :     uint64_t val_uint64;
    1651           1 :     struct ini_cfgfile *file_ctx = NULL;
    1652           1 :     struct ini_cfgobj *ini_config = NULL;
    1653           1 :     struct value_obj *vo = NULL;
    1654           1 :     char **error_list = NULL;
    1655             :     char infile[PATH_MAX];
    1656           1 :     char *srcdir = NULL;
    1657           1 :     int bad_val = 0;
    1658             : 
    1659             :     /* Define structure for testing arrays in the loop */
    1660             :     struct a_t { char section[100];
    1661             :                  char value[100];
    1662             :                  int raw;
    1663             :                  int expect;
    1664             :                  char sep[10];
    1665           1 :                  char message[100]; } array_test[NUM_TESTS] =
    1666             :             {
    1667             :                 { "services",
    1668             :                   "activeServices",
    1669             :                   0,
    1670             :                   4,
    1671             :                   ",:;",
    1672             :                   "Make sure we parse string array properly\n"},
    1673             : 
    1674             :                 { "services",
    1675             :                   "activeServices",
    1676             :                   1,
    1677             :                   4,
    1678             :                   ",:;",
    1679             :                   "Make sure we parse raw string array properly\n"},
    1680             : 
    1681             :                 { "domains",
    1682             :                   "domainsOrder",
    1683             :                   0,
    1684             :                   3,
    1685             :                   ",:;",
    1686             :                   "Parse string array with comma at the end\n"},
    1687             : 
    1688             :                 { "domains",
    1689             :                   "domainsOrder",
    1690             :                   1,
    1691             :                   8,
    1692             :                   ",:;",
    1693             :                   "Parse raw string array with comma at the end\n"},
    1694             : 
    1695             :                 { "domains",
    1696             :                   "badarray",
    1697             :                   0,
    1698             :                   0,
    1699             :                   ",:;",
    1700             :                   "Bad array should have no tokens\n"},
    1701             : 
    1702             :                 { "domains",
    1703             :                   "badarray",
    1704             :                   1,
    1705             :                   6,
    1706             :                   ",:;",
    1707             :                   "Raw bad array should have right number of tokens.\n"},
    1708             : 
    1709             :                 { "domains",
    1710             :                   "somearray",
    1711             :                   0,
    1712             :                   0,
    1713             :                   ",:;",
    1714             :                   "Bad array should have no tokens\n"},
    1715             : 
    1716             :                 { "domains",
    1717             :                   "somearray",
    1718             :                   1,
    1719             :                   2,
    1720             :                   ",:;",
    1721             :                   "Raw bad array should have right number of tokens.\n"},
    1722             : 
    1723             :                 { "domains",
    1724             :                   "someotherarray",
    1725             :                   0,
    1726             :                   0,
    1727             :                   ",:;",
    1728             :                   "Bad array should have no tokens\n"},
    1729             : 
    1730             :                 { "domains",
    1731             :                   "someotherarray",
    1732             :                   1,
    1733             :                   3,
    1734             :                   ",:;",
    1735             :                   "Raw bad array should have right number of tokens.\n"},
    1736             : 
    1737             :                 { "domains",
    1738             :                   "justdelim",
    1739             :                   0,
    1740             :                   0,
    1741             :                   ",:;",
    1742             :                   "Bad array should have no tokens\n"},
    1743             : 
    1744             :                 { "domains",
    1745             :                   "justdelim",
    1746             :                   1,
    1747             :                   5,
    1748             :                   ",:;",
    1749             :                   "Delimeters only should have right number of tokens.\n"},
    1750             : 
    1751             :                 { "domains",
    1752             :                   "yetanother",
    1753             :                   0,
    1754             :                   0,
    1755             :                   ",:;",
    1756             :                   "Empty array should have no tokens.\n"},
    1757             : 
    1758             :                 { "domains",
    1759             :                   "yetanother",
    1760             :                   1,
    1761             :                   0,
    1762             :                   ",:;",
    1763             :                   "Empty raw array should have no token.\n"}
    1764             :             };
    1765             : 
    1766             :     /*****************************************************/
    1767             : 
    1768           1 :     INIOUT(printf("\n\n<==== GET TEST START =====>\n"));
    1769           1 :     INIOUT(printf("Creating configuration object\n"));
    1770             : 
    1771             :     /* Create config collection */
    1772           1 :     error = ini_config_create(&ini_config);
    1773           1 :     if (error) {
    1774           0 :         printf("Failed to create collection. Error %d.\n", error);
    1775           0 :         return error;
    1776             :     }
    1777             : 
    1778           1 :     srcdir = getenv("srcdir");
    1779           1 :     snprintf(infile, PATH_MAX, "%s/ini/ini.d/real.conf",
    1780             :              (srcdir == NULL) ? "." : srcdir);
    1781             : 
    1782           1 :     INIOUT(printf("Reading file %s\n", infile));
    1783             : 
    1784           1 :     error = ini_config_file_open(infile,
    1785             :                                  0,
    1786             :                                  &file_ctx);
    1787           1 :     if (error) {
    1788           0 :         printf("Failed to open file for reading. Error %d.\n",  error);
    1789           0 :         ini_config_destroy(ini_config);
    1790           0 :         return error;
    1791             :     }
    1792             : 
    1793           1 :     error = ini_config_parse(file_ctx,
    1794             :                              INI_STOP_ON_NONE,
    1795             :                              /* Merge section but allow duplicates */
    1796             :                              INI_MS_MERGE |
    1797             :                              INI_MV1S_ALLOW |
    1798             :                              INI_MV2S_ALLOW,
    1799             :                              0,
    1800             :                              ini_config);
    1801           1 :     if (error) {
    1802           0 :         INIOUT(printf("Failed to parse configuration. Error %d.\n", error));
    1803             : 
    1804           0 :         if (ini_config_error_count(ini_config)) {
    1805           0 :             INIOUT(printf("Errors detected while parsing: %s\n",
    1806             :                    ini_config_get_filename(file_ctx)));
    1807           0 :             ini_config_get_errors(ini_config, &error_list);
    1808           0 :             INIOUT(ini_config_print_errors(stdout, error_list));
    1809           0 :             ini_config_free_errors(error_list);
    1810             :         }
    1811             :         /* We do not return here intentionally */
    1812             :     }
    1813             : 
    1814           1 :     ini_config_file_destroy(file_ctx);
    1815             : 
    1816           1 :     INIOUT(printf("Negtive test - trying to get non"
    1817             :                   " existing key-value pair.\n"));
    1818             : 
    1819             :     /* Negative test */
    1820           1 :     vo = NULL;
    1821           1 :     error = ini_get_config_valueobj("monitor1",
    1822             :                                     "description1",
    1823             :                                     ini_config,
    1824             :                                     INI_GET_FIRST_VALUE,
    1825             :                                     &vo);
    1826           1 :     if (error) {
    1827           0 :         printf("Expected success but got error! %d\n", error);
    1828           0 :         ini_config_destroy(ini_config);
    1829           0 :         return error;
    1830             :     }
    1831             : 
    1832             :     /* Values should not be found */
    1833           1 :     if (vo != NULL) {
    1834           0 :         printf("Expected NULL but got something else!\n");
    1835           0 :         ini_config_destroy(ini_config);
    1836           0 :         return -1;
    1837             :     }
    1838             : 
    1839             :     /* Another negative test but section exists this time */
    1840           1 :     vo = NULL;
    1841           1 :     error = ini_get_config_valueobj("monitor",
    1842             :                                     "description1",
    1843             :                                     ini_config,
    1844             :                                     INI_GET_FIRST_VALUE,
    1845             :                                     &vo);
    1846           1 :     if (error) {
    1847           0 :         printf("Expected success but got error! %d\n", error);
    1848           0 :         ini_config_destroy(ini_config);
    1849           0 :         return error;
    1850             :     }
    1851             : 
    1852             :     /* Valueobj should not be found */
    1853           1 :     if(vo != NULL) {
    1854           0 :         printf("Expected NULL but got something else!\n");
    1855           0 :         ini_config_destroy(ini_config);
    1856           0 :         return -1;
    1857             :     }
    1858             : 
    1859           1 :     INIOUT(printf("Trying to get a value.\n"));
    1860             : 
    1861             :     /* Positive test */
    1862           1 :     vo = NULL;
    1863           1 :     error = ini_get_config_valueobj("monitor",
    1864             :                                     "description",
    1865             :                                     ini_config,
    1866             :                                     INI_GET_FIRST_VALUE,
    1867             :                                     &vo);
    1868           1 :     if (error) {
    1869           0 :         printf("Expected success but got error! %d\n", error);
    1870           0 :         ini_config_destroy(ini_config);
    1871           0 :         return error;
    1872             :     }
    1873             : 
    1874             :     /* Value should be found */
    1875           1 :     if (vo == NULL) {
    1876           0 :         printf("Expected value but got NULL!\n");
    1877           0 :         ini_config_destroy(ini_config);
    1878           0 :         return -1;
    1879             :     }
    1880             : 
    1881           1 :     INIOUT(value_print("description", vo));
    1882             : 
    1883           1 :     INIOUT(printf("Get values as string without duplication"
    1884             :                   " from the NULL valueobj.\n"));
    1885             : 
    1886             :     /* Get a string without duplicication */
    1887             :     /* Negative test */
    1888           1 :     cstrn = ini_get_const_string_config_value(NULL, NULL);
    1889           1 :     if (cstrn != NULL) {
    1890           0 :         printf("Expected error got success.\n");
    1891           0 :         ini_config_destroy(ini_config);
    1892           0 :         return -1;
    1893             :     }
    1894             : 
    1895           1 :     INIOUT(printf("Get value as string without duplication"
    1896             :                   "from the correct value object.\n"));
    1897             : 
    1898             :     /* Now get string from the right value object */
    1899           1 :     error = 0;
    1900           1 :     cstr = ini_get_const_string_config_value(vo, &error);
    1901           1 :     if (error) {
    1902           0 :         printf("Expected success got error %d.\n", error);
    1903           0 :         ini_config_destroy(ini_config);
    1904           0 :         return error;
    1905             :     }
    1906             : 
    1907           1 :     INIOUT(printf("Value: [%s]\n", cstr));
    1908             : 
    1909             :     /* Same thing but create a dup */
    1910             : 
    1911           1 :     INIOUT(printf("Get value as string with duplication"
    1912             :                   " from correct value object.\n"));
    1913             : 
    1914           1 :     error = 0;
    1915           1 :     str = ini_get_string_config_value(vo, &error);
    1916           1 :     if (error) {
    1917           0 :         printf("Expected success got error %d.\n", error);
    1918           0 :         ini_config_destroy(ini_config);
    1919           0 :         return error;
    1920             :     }
    1921             : 
    1922           1 :     INIOUT(printf("Value: [%s]\n", str));
    1923           1 :     free(str);
    1924             : 
    1925             : 
    1926             :     /* Get a badly formated number */
    1927           1 :     INIOUT(printf("Convert value to number with strict conversion.\n"));
    1928             : 
    1929           1 :     vo = NULL;
    1930           1 :     error = ini_get_config_valueobj("monitor",
    1931             :                                     "bad_number",
    1932             :                                     ini_config,
    1933             :                                     INI_GET_FIRST_VALUE,
    1934             :                                     &vo);
    1935           1 :     if (error) {
    1936           0 :         printf("Expected success but got error! %d\n", error);
    1937           0 :         ini_config_destroy(ini_config);
    1938           0 :         return error;
    1939             :     }
    1940             : 
    1941             :     /* Value should be found */
    1942           1 :     if (vo == NULL) {
    1943           0 :         printf("Expected value but got something NULL!\n");
    1944           0 :         ini_config_destroy(ini_config);
    1945           0 :         return -1;
    1946             :     }
    1947             : 
    1948           1 :     INIOUT(value_print("bad_number", vo));
    1949             : 
    1950             :     /* Now try to get value in different ways */
    1951           1 :     error = 0;
    1952           1 :     number = ini_get_int_config_value(vo, 1, 10, &error);
    1953           1 :     if (error) {
    1954             :         /* We expected error in this case */
    1955           1 :         INIOUT(printf("Expected error.\n"));
    1956           1 :         if(number != 10) {
    1957           0 :             printf("It failed to set default value.\n");
    1958           0 :             ini_config_destroy(ini_config);
    1959           0 :             return -1;
    1960             :         }
    1961             :     }
    1962             :     else {
    1963           0 :         printf("Expected error got success.\n");
    1964           0 :         ini_config_destroy(ini_config);
    1965           0 :         return -1;
    1966             :     }
    1967             : 
    1968           1 :     INIOUT(printf("Convert value to number without strict conversion.\n"));
    1969             : 
    1970           1 :     error = 0;
    1971           1 :     number = ini_get_int_config_value(vo, 0, 10, &error);
    1972           1 :     if (error) {
    1973           0 :         printf("Did not expect error.\n");
    1974           0 :         ini_config_destroy(ini_config);
    1975           0 :         return error;
    1976             :     }
    1977             : 
    1978           1 :     if (number != 5) {
    1979           0 :         printf("We expected that the conversion will return 5.\n");
    1980           0 :         ini_config_destroy(ini_config);
    1981           0 :         return -1;
    1982             :     }
    1983             : 
    1984             :     /* Get real integer */
    1985             : 
    1986           1 :     INIOUT(printf("Fetch another value from section \"domains/LOCAL\""
    1987             :                   " named \"enumerate\".\n"));
    1988             : 
    1989           1 :     vo = NULL;
    1990           1 :     error = ini_get_config_valueobj("domains/LOCAL",
    1991             :                                     "enumerate",
    1992             :                                     ini_config,
    1993             :                                     INI_GET_FIRST_VALUE,
    1994             :                                     &vo);
    1995           1 :     if (error) {
    1996           0 :         printf("Expected success but got error! %d\n", error);
    1997           0 :         ini_config_destroy(ini_config);
    1998           0 :         return error;
    1999             :     }
    2000             : 
    2001             :     /* Value should be found */
    2002           1 :     if (vo == NULL) {
    2003           0 :         printf("Expected success but got NULL.\n");
    2004           0 :         ini_config_destroy(ini_config);
    2005           0 :         return -1;
    2006             :     }
    2007             : 
    2008           1 :     INIOUT(printf("Convert value to integer.\n"));
    2009             : 
    2010             :     /* Take number out of it */
    2011           1 :     error = 0;
    2012           1 :     number = ini_get_int_config_value(vo, 1, 100, &error);
    2013           1 :     if (error) {
    2014           0 :         printf("Did not expect error. Got %d\n", error);
    2015           0 :         ini_config_destroy(ini_config);
    2016           0 :         return error;
    2017             :     }
    2018             : 
    2019             :     /* It is 3 in the file */
    2020           1 :     if (number != 3) {
    2021           0 :         printf("We expected that the conversion will return 3.\n");
    2022           0 :         ini_config_destroy(ini_config);
    2023           0 :         return -1;
    2024             :     }
    2025             : 
    2026           1 :     INIOUT(printf("Expected 3 got %d\n", number));
    2027             : 
    2028           1 :     INIOUT(printf("Convert value to long.\n"));
    2029             : 
    2030             :     /* Take number out of it */
    2031           1 :     error = 0;
    2032           1 :     number_long = ini_get_long_config_value(vo, 1, 100, &error);
    2033           1 :     if (error) {
    2034           0 :         printf("Did not expect error. Got %d\n", error);
    2035           0 :         ini_config_destroy(ini_config);
    2036           0 :         return error;
    2037             :     }
    2038             : 
    2039             :     /* It is 3 in the file */
    2040           1 :     if (number_long != 3) {
    2041           0 :         printf("We expected that the conversion will return 3.\n");
    2042           0 :         ini_config_destroy(ini_config);
    2043           0 :         return -1;
    2044             :     }
    2045             : 
    2046           1 :     INIOUT(printf("Expected 3 got %ld\n", number_long));
    2047             : 
    2048           1 :     INIOUT(printf("Convert value to unsigned.\n"));
    2049             : 
    2050             :     /* Take number out of it */
    2051           1 :     error = 0;
    2052           1 :     number_unsigned = ini_get_unsigned_config_value(vo, 1, 100, &error);
    2053           1 :     if (error) {
    2054           0 :         printf("Did not expect error. Got %d\n", error);
    2055           0 :         ini_config_destroy(ini_config);
    2056           0 :         return error;
    2057             :     }
    2058             : 
    2059             :     /* It is 3 in the file */
    2060           1 :     if (number_unsigned != 3) {
    2061           0 :         printf("We expected that the conversion will return 3.\n");
    2062           0 :         ini_config_destroy(ini_config);
    2063           0 :         return -1;
    2064             :     }
    2065             : 
    2066           1 :     INIOUT(printf("Expected 3 got %d\n", number_unsigned));
    2067             : 
    2068           1 :     INIOUT(printf("Convert value to unsigned long.\n"));
    2069             : 
    2070             :     /* Take number out of it */
    2071           1 :     error = 0;
    2072           1 :     number_ulong = ini_get_ulong_config_value(vo, 1, 100, &error);
    2073           1 :     if (error) {
    2074           0 :         printf("Did not expect error. Got %d\n", error);
    2075           0 :         ini_config_destroy(ini_config);
    2076           0 :         return error;
    2077             :     }
    2078             : 
    2079             :     /* It is 3 in the file */
    2080           1 :     if (number_ulong != 3) {
    2081           0 :         printf("We expected that the conversion will return 3.\n");
    2082           0 :         ini_config_destroy(ini_config);
    2083           0 :         return -1;
    2084             :     }
    2085             : 
    2086           1 :     INIOUT(printf("Expected 3 got %lu\n", number_ulong));
    2087             : 
    2088           1 :     INIOUT(printf("Convert value to double.\n"));
    2089             : 
    2090             :     /* Take number out of it */
    2091           1 :     error = 0;
    2092           1 :     number_double = ini_get_double_config_value(vo, 1, 100., &error);
    2093           1 :     if (error) {
    2094           0 :         printf("Did not expect error. Got %d\n", error);
    2095           0 :         ini_config_destroy(ini_config);
    2096           0 :         return error;
    2097             :     }
    2098             : 
    2099             :     /* It is 3 in the file */
    2100           1 :     if (number_double != 3.) {
    2101           0 :         printf("We expected that the conversion will return 3.\n");
    2102           0 :         ini_config_destroy(ini_config);
    2103           0 :         return -1;
    2104             :     }
    2105             : 
    2106           1 :     INIOUT(printf("Expected 3 got %e\n", number_double));
    2107             : 
    2108           1 :     INIOUT(printf("Convert value to bool.\n"));
    2109             : 
    2110             :     /* Take number out of it */
    2111           1 :     error = 0;
    2112           1 :     logical = ini_get_bool_config_value(vo, 1, &error);
    2113           1 :     if (!error) {
    2114           0 :         printf("Expect error. Got success. Value %d\n", (int) logical);
    2115           0 :         ini_config_destroy(ini_config);
    2116           0 :         return -1;
    2117             :     }
    2118             : 
    2119             :     /* Get real bool values and convert it */
    2120           1 :     INIOUT(printf("Get real bool value \"legacy\" and convert it.\n"));
    2121             : 
    2122           1 :     vo = NULL;
    2123           1 :     error = ini_get_config_valueobj("domains/LOCAL",
    2124             :                                     "legacy",
    2125             :                                     ini_config,
    2126             :                                     INI_GET_FIRST_VALUE,
    2127             :                                     &vo);
    2128           1 :     if (error) {
    2129           0 :         printf("Expected success but got error! %d\n",error);
    2130           0 :         ini_config_destroy(ini_config);
    2131           0 :         return error;
    2132             :     }
    2133             : 
    2134             :     /* Value should be found */
    2135           1 :     if (vo == NULL) {
    2136           0 :         printf("Expected success but got NULL.\n");
    2137           0 :         ini_config_destroy(ini_config);
    2138           0 :         return -1;
    2139             :     }
    2140             : 
    2141           1 :     INIOUT(printf("Convert values to bool.\n"));
    2142             : 
    2143           1 :     error = 0;
    2144           1 :     logical = ini_get_bool_config_value(vo, 1, &error);
    2145           1 :     if (error) {
    2146           0 :         printf("Expect success got error %d.\n", error);
    2147           0 :         ini_config_destroy(ini_config);
    2148           0 :         return error;
    2149             :     }
    2150             : 
    2151           1 :     if (logical) {
    2152           0 :         printf("Expected false but got true - bad.\n");
    2153           0 :         return -1;
    2154             :     }
    2155             : 
    2156           1 :     INIOUT(printf("In the files it is FALSE so we got false.\n"));
    2157             : 
    2158           1 :     INIOUT(printf("Get binary value\n"));
    2159             : 
    2160           1 :     vo = NULL;
    2161           1 :     error = ini_get_config_valueobj("domains/EXAMPLE.COM",
    2162             :                                     "binary_test",
    2163             :                                     ini_config,
    2164             :                                     INI_GET_FIRST_VALUE,
    2165             :                                     &vo);
    2166           1 :     if (error) {
    2167           0 :         printf("Expected success but got error! %d\n", error);
    2168           0 :         ini_config_destroy(ini_config);
    2169           0 :         return error;
    2170             :     }
    2171             : 
    2172             :     /* Value should be found */
    2173           1 :     if (vo == NULL) {
    2174           0 :         printf("Expected success but got NULL.\n");
    2175           0 :         ini_config_destroy(ini_config);
    2176           0 :         return -1;
    2177             :     }
    2178             : 
    2179           1 :     INIOUT(value_print("binary_test", vo));
    2180             : 
    2181           1 :     error = 0;
    2182           1 :     binary = ini_get_bin_config_value(vo, &length, &error);
    2183           1 :     if (error) {
    2184           0 :         printf("Expect success got error %d.\n", error);
    2185           0 :         ini_config_destroy(ini_config);
    2186           0 :         return error;
    2187             :     }
    2188             : 
    2189           1 :     INIOUT(printf("Binary value (expect 123) = "));
    2190           1 :     INIOUT(for (i = 0; i < length; i++) {
    2191             :                 printf("%d",*((unsigned char*)(binary) + i));
    2192             :                 if (*((unsigned char*)(binary) + i) != (i + 1)) bad_val = 1;
    2193             :            });
    2194           1 :     INIOUT(printf("\n"));
    2195             : 
    2196           1 :     ini_free_bin_config_value(binary);
    2197             : 
    2198           1 :     if (bad_val) {
    2199           0 :         printf("Unexpected binary value.\n");
    2200           0 :         ini_config_destroy(ini_config);
    2201           0 :         return -1;
    2202             :     }
    2203             : 
    2204           1 :     INIOUT(printf("Get another binary value\n"));
    2205             : 
    2206           1 :     bad_val = 0;
    2207           1 :     vo = NULL;
    2208           1 :     error = ini_get_config_valueobj("domains/EXAMPLE.COM",
    2209             :                                     "binary_test_two",
    2210             :                                     ini_config,
    2211             :                                     INI_GET_FIRST_VALUE,
    2212             :                                     &vo);
    2213           1 :     if (error) {
    2214           0 :         printf("Expected success but got error! %d\n", error);
    2215           0 :         ini_config_destroy(ini_config);
    2216           0 :         return error;
    2217             :     }
    2218             : 
    2219             :     /* Value should be found */
    2220           1 :     if (vo == NULL) {
    2221           0 :         printf("Expected success but got NULL.\n");
    2222           0 :         ini_config_destroy(ini_config);
    2223           0 :         return -1;
    2224             :     }
    2225             : 
    2226           1 :     INIOUT(value_print("binary_test_two", vo));
    2227             : 
    2228           1 :     error = 0;
    2229           1 :     binary = ini_get_bin_config_value(vo, &length, &error);
    2230           1 :     if (error) {
    2231           0 :         printf("Expect success got error %d.\n", error);
    2232           0 :         ini_config_destroy(ini_config);
    2233           0 :         return error;
    2234             :     }
    2235             : 
    2236           1 :     INIOUT(printf("Binary value (expect abc) = "));
    2237           1 :     INIOUT(for (i = 0; i < length; i++) {
    2238             :                 printf("%x",*((unsigned char*)(binary) + i));
    2239             :                 if (*((unsigned char*)(binary) + i) - 10 != i) bad_val = 1;
    2240             :            });
    2241           1 :     INIOUT(printf("\n"));
    2242             : 
    2243           1 :     ini_free_bin_config_value(binary);
    2244             : 
    2245           1 :     if (bad_val) {
    2246           0 :         printf("Unexpected binary value.\n");
    2247           0 :         ini_config_destroy(ini_config);
    2248           0 :         return -1;
    2249             :     }
    2250             : 
    2251           1 :     INIOUT(printf("Get string array value\n"));
    2252             : 
    2253           1 :     vo = NULL;
    2254           1 :     error = ini_get_config_valueobj("domains",
    2255             :                                     "domainsorder",
    2256             :                                     ini_config,
    2257             :                                     INI_GET_FIRST_VALUE,
    2258             :                                     &vo);
    2259           1 :     if(error) {
    2260           0 :         printf("Expected success but got error! %d\n",error);
    2261           0 :         ini_config_destroy(ini_config);
    2262           0 :         return error;
    2263             :     }
    2264             : 
    2265             :     /* Value should be found */
    2266           1 :     if (vo == NULL) {
    2267           0 :         printf("Expected success but got NULL.\n");
    2268           0 :         ini_config_destroy(ini_config);
    2269           0 :         return -1;
    2270             :     }
    2271             : 
    2272           1 :     INIOUT(value_print("domainsorder", vo));
    2273             : 
    2274           1 :     INIOUT(printf("Get str array without size.\n"));
    2275             : 
    2276           1 :     error = 0;
    2277           1 :     strarray = ini_get_string_config_array(vo, ",", NULL, &error);
    2278           1 :     if (error) {
    2279           0 :         printf("Expect success got error %d.\n", error);
    2280           0 :         ini_config_destroy(ini_config);
    2281           0 :         return error;
    2282             :     }
    2283             : 
    2284             :     /* Can be used with this cycle */
    2285             :     strptr = strarray;
    2286           4 :     while (*strptr != NULL) {
    2287           3 :         INIOUT(printf("[%s]\n",*strptr));
    2288           3 :         strptr++;
    2289             :     }
    2290             : 
    2291           1 :     ini_free_string_config_array(strarray);
    2292             : 
    2293           1 :     INIOUT(printf("Get raw str array without size.\n"));
    2294             : 
    2295           1 :     error = 0;
    2296           1 :     strarray = ini_get_raw_string_config_array(vo, ",", NULL, &error);
    2297           1 :     if (error) {
    2298           0 :         printf("Expect success got error %d.\n", error);
    2299           0 :         ini_config_destroy(ini_config);
    2300           0 :         return error;
    2301             :     }
    2302             : 
    2303             :     /* Can be used with this cycle */
    2304             :     strptr = strarray;
    2305           9 :     while (*strptr != NULL) {
    2306           8 :         INIOUT(printf("[%s]\n",*strptr));
    2307           8 :         strptr++;
    2308             :     }
    2309             : 
    2310           1 :     ini_free_string_config_array(strarray);
    2311             : 
    2312           1 :     INIOUT(printf("Get str array with size.\n"));
    2313             : 
    2314           1 :     error = 0;
    2315           1 :     size = 0;
    2316           1 :     strarray = ini_get_string_config_array(vo, ",", &size, &error);
    2317           1 :     if (error) {
    2318           0 :         printf("Expect success got error %d.\n", error);
    2319           0 :         ini_config_destroy(ini_config);
    2320           0 :         return error;
    2321             :     }
    2322             : 
    2323             :     /* Can be used with this cycle */
    2324           1 :     INIOUT(for (i=0;i<size;i++) printf("[%s]\n",*(strarray + i)));
    2325             : 
    2326           1 :     ini_free_string_config_array(strarray);
    2327             : 
    2328           1 :     INIOUT(printf("Get raw str array with size.\n"));
    2329             : 
    2330           1 :     error = 0;
    2331           1 :     size = 0;
    2332           1 :     strarray = ini_get_raw_string_config_array(vo, ",", &size, &error);
    2333           1 :     if (error) {
    2334           0 :         printf("Expect success got error %d.\n", error);
    2335           0 :         ini_config_destroy(ini_config);
    2336           0 :         return error;
    2337             :     }
    2338             : 
    2339             :     /* Can be used with this cycle */
    2340           1 :     INIOUT(for (i=0;i<size;i++) printf("[%s]\n",*(strarray + i)));
    2341             : 
    2342           1 :     ini_free_string_config_array(strarray);
    2343             : 
    2344             :     /**********************************************************/
    2345             : 
    2346           1 :     INIOUT(printf("Get bad string array \n"));
    2347             : 
    2348           1 :     vo = NULL;
    2349           1 :     error = ini_get_config_valueobj("domains",
    2350             :                                     "badarray",
    2351             :                                     ini_config,
    2352             :                                     INI_GET_FIRST_VALUE,
    2353             :                                     &vo);
    2354           1 :     if(error) {
    2355           0 :         printf("Expected success but got error! %d\n",error);
    2356           0 :         ini_config_destroy(ini_config);
    2357           0 :         return error;
    2358             :     }
    2359             : 
    2360             :     /* Value should be found */
    2361           1 :     if (vo == NULL) {
    2362           0 :         printf("Expected success but got NULL.\n");
    2363           0 :         ini_config_destroy(ini_config);
    2364           0 :         return -1;
    2365             :     }
    2366             : 
    2367           1 :     INIOUT(value_print("badarray", vo));
    2368             : 
    2369           1 :     INIOUT(printf("Get bad str array without size.\n"));
    2370             : 
    2371           1 :     error = 0;
    2372           1 :     strarray = ini_get_string_config_array(vo, ",", NULL, &error);
    2373           1 :     if (error) {
    2374           0 :         printf("Expect success got error %d.\n", error);
    2375           0 :         ini_config_destroy(ini_config);
    2376           0 :         return error;
    2377             :     }
    2378             : 
    2379             :     /* Can be used with this cycle */
    2380             :     strptr = strarray;
    2381           1 :     while (*strptr != NULL) {
    2382           0 :         INIOUT(printf("[%s]\n",*strptr));
    2383           0 :         strptr++;
    2384             :     }
    2385             : 
    2386           1 :     ini_free_string_config_array(strarray);
    2387             : 
    2388             :     /**********************************************************/
    2389             : 
    2390          15 :     for (i = 0; i< NUM_TESTS; i++) {
    2391          28 :         error = test_one_array(ini_config,
    2392          14 :                                array_test[i].section,
    2393          14 :                                array_test[i].value,
    2394             :                                array_test[i].raw,
    2395             :                                array_test[i].expect,
    2396          14 :                                array_test[i].sep,
    2397          14 :                                array_test[i].message);
    2398          14 :         if (error) {
    2399             :             /* Message is printed inside function */
    2400           0 :             ini_config_destroy(ini_config);
    2401           0 :             return error;
    2402             :         }
    2403             :     }
    2404             : 
    2405             :     /**********************************************************/
    2406             : 
    2407           1 :     INIOUT(printf("Get long array value\n"));
    2408             : 
    2409           1 :     vo = NULL;
    2410           1 :     error = ini_get_config_valueobj("domains/EXAMPLE.COM",
    2411             :                                     "long_array",
    2412             :                                     ini_config,
    2413             :                                     INI_GET_FIRST_VALUE,
    2414             :                                     &vo);
    2415           1 :     if(error) {
    2416           0 :         printf("Expected success but got error! %d\n", error);
    2417           0 :         ini_config_destroy(ini_config);
    2418           0 :         return error;
    2419             :     }
    2420             : 
    2421             :     /* Value should be found */
    2422           1 :     if (vo == NULL) {
    2423           0 :         printf("Expected success but got NULL.\n");
    2424           0 :         ini_config_destroy(ini_config);
    2425           0 :         return -1;
    2426             :     }
    2427             : 
    2428           1 :     INIOUT(value_print("long_array", vo));
    2429             : 
    2430           1 :     error = 0;
    2431           1 :     size = 0; /* Here size is not optional!!! */
    2432           1 :     array = ini_get_long_config_array(vo, &size, &error);
    2433           1 :     if(error) {
    2434           0 :         printf("Expect success got error %d.\n", error);
    2435           0 :         ini_config_destroy(ini_config);
    2436           0 :         return error;
    2437             :     }
    2438             : 
    2439             :     /* Can be used with this cycle */
    2440           1 :     INIOUT(for (i=0;i<size;i++) printf("%ld\n", *(array + i)));
    2441             : 
    2442           1 :     ini_free_long_config_array(array);
    2443             : 
    2444           1 :     INIOUT(printf("Get double array value\n"));
    2445             : 
    2446           1 :     vo = NULL;
    2447           1 :     error = ini_get_config_valueobj("domains/EXAMPLE.COM",
    2448             :                                     "double_array",
    2449             :                                     ini_config,
    2450             :                                     INI_GET_FIRST_VALUE,
    2451             :                                     &vo);
    2452           1 :     if (error) {
    2453           0 :         printf("Expected success but got error! %d\n", error);
    2454           0 :         ini_config_destroy(ini_config);
    2455           0 :         return error;
    2456             :     }
    2457             : 
    2458             :     /* Values should be found */
    2459           1 :     if (vo == NULL) {
    2460           0 :         printf("Expected success but got NULL.\n");
    2461           0 :         ini_config_destroy(ini_config);
    2462           0 :         return -1;
    2463             :     }
    2464             : 
    2465           1 :     INIOUT(value_print("double_array", vo));
    2466             : 
    2467           1 :     error = 0;
    2468           1 :     size = 0; /* Here size is not optional!!! */
    2469           1 :     darray = ini_get_double_config_array(vo, &size, &error);
    2470           1 :     if (error) {
    2471           0 :         printf("Expect success got error %d.\n", error);
    2472           0 :         ini_config_destroy(ini_config);
    2473           0 :         return error;
    2474             :     }
    2475             : 
    2476             :     /* Can be used with this cycle */
    2477           1 :     INIOUT(for (i=0;i<size;i++) printf("%.4f\n", darray[i]));
    2478             : 
    2479           1 :     ini_free_double_config_array(darray);
    2480             : 
    2481           1 :     INIOUT(printf("\n\nSection list - no size\n"));
    2482             : 
    2483             :     /* Do not care about the error or size */
    2484           1 :     prop_array = ini_get_section_list(ini_config, NULL, NULL);
    2485           1 :     if (prop_array == NULL) {
    2486           0 :         printf("Expect success got error.\n");
    2487           0 :         ini_config_destroy(ini_config);
    2488           0 :         return -1;
    2489             :     }
    2490             : 
    2491           1 :     i = 0;
    2492           1 :     INIOUT(while (prop_array[i]) {
    2493             :                printf("Section: [%s]\n", prop_array[i]);
    2494             :                i++;
    2495             :            });
    2496             : 
    2497           1 :     ini_free_section_list(prop_array);
    2498             : 
    2499           1 :     INIOUT(printf("\n\nSection list - with size\n"));
    2500             : 
    2501             :     /* Do not care about the error or size */
    2502           1 :     prop_array = ini_get_section_list(ini_config, &size, NULL);
    2503           1 :     if (prop_array == NULL) {
    2504           0 :         printf("Expect success got error.\n");
    2505           0 :         ini_config_destroy(ini_config);
    2506           0 :         return -1;
    2507             :     }
    2508             : 
    2509           1 :     INIOUT(for (i=0;i<size;i++) printf("Section: [%s]\n", prop_array[i]));
    2510           1 :     ini_free_section_list(prop_array);
    2511             : 
    2512           1 :     INIOUT(printf("\n\nAttributes in the section - with size and error\n"));
    2513             : 
    2514             :     /* Do not care about the error or size */
    2515           1 :     prop_array = ini_get_attribute_list(ini_config,
    2516             :                                     "domains/EXAMPLE.COM",
    2517             :                                     &size,
    2518             :                                     &error);
    2519           1 :     if (prop_array == NULL) {
    2520           0 :         printf("Expect success got error.\n");
    2521           0 :         ini_config_destroy(ini_config);
    2522           0 :         return -1;
    2523             :     }
    2524             : 
    2525           1 :     INIOUT(for (i=0;i<size;i++) printf("Attribute: [%s]\n", prop_array[i]));
    2526           1 :     ini_free_attribute_list(prop_array);
    2527             : 
    2528             : 
    2529             :     /***************************************/
    2530             :     /* Test special types                  */
    2531             :     /***************************************/
    2532           1 :     INIOUT(printf("Test int32_t\n"));
    2533             : 
    2534           1 :     vo = NULL;
    2535           1 :     error = ini_get_config_valueobj("domains/EXAMPLE.COM",
    2536             :                                     "int32_t",
    2537             :                                     ini_config,
    2538             :                                     INI_GET_FIRST_VALUE,
    2539             :                                     &vo);
    2540           1 :     if (error) {
    2541           0 :         printf("Expected success but got error! %d\n", error);
    2542           0 :         ini_config_destroy(ini_config);
    2543           0 :         return error;
    2544             :     }
    2545             : 
    2546             :     /* Value should be found */
    2547           1 :     if (vo == NULL) {
    2548           0 :         printf("Expected success but got NULL.\n");
    2549           0 :         ini_config_destroy(ini_config);
    2550           0 :         return -1;
    2551             :     }
    2552             : 
    2553           1 :     INIOUT(value_print("int32_t", vo));
    2554             : 
    2555           1 :     error = 0;
    2556           1 :     val_int32 = ini_get_int32_config_value(vo, 1, 0, &error);
    2557           1 :     if (error) {
    2558           0 :         printf("Expect success got error %d.\n", error);
    2559           0 :         ini_config_destroy(ini_config);
    2560           0 :         return error;
    2561             :     }
    2562             : 
    2563           1 :     INIOUT(printf("Value: %d\n", val_int32));
    2564             : 
    2565             :     /***************************************/
    2566             : 
    2567           1 :     INIOUT(printf("Test uint32_t\n"));
    2568             : 
    2569           1 :     vo = NULL;
    2570           1 :     error = ini_get_config_valueobj("domains/EXAMPLE.COM",
    2571             :                                     "uint32_t",
    2572             :                                     ini_config,
    2573             :                                     INI_GET_FIRST_VALUE,
    2574             :                                     &vo);
    2575           1 :     if (error) {
    2576           0 :         printf("Expected success but got error! %d\n", error);
    2577           0 :         ini_config_destroy(ini_config);
    2578           0 :         return error;
    2579             :     }
    2580             : 
    2581             :     /* Valu should be found */
    2582           1 :     if (vo == NULL) {
    2583           0 :         printf("Expected success but got NULL.\n");
    2584           0 :         ini_config_destroy(ini_config);
    2585           0 :         return -1;
    2586             :     }
    2587             : 
    2588           1 :     INIOUT(value_print("uint32_t", vo));
    2589             : 
    2590           1 :     error = 0;
    2591           1 :     val_uint32 = ini_get_uint32_config_value(vo, 1, 0, &error);
    2592           1 :     if (error) {
    2593           0 :         printf("Expect success got error %d.\n", error);
    2594           0 :         ini_config_destroy(ini_config);
    2595           0 :         return error;
    2596             :    }
    2597             : 
    2598           1 :     INIOUT(printf("Value: %u\n", val_uint32));
    2599             : 
    2600             :     /***************************************/
    2601             : 
    2602           1 :     INIOUT(printf("Test int64_t\n"));
    2603             : 
    2604           1 :     vo = NULL;
    2605           1 :     error = ini_get_config_valueobj("domains/EXAMPLE.COM",
    2606             :                                     "int64_t",
    2607             :                                     ini_config,
    2608             :                                     INI_GET_FIRST_VALUE,
    2609             :                                     &vo);
    2610           1 :     if (error) {
    2611           0 :         printf("Expected success but got error! %d\n", error);
    2612           0 :         ini_config_destroy(ini_config);
    2613           0 :         return error;
    2614             :     }
    2615             : 
    2616             :     /* Value should be found */
    2617           1 :     if (vo == NULL) {
    2618           0 :         printf("Expected success but got NULL.\n");
    2619           0 :         ini_config_destroy(ini_config);
    2620           0 :         return -1;
    2621             :     }
    2622             : 
    2623           1 :     INIOUT(value_print("int64_t", vo));
    2624             : 
    2625           1 :     error = 0;
    2626           1 :     val_int64 = ini_get_int64_config_value(vo, 1, 0, &error);
    2627           1 :     if (error) {
    2628           0 :         printf("Expect success got error %d.\n", error);
    2629           0 :         ini_config_destroy(ini_config);
    2630           0 :         return error;
    2631             :     }
    2632             : 
    2633           1 :     INIOUT(printf("Value: %lld\n", (long long)val_int64));
    2634             : 
    2635             :     /***************************************/
    2636             : 
    2637           1 :     INIOUT(printf("Test uint32_t\n"));
    2638             : 
    2639           1 :     vo = NULL;
    2640           1 :     error = ini_get_config_valueobj("domains/EXAMPLE.COM",
    2641             :                                     "uint64_t",
    2642             :                                     ini_config,
    2643             :                                     INI_GET_FIRST_VALUE,
    2644             :                                     &vo);
    2645           1 :     if (error) {
    2646           0 :         printf("Expected success but got error! %d\n", error);
    2647           0 :         ini_config_destroy(ini_config);
    2648           0 :         return error;
    2649             :     }
    2650             : 
    2651             :     /* Value should be found */
    2652           1 :     if (vo == NULL) {
    2653           0 :         printf("Expected success but got NULL.\n");
    2654           0 :         ini_config_destroy(ini_config);
    2655           0 :         return -1;
    2656             :     }
    2657             : 
    2658           1 :     INIOUT(value_print("uint64_t", vo));
    2659             : 
    2660           1 :     error = 0;
    2661           1 :     val_uint64 = ini_get_uint64_config_value(vo, 1, 0, &error);
    2662           1 :     if (error) {
    2663           0 :         printf("Expect success got error %d.\n", error);
    2664           0 :         ini_config_destroy(ini_config);
    2665           0 :         return error;
    2666             :     }
    2667             : 
    2668           1 :     INIOUT(printf("Value: %llu\n", (unsigned long long)val_uint64));
    2669             : 
    2670             :     /***************************************/
    2671             : 
    2672           1 :     INIOUT(printf("Get empty array value object\n"));
    2673             : 
    2674           1 :     vo = NULL;
    2675           1 :     error = ini_get_config_valueobj("domains/EXAMPLE.COM",
    2676             :                                     "empty_value",
    2677             :                                     ini_config,
    2678             :                                     INI_GET_FIRST_VALUE,
    2679             :                                     &vo);
    2680           1 :     if(error) {
    2681           0 :         printf("Expected success but got error! %d\n", error);
    2682           0 :         ini_config_destroy(ini_config);
    2683           0 :         return error;
    2684             :     }
    2685             : 
    2686             :     /* Value should be found */
    2687           1 :     if (vo == NULL) {
    2688           0 :         printf("Expected success but got NULL.\n");
    2689           0 :         ini_config_destroy(ini_config);
    2690           0 :         return -1;
    2691             :     }
    2692             : 
    2693           1 :     INIOUT(value_print("empty_value", vo));
    2694             : 
    2695           1 :     error = 0;
    2696           1 :     size = 0; /* Here size is not optional!!! */
    2697           1 :     strarray = ini_get_string_config_array(vo, ",", &size, &error);
    2698           1 :     if(error) {
    2699           0 :         printf("Expect success got error %d.\n", error);
    2700           0 :         ini_config_destroy(ini_config);
    2701           0 :         return error;
    2702             :     }
    2703             : 
    2704           1 :     if (size != 0) {
    2705           0 :         for (i=0; i<size; i++) printf("%s\n", *(strarray + i));
    2706           0 :         printf("Expected size=0, got size=%d\n", size);
    2707           0 :         ini_free_string_config_array(strarray);
    2708           0 :         ini_config_destroy(ini_config);
    2709           0 :         return -1;
    2710             :     }
    2711             : 
    2712           1 :     ini_free_string_config_array(strarray);
    2713             : 
    2714             :     /***************************************/
    2715             : 
    2716           1 :     INIOUT(printf("\nGet last value\n"));
    2717             : 
    2718           1 :     vo = NULL;
    2719           1 :     error = ini_get_config_valueobj("domains/EXAMPLE.COM",
    2720             :                                     "server",
    2721             :                                     ini_config,
    2722             :                                     INI_GET_LAST_VALUE,
    2723             :                                     &vo);
    2724           1 :     if(error) {
    2725           0 :         printf("Expected success but got error! %d\n", error);
    2726           0 :         ini_config_destroy(ini_config);
    2727           0 :         return error;
    2728             :     }
    2729             : 
    2730             :     /* Value should be found */
    2731           1 :     if (vo == NULL) {
    2732           0 :         printf("Expected success but got NULL.\n");
    2733           0 :         ini_config_destroy(ini_config);
    2734           0 :         return -1;
    2735             :     }
    2736             : 
    2737           1 :     INIOUT(value_print("server", vo));
    2738             : 
    2739             :     /***************************************/
    2740             : 
    2741           1 :     INIOUT(printf("\nGet sequence of the multi-value keys\n"));
    2742             : 
    2743           1 :     vo = NULL;
    2744           1 :     error = ini_get_config_valueobj("domains/EXAMPLE.COM",
    2745             :                                     "server",
    2746             :                                     ini_config,
    2747             :                                     INI_GET_FIRST_VALUE,
    2748             :                                     &vo);
    2749           1 :     if(error) {
    2750           0 :         printf("Expected success but got error! %d\n", error);
    2751           0 :         ini_config_destroy(ini_config);
    2752           0 :         return error;
    2753             :     }
    2754             : 
    2755             :     /* Value should be found */
    2756           1 :     if (vo == NULL) {
    2757           0 :         printf("Expected success but got NULL.\n");
    2758           0 :         ini_config_destroy(ini_config);
    2759           0 :         return -1;
    2760             :     }
    2761             : 
    2762           1 :     INIOUT(value_print("server", vo));
    2763             : 
    2764             : 
    2765             :     do {
    2766             : 
    2767           4 :         vo = NULL;
    2768           4 :         error = ini_get_config_valueobj("domains/EXAMPLE.COM",
    2769             :                                         "server",
    2770             :                                         ini_config,
    2771             :                                         INI_GET_NEXT_VALUE,
    2772             :                                     &vo);
    2773           4 :         if(error) {
    2774           0 :             printf("Expected success but got error! %d\n", error);
    2775           0 :             ini_config_destroy(ini_config);
    2776           0 :             return error;
    2777             :         }
    2778             : 
    2779           4 :         if (vo == NULL) break;
    2780             : 
    2781           3 :         INIOUT(value_print("server", vo));
    2782             :     }
    2783             :     while(1);
    2784             : 
    2785             :     /***************************************/
    2786             : 
    2787           1 :     INIOUT(printf("\nGet multi-value keys without prefetching\n"));
    2788             : 
    2789             :     do {
    2790             : 
    2791           5 :         vo = NULL;
    2792           5 :         error = ini_get_config_valueobj("domains/EXAMPLE.COM",
    2793             :                                         "server",
    2794             :                                         ini_config,
    2795             :                                         INI_GET_NEXT_VALUE,
    2796             :                                     &vo);
    2797           5 :         if(error) {
    2798           0 :             printf("Expected success but got error! %d\n", error);
    2799           0 :             ini_config_destroy(ini_config);
    2800           0 :             return error;
    2801             :         }
    2802             : 
    2803           5 :         if (vo == NULL) break;
    2804             : 
    2805           4 :         INIOUT(value_print("server", vo));
    2806             :     }
    2807             :     while(1);
    2808             : 
    2809             :     /***************************************/
    2810             : 
    2811           1 :     INIOUT(printf("\nGet multi-value keys with key interrupt\n"));
    2812             : 
    2813           1 :     i = 0;
    2814             : 
    2815           1 :     vo = NULL;
    2816             :     do {
    2817             : 
    2818           7 :         vo = NULL;
    2819           7 :         error = ini_get_config_valueobj("domains/EXAMPLE.COM",
    2820             :                                         "server",
    2821             :                                         ini_config,
    2822             :                                         INI_GET_NEXT_VALUE,
    2823             :                                         &vo);
    2824           7 :         if(error) {
    2825           0 :             printf("Expected success but got error! %d\n", error);
    2826           0 :             ini_config_destroy(ini_config);
    2827           0 :             return error;
    2828             :         }
    2829             : 
    2830           7 :         if (vo == NULL) break;
    2831             : 
    2832           6 :         INIOUT(value_print("server", vo));
    2833           6 :         i++;
    2834             : 
    2835           6 :         if (i==2) {
    2836           1 :             vo = NULL;
    2837           1 :             error = ini_get_config_valueobj("domains/EXAMPLE.COM",
    2838             :                                             "empty_value",
    2839             :                                             ini_config,
    2840             :                                             INI_GET_NEXT_VALUE,
    2841             :                                             &vo);
    2842           1 :             if(error) {
    2843           0 :                 printf("Expected success but got error! %d\n", error);
    2844           0 :                 ini_config_destroy(ini_config);
    2845           0 :                 return error;
    2846             :             }
    2847             :         }
    2848             :     }
    2849             :     while(1);
    2850             : 
    2851           1 :     if (i != 6) {
    2852           0 :         printf("Expected 6 iterations got %d\n", i);
    2853           0 :         ini_config_destroy(ini_config);
    2854           0 :         return -1;
    2855             :     }
    2856             : 
    2857             :     /***************************************/
    2858             : 
    2859           1 :     INIOUT(printf("\nGet multi-value keys with section interrupt\n"));
    2860             : 
    2861           1 :     i = 0;
    2862             : 
    2863           1 :     vo = NULL;
    2864             :     do {
    2865             : 
    2866           7 :         vo = NULL;
    2867           7 :         error = ini_get_config_valueobj("domains/EXAMPLE.COM",
    2868             :                                         "server",
    2869             :                                         ini_config,
    2870             :                                         INI_GET_NEXT_VALUE,
    2871             :                                     &vo);
    2872           7 :         if(error) {
    2873           0 :             printf("Expected success but got error! %d\n", error);
    2874           0 :             ini_config_destroy(ini_config);
    2875           0 :             return error;
    2876             :         }
    2877             : 
    2878           7 :         if (vo == NULL) break;
    2879             : 
    2880           6 :         INIOUT(value_print("server", vo));
    2881           6 :         i++;
    2882             : 
    2883           6 :         if (i==2) {
    2884           1 :             vo = NULL;
    2885           1 :             error = ini_get_config_valueobj("domains",
    2886             :                                             "badarray",
    2887             :                                             ini_config,
    2888             :                                             INI_GET_NEXT_VALUE,
    2889             :                                         &vo);
    2890           1 :             if(error) {
    2891           0 :                 printf("Expected success but got error! %d\n", error);
    2892           0 :                 ini_config_destroy(ini_config);
    2893           0 :                 return error;
    2894             :             }
    2895             :         }
    2896             :     }
    2897             :     while(1);
    2898             : 
    2899           1 :     if (i != 6) {
    2900           0 :         printf("Expected 6 iterations got %d\n", i);
    2901           0 :         ini_config_destroy(ini_config);
    2902           0 :         return -1;
    2903             :     }
    2904             : 
    2905           1 :     ini_config_destroy(ini_config);
    2906             : 
    2907           1 :     INIOUT(printf("\n<==== GET TEST END =====>\n\n"));
    2908             :     return EOK;
    2909             : }
    2910             : 
    2911           1 : static int space_test(void)
    2912             : {
    2913             : 
    2914             :     int error;
    2915           1 :     struct ini_cfgfile *file_ctx = NULL;
    2916           1 :     struct ini_cfgobj *ini_config = NULL;
    2917           1 :     char **error_list = NULL;
    2918             :     char infile[PATH_MAX];
    2919           1 :     char *srcdir = NULL;
    2920             :     unsigned errnum;
    2921             :     int i;
    2922           1 :     uint32_t flags[] = { INI_PARSE_NOWRAP,
    2923             :                          INI_PARSE_NOWRAP |
    2924             :                          INI_PARSE_NOSPACE,
    2925             :                          INI_PARSE_NOWRAP |
    2926             :                          INI_PARSE_NOTAB,
    2927             :                          INI_PARSE_NOWRAP |
    2928             :                          INI_PARSE_NOSPACE |
    2929             :                          INI_PARSE_NOTAB };
    2930             : 
    2931           1 :     INIOUT(printf("\n\n<==== SPACE TEST START =====>\n"));
    2932             : 
    2933           1 :     srcdir = getenv("srcdir");
    2934           1 :     snprintf(infile, PATH_MAX, "%s/ini/ini.d/space.conf",
    2935             :              (srcdir == NULL) ? "." : srcdir);
    2936             : 
    2937             : 
    2938           5 :     for (i = 0; i < 4; i++ ) {
    2939             : 
    2940           4 :         INIOUT(printf("Reading file %s\n", infile));
    2941           4 :         error = ini_config_file_open(infile,
    2942             :                                         0,
    2943             :                                         &file_ctx);
    2944           4 :         if (error) {
    2945           0 :             printf("Failed to open file for reading. Error %d.\n",  error);
    2946           0 :             return error;
    2947             :         }
    2948             : 
    2949           4 :         INIOUT(printf("Creating configuration object\n"));
    2950           4 :         error = ini_config_create(&ini_config);
    2951           4 :         if (error) {
    2952           0 :             printf("Failed to create object. Error %d.\n", error);
    2953           0 :             ini_config_file_destroy(file_ctx);
    2954           0 :             return error;
    2955             :         }
    2956           4 :         INIOUT(printf("Parsing\n"));
    2957           4 :         error = ini_config_parse(file_ctx,
    2958             :                                  INI_STOP_ON_NONE,
    2959             :                                  0,
    2960             :                                  flags[i],
    2961             :                                  ini_config);
    2962           4 :         if (error) {
    2963           3 :             INIOUT(printf("Failed to parse configuration. Error %d.\n", error));
    2964             : 
    2965           3 :             errnum = ini_config_error_count(ini_config);
    2966           3 :             if (errnum) {
    2967           3 :                 INIOUT(printf("Errors detected while parsing: %s\n",
    2968             :                        ini_config_get_filename(file_ctx)));
    2969           3 :                 ini_config_get_errors(ini_config, &error_list);
    2970           3 :                 INIOUT(ini_config_print_errors(stdout, error_list));
    2971           3 :                 ini_config_free_errors(error_list);
    2972             :             }
    2973           6 :             if (((i == 0) && (errnum != 0)) ||
    2974           6 :                 ((i == 1) && (errnum != 3)) ||
    2975           6 :                 ((i == 2) && (errnum != 3)) ||
    2976           3 :                 ((i == 3) && (errnum != 4))) {
    2977           0 :                 printf("Failed to open file for reading. Error %d.\n",  error);
    2978           0 :                 ini_config_file_destroy(file_ctx);
    2979           0 :                 ini_config_destroy(ini_config);
    2980           0 :                 return -1;
    2981             :             }
    2982             :             /* We do not return here intentionally */
    2983             :         }
    2984             : 
    2985           4 :         INIOUT(col_debug_collection(ini_config->cfg, COL_TRAVERSE_DEFAULT));
    2986           4 :         ini_config_destroy(ini_config);
    2987           4 :         ini_config_file_destroy(file_ctx);
    2988             :     }
    2989             : 
    2990           1 :     INIOUT(printf("\n<==== SPACE TEST END =====>\n\n"));
    2991             :     return EOK;
    2992             : }
    2993             : 
    2994             : 
    2995           1 : static int trim_test(void)
    2996             : {
    2997             :     int error;
    2998           1 :     struct ini_cfgfile *file_ctx = NULL;
    2999           1 :     struct ini_cfgobj *ini_config = NULL;
    3000           1 :     char **error_list = NULL;
    3001             :     char infile[PATH_MAX];
    3002           1 :     char *srcdir = NULL;
    3003             :     const char *value;
    3004           1 :     struct value_obj *vo = NULL;
    3005             : 
    3006           1 :     INIOUT(printf("\n\n<==== TRIM TEST START =====>\n"));
    3007             : 
    3008           1 :     srcdir = getenv("srcdir");
    3009           1 :     snprintf(infile, PATH_MAX, "%s/ini/ini.d/real.conf",
    3010             :              (srcdir == NULL) ? "." : srcdir);
    3011             : 
    3012             : 
    3013           1 :     INIOUT(printf("Reading file %s\n", infile));
    3014           1 :     error = ini_config_file_open(infile,
    3015             :                                  0,
    3016             :                                  &file_ctx);
    3017           1 :     if (error) {
    3018           0 :         printf("Failed to open file for reading. Error %d.\n",  error);
    3019           0 :         return error;
    3020             :     }
    3021             : 
    3022           1 :     INIOUT(printf("Creating configuration object\n"));
    3023           1 :     error = ini_config_create(&ini_config);
    3024           1 :     if (error) {
    3025           0 :         printf("Failed to create object. Error %d.\n", error);
    3026           0 :         ini_config_file_destroy(file_ctx);
    3027           0 :         return error;
    3028             :     }
    3029           1 :     INIOUT(printf("Parsing\n"));
    3030           1 :     error = ini_config_parse(file_ctx,
    3031             :                              INI_STOP_ON_NONE,
    3032             :                              0,
    3033             :                              0,
    3034             :                              ini_config);
    3035           1 :     if (error) {
    3036           0 :         INIOUT(printf("Failed to parse configuration. "
    3037             :                       "Error %d.\n", error));
    3038             : 
    3039           0 :         if (ini_config_error_count(ini_config)) {
    3040           0 :             INIOUT(printf("Errors detected while parsing: %s\n",
    3041             :                    ini_config_get_filename(file_ctx)));
    3042           0 :             ini_config_get_errors(ini_config, &error_list);
    3043           0 :             INIOUT(ini_config_print_errors(stdout, error_list));
    3044           0 :             ini_config_free_errors(error_list);
    3045             :         }
    3046           0 :         ini_config_file_destroy(file_ctx);
    3047           0 :         return error;
    3048             :     }
    3049             : 
    3050           1 :     INIOUT(col_debug_collection(ini_config->cfg, COL_TRAVERSE_DEFAULT));
    3051           1 :     ini_config_file_destroy(file_ctx);
    3052             : 
    3053           1 :     vo = NULL;
    3054           1 :     error = ini_get_config_valueobj("domains/EXAMPLE.COM",
    3055             :                                     "description",
    3056             :                                     ini_config,
    3057             :                                     INI_GET_FIRST_VALUE,
    3058             :                                     &vo);
    3059           1 :     if(error) {
    3060           0 :         printf("Expected success but got error! %d\n",error);
    3061           0 :         ini_config_destroy(ini_config);
    3062           0 :         return error;
    3063             :     }
    3064             : 
    3065             :     /* Value should be found */
    3066           1 :     if (vo == NULL) {
    3067           0 :         printf("Expected success but got NULL.\n");
    3068           0 :         ini_config_destroy(ini_config);
    3069           0 :         return -1;
    3070             :     }
    3071             : 
    3072           1 :     value = ini_get_const_string_config_value(vo, NULL);
    3073             : 
    3074           1 :     if (value == NULL) {
    3075           0 :         printf("No value.\n");
    3076           0 :         ini_config_destroy(ini_config);
    3077           0 :         return -1;
    3078             :     }
    3079             : 
    3080           1 :     if(value[strlen(value) - 1] == ' ') {
    3081           0 :         printf("Trailing space is not trimmed.\n");
    3082           0 :         ini_config_destroy(ini_config);
    3083           0 :         return -1;
    3084             :     }
    3085             : 
    3086           1 :     INIOUT(printf("[%s]\n", value));
    3087             : 
    3088           1 :     ini_config_destroy(ini_config);
    3089             : 
    3090           1 :     INIOUT(printf("\n<==== TRIM TEST END =====>\n\n"));
    3091             :     return EOK;
    3092             : }
    3093             : 
    3094           1 : static int comment_test(void)
    3095             : {
    3096             :     int error;
    3097           1 :     struct ini_cfgfile *file_ctx = NULL;
    3098           1 :     struct ini_cfgobj *ini_config = NULL;
    3099           1 :     char **error_list = NULL;
    3100             :     char infile[PATH_MAX];
    3101           1 :     char *srcdir = NULL;
    3102           1 :     int err_count = 0;
    3103             : 
    3104           1 :     INIOUT(printf("\n\n<==== COMMENT TEST START =====>\n"));
    3105             : 
    3106           1 :     srcdir = getenv("srcdir");
    3107           1 :     snprintf(infile, PATH_MAX, "%s/ini/ini.d/comment.conf",
    3108             :              (srcdir == NULL) ? "." : srcdir);
    3109             : 
    3110             : 
    3111           1 :     INIOUT(printf("Reading file %s\n", infile));
    3112           1 :     error = ini_config_file_open(infile,
    3113             :                                  0,
    3114             :                                  &file_ctx);
    3115           1 :     if (error) {
    3116           0 :         printf("Failed to open file for reading. Error %d.\n",  error);
    3117           0 :         return error;
    3118             :     }
    3119             : 
    3120           1 :     INIOUT(printf("Creating configuration object\n"));
    3121           1 :     error = ini_config_create(&ini_config);
    3122           1 :     if (error) {
    3123           0 :         printf("Failed to create object. Error %d.\n", error);
    3124           0 :         ini_config_file_destroy(file_ctx);
    3125           0 :         return error;
    3126             :     }
    3127           1 :     INIOUT(printf("Parsing\n"));
    3128           1 :     error = ini_config_parse(file_ctx,
    3129             :                              INI_STOP_ON_NONE,
    3130             :                              0,
    3131             :                              0,
    3132             :                              ini_config);
    3133           1 :     if (error) {
    3134           1 :         INIOUT(printf("Failed to parse configuration. "
    3135             :                       "Error %d.\n", error));
    3136           1 :         err_count = ini_config_error_count(ini_config);
    3137           1 :         if (err_count) {
    3138           1 :             INIOUT(printf("Errors detected while parsing: %s\n",
    3139             :                    ini_config_get_filename(file_ctx)));
    3140           1 :             ini_config_get_errors(ini_config, &error_list);
    3141           1 :             INIOUT(ini_config_print_errors(stdout, error_list));
    3142           1 :             ini_config_free_errors(error_list);
    3143             :         }
    3144             :     }
    3145             : 
    3146           1 :     INIOUT(col_debug_collection(ini_config->cfg, COL_TRAVERSE_DEFAULT));
    3147           1 :     ini_config_file_destroy(file_ctx);
    3148           1 :     ini_config_destroy(ini_config);
    3149             : 
    3150           1 :     if(err_count != 4) {
    3151           0 :         printf("Expected 4 errors got: %d\n", err_count);
    3152           0 :         return 1;
    3153             :     }
    3154             : 
    3155           1 :     INIOUT(printf("\n<==== COMMENT TEST END =====>\n\n"));
    3156             :     return EOK;
    3157             : }
    3158             : 
    3159           1 : static void create_boms(void)
    3160             : {
    3161             :     FILE *f;
    3162             : 
    3163           1 :     f = fopen("bom2be","wb");
    3164           1 :     fprintf(f,"%c%c", 0xFE, 0xFF);
    3165           1 :     fclose(f);
    3166           1 :     f = fopen("bom2le","wb");
    3167           1 :     fprintf(f,"%c%c", 0xFF, 0xFE);
    3168           1 :     fclose(f);
    3169           1 :     f = fopen("bom4be","wb");
    3170           1 :     fprintf(f,"%c%c%c%c", 0x00, 0x00, 0xFE, 0xFF);
    3171           1 :     fclose(f);
    3172           1 :     f = fopen("bom4le","wb");
    3173           1 :     fprintf(f,"%c%c%c%c", 0xFF, 0xFE, 0x00, 0x00);
    3174           1 :     fclose(f);
    3175           1 :     f = fopen("bom3","wb");
    3176           1 :     fprintf(f,"%c%c%c", 0xEF, 0xBB, 0xBF);
    3177           1 :     fclose(f);
    3178           1 : }
    3179             : 
    3180             : 
    3181             : /* Main function of the unit test */
    3182           1 : int main(int argc, char *argv[])
    3183             : {
    3184           1 :     int error = 0;
    3185           1 :     test_fn tests[] = { read_save_test,
    3186             :                         read_again_test,
    3187             :                         read_mem_test,
    3188             :                         merge_values_test,
    3189             :                         merge_section_test,
    3190             :                         merge_file_test,
    3191             :                         startup_test,
    3192             :                         reload_test,
    3193             :                         get_test,
    3194             :                         space_test,
    3195             :                         trim_test,
    3196             :                         comment_test,
    3197             :                         NULL };
    3198             :     test_fn t;
    3199           1 :     int i = 0;
    3200             :     char *var;
    3201             : 
    3202           1 :     if ((argc > 1) && (strcmp(argv[1], "-v") == 0)) verbose = 1;
    3203             :     else {
    3204           1 :         var = getenv("COMMON_TEST_VERBOSE");
    3205           1 :         if (var) verbose = 1;
    3206             :     }
    3207             : 
    3208             :     /* Create boms in case we want to create more test files */
    3209           1 :     create_boms();
    3210             : 
    3211           1 :     INIOUT(printf("Start\n"));
    3212             : 
    3213          13 :     while ((t = tests[i++])) {
    3214          12 :         error = t();
    3215          12 :         fflush(NULL);
    3216          12 :         if (error) {
    3217           0 :             INIOUT(printf("Failed with error %d!\n", error));
    3218           0 :             return error;
    3219             :         }
    3220             :     }
    3221             : 
    3222           1 :     INIOUT(printf("Success!\n"));
    3223             : 
    3224             :     return 0;
    3225             : }

Generated by: LCOV version 1.10