Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add function to create a new titled section #69

Merged
merged 4 commits into from
May 27, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions examples/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ ftpconf
cli
nested
deprecated
addsec
2 changes: 1 addition & 1 deletion examples/Makefile.am
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
EXTRA_DIST = simple.conf reread.conf ftp.conf test.conf nested.conf deprecated.conf
noinst_PROGRAMS = simple reread ftpconf cfgtest cli nested deprecated
noinst_PROGRAMS = simple reread ftpconf cfgtest cli nested deprecated addsec
AM_CPPFLAGS = -I$(top_srcdir)/src
AM_LDFLAGS = -L../src/
LIBS = $(LTLIBINTL)
Expand Down
61 changes: 61 additions & 0 deletions examples/addsec.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
#include <err.h>
#include <string.h>
#include <unistd.h>
#include <locale.h>
#include "confuse.h"

cfg_t *cfg = 0;
const char *config_filename = "./reread.conf";

void read_config(void)
{
static cfg_opt_t arg_opts[] = {
CFG_STR("value", "default", CFGF_NONE),
CFG_END()
};
cfg_opt_t opts[] = {
CFG_INT("delay", 3, CFGF_NONE),
CFG_STR("message", "This is a message", CFGF_NONE),
CFG_SEC("argument", arg_opts, CFGF_MULTI | CFGF_TITLE),
CFG_END()
};

cfg = cfg_init(opts, CFGF_NONE);
if (cfg_parse(cfg, config_filename) != CFG_SUCCESS)
errx(1, "Failed parsing configuration!\n");
}

void print_message()
{
int i;

printf("Message: %s", cfg_getstr(cfg, "message"));
for (i = 0; i < cfg_size(cfg, "argument"); i++) {
cfg_t *arg = cfg_getnsec(cfg, "argument", i);

printf(", %s", cfg_getstr(arg, "value"));
}
printf("\n");
}

int main(void)
{
cfg_t* sec;

/* Localize messages & types according to environment, since v2.9 */
setlocale(LC_MESSAGES, "");
setlocale(LC_CTYPE, "");

read_config();
print_message();

/* Add a new section */
sec = cfg_addtsec(cfg, "argument", "two");
cfg_setstr(sec, "value", "foo");
print_message();

cfg_free(cfg);
cfg = 0;

return 0;
}
24 changes: 24 additions & 0 deletions src/confuse.c
Original file line number Diff line number Diff line change
Expand Up @@ -1823,6 +1823,30 @@ DLLIMPORT int cfg_addlist(cfg_t *cfg, const char *name, unsigned int nvalues, ..
return CFG_SUCCESS;
}

DLLIMPORT cfg_t *cfg_addtsec(cfg_t *cfg, const char *name, const char *title)
{
cfg_opt_t *opt;
cfg_value_t *val;

if (cfg_gettsec(cfg, name, title))
return NULL;

opt = cfg_getopt(cfg, name);
if (!opt) {
cfg_error(cfg, _("no such option '%s'"), name);
return NULL;
}
val = cfg_setopt(cfg, opt, title);
if (!val)
return NULL;

val->section->path = cfg->path;
val->section->line = 1;
val->section->errfunc = cfg->errfunc;

return val->section;
}

DLLIMPORT int cfg_opt_rmnsec(cfg_opt_t *opt, unsigned int index)
{
unsigned int n;
Expand Down
12 changes: 12 additions & 0 deletions src/confuse.h
Original file line number Diff line number Diff line change
Expand Up @@ -1119,6 +1119,18 @@ DLLIMPORT int cfg_opt_setmulti(cfg_t *cfg, cfg_opt_t *opt, unsigned int nvalues,
*/
DLLIMPORT int cfg_setmulti(cfg_t *cfg, const char *name, unsigned int nvalues, char **values);

/** Create a new titled config section.
*
* @param cfg The configuration file context.
* @param name The name of the option.
* @param title The title of this section.
*
* @return A pointer to the created section or if the section
* already exists a pointer to that section is returned.
* If the section could not be created or found, 0 is returned.
*/
DLLIMPORT cfg_t *cfg_addtsec(cfg_t *cfg, const char *name, const char *title);

/** Removes and frees a config section, given a cfg_opt_t pointer.
* @param opt The option structure (eg, as returned from cfg_getopt())
* @param index Index of the section to remove. Zero based.
Expand Down
1 change: 1 addition & 0 deletions tests/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ TESTS += list_plus_syntax
TESTS += section_title_dupes
TESTS += single_title_sections
TESTS += section_remove
TESTS += section_add
TESTS += quote_before_print
TESTS += include
TESTS += searchpath
Expand Down
45 changes: 45 additions & 0 deletions tests/section_add.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#include "check_confuse.h"
#include <string.h>

int main(void)
{
static cfg_opt_t section_opts[] = {
CFG_STR("prop", 0, CFGF_NONE),
CFG_END()
};

cfg_opt_t opts[] = {
CFG_SEC("section", section_opts, CFGF_TITLE | CFGF_MULTI),
CFG_END()
};

const char *config_data =
"section title_one { prop = 'value_one' }\n"
"section title_two { prop = 'value_two' }\n";

int rc;
cfg_t *cfg = cfg_init(opts, CFGF_NONE);

fail_unless(cfg);

rc = cfg_parse_buf(cfg, config_data);
fail_unless(rc == CFG_SUCCESS);

fail_unless(cfg_addtsec(cfg, "section", "title_three"));
fail_unless(cfg_size(cfg, "section") == 3);
fail_unless(cfg_title(cfg_gettsec(cfg, "section", "title_three")));

/* attempt to add a pre-existing section should fail */
fail_unless(!cfg_addtsec(cfg, "section", "title_three"));

cfg_free(cfg);

return 0;
}

/**
* Local Variables:
* indent-tabs-mode: t
* c-file-style: "linux"
* End:
*/