[ccan] cinitparser: section numbering issue

Rusty Russell rusty at rustcorp.com.au
Wed Jan 27 15:44:27 AEDT 2016


Richard Weinberger <richard.weinberger at gmail.com> writes:
> Hi!
>
> ciniparser seems to be confused with its own API.

Hmm, ciniparser should have been removed ages ago.  Tim thought it was
abandoned when he added it to CCAN, but it is an active external project
which you can find here:

        https://github.com/ndevilla/iniparser

Unless there are strong objections, I will remove it from the repo.

Thanks,
Rusty.

> From the docs:
> /**
>  * @brief    Get name for section n in a dictionary.
>  * @param    d   Dictionary to examine
>  * @param    n   Section number (from 0 to nsec-1).
>  * @return   Pointer to char string, NULL on error
>  *
>  * This function locates the n-th section in a dictionary and returns
>  * its name as a pointer to a string statically allocated inside the
>  * dictionary. Do not free or modify the returned string!
>  */
> char *ciniparser_getsecname(dictionary *d, int n);
>
> So, the section numbers are 0 to ciniparser_getnsec() - 1.
>
> But in the test directory run.c does:
>         ok(stmp2 = ciniparser_getsecname(ini, 1),
>                 "ciniparser_getsecname(): first dict entry is %s", stmp2);
>
> First entry should be 0, not 1.
>
> ciniparser_dump_ini() follows the docs and fails.
> ---cut---
> rw at sandpuppy:~/ccan/ciniparser> cat test.ini
> [one]
> foo = bar
> [two]
> foo = bar
> [three]
> foo = bar
> rw at sandpuppy:~/ccan/ciniparser> cat main.c
> #include <stdio.h>
> #include <stdbool.h>
> #include "ciniparser.h"
>
> #define CONFIG_FILE "test.ini"
>
> int main(int argc, char *argv[])
> {
>         dictionary *d;
>         d = ciniparser_load(CONFIG_FILE);
>         if (d == NULL)
>                 return 1;
>
>         ciniparser_dump_ini(d, stdout);
>
>         ciniparser_freedict(d);
>
>         return 0;
> }
> rw at sandpuppy:~/ccan/ciniparser> ./main
>
> [one]
> foo                            = bar
>
> [one]
> foo                            = bar
>
> [two]
> foo                            = bar
>
> ---cut---
>
> 3rd section is missing but 1st is here twice.
>
> I'd suggest the following fix:
> diff --git a/ccan/ciniparser/ciniparser.c b/ccan/ciniparser/ciniparser.c
> index 2b60e40..a6082da 100644
> --- a/ccan/ciniparser/ciniparser.c
> +++ b/ccan/ciniparser/ciniparser.c
> @@ -270,7 +270,7 @@ void ciniparser_dump_ini(dictionary *d, FILE *f)
>                 return;
>         }
>
> -       for (i = 0; i < nsec; i++) {
> +       for (i = 1; i <= nsec; i++) {
>                 secname = ciniparser_getsecname(d, i);
>                 seclen  = (int)strlen(secname);
>                 fprintf(f, "\n[%s]\n", secname);
> diff --git a/ccan/ciniparser/ciniparser.h b/ccan/ciniparser/ciniparser.h
> index f61b357..e676c23 100644
> --- a/ccan/ciniparser/ciniparser.h
> +++ b/ccan/ciniparser/ciniparser.h
> @@ -65,7 +65,7 @@ int ciniparser_getnsec(dictionary *d);
>  /**
>   * @brief    Get name for section n in a dictionary.
>   * @param    d   Dictionary to examine
> - * @param    n   Section number (from 0 to nsec-1).
> + * @param    n   Section number (from 1 to nsec).
>   * @return   Pointer to char string, NULL on error
>   *
>   * This function locates the n-th section in a dictionary and returns
>
> ---
>
> Side note, ciniparser_getsecname() returns the first section
> if asked for both 0 and 1. 0 should be undefined behavior IMHO.
>
> -- 
> Thanks,
> //richard
> _______________________________________________
> ccan mailing list
> ccan at lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/ccan


More information about the ccan mailing list