Skip to content
tat edited this page Oct 3, 2012 · 2 revisions

by AUGER Mickael (from France)

This document gives examples of use of the “u_config...” functions.

Example 1 : load and read an external file

Objective : load and read an external configuration file. For example the path of this is “.” (the same of kloned exec)

Example of configuration file :

#myconfig.conf
section1
{
  key1 value1
  key2 value2
}
section2
{
  key1 value1
  key2 value2
  sbsection
  {
    key value
  }
}
keywithoutsection value

Read this file :

/*
include
*/
#include <u/libu_conf.h>
//...

/*
variables
*/
u_config_t *conf_file,*section,*sbsection;
const char *value;
//...

/*
use
*/
//load myconfig.conf with an external file
if(u_config_load_from_file("myconfig.conf",&conf_file)==0)
{
  //select section "section1"
  if(u_config_get_subkey(conf_file, "section1", &section)==0)
  {
    //read and print keys of this section
    value = u_config_get_subkey_value(section, "key1");
    printf("key1=[%s]\n",value);
    value = u_config_get_subkey_value(section, "key2");
    printf("key2=[%s]\n",value);
  }

  //select section "section2"
  if(u_config_get_subkey(conf_file, "section2", &section)==0)
  {
    //read and print keys of this section
    value = u_config_get_subkey_value(section, "key1");
    printf("key1=[%s]\n",value);
    value = u_config_get_subkey_value(section, "key2");
    printf("key2=[%s]\n",value);
    
    //read and print a key of sub-section
    if(u_config_get_subkey(section, "sbsection", &sbsection)==0)
    {
      value = u_config_get_subkey_value(sbsection, "key");
      printf("key=[%s]\n",value);
    }
  }

  //select, read and print global key "keywithoutsection"
  value = u_config_get_subkey_value(conf_file, "keywithoutsection");
  printf("keywithoutsection=[%s]",value);

  //free memory
  u_config_free(conf_file);
}

Example 2 : load and read an internal file

Objective : load and read an internal configuration like kloned.conf (embedded into the kloned executable)

See also the previous example to read a more complete configuration file.

Example of configuration file copy in “/etc” folder with kloned.conf :

#myconfig.conf
section
{
  key value
}

Read this file :

/*
include
*/
#include <u/libu_conf.h>
//static functions to read an embedded file (these functions have been written by KLone Team)
static int drv_io_open(const char *uri, void **parg);
static int drv_io_close(void *arg);
static char *drv_io_gets(void *arg, char *buf, size_t size);
static u_config_driver_t drv_embfs = {
    drv_io_open, drv_io_close, drv_io_gets, NULL
};
static int drv_io_open(const char *uri, void **parg){
    io_t *io = NULL;
    dbg_err_if(uri == NULL);
    dbg_err_if(strlen(uri) == 0);
    dbg_err_if(parg == NULL);
    warn_err_ifm(emb_open(uri, &io), 
            "unable to open embedded resource: %s", uri);
    *parg = io;
    return 0;
err: 
    if(io)
        io_free(io);
    return ~0;
}
static int drv_io_close(void *arg){
    io_t *io = (io_t*) arg;
    dbg_err_if(io == NULL);
    io_free(io);
    return 0;
err: 
    return ~0;
}
static char *drv_io_gets(void *arg, char *buf, size_t size){
    io_t *io = (io_t*)arg;
    dbg_err_if (arg == NULL);
    dbg_err_if (buf == NULL);
    nop_err_if(io_gets(io, buf, size) <= 0);
    return buf;
err: 
    return NULL;
}
//...

/*
variables
*/
u_config_t *conf_file,*section;
const char *value;
//...

/*
use
*/
//load myconfig.conf with an internal file
if(u_config_load_from_drv("/etc/myconfig.conf",&drv_embfs,0,&conf_file)==0)
{
  if(u_config_get_subkey(conf_file, "section", &section)==0)
  {
    value = u_config_get_subkey_value(section, "key");
    printf("key1=[%s]\n",value);
  }

  //free memory
  u_config_free(conf_file);
}

Example 3 : load, change and save an external file

Objective : load, change and save an external configuration file. For example the path of this is “.” (the same of kloned exec)

Example a configuration file :

#myconfig.conf
gkey value
section
{
  key value
}

Load a “myconfig.conf” and save in “newconfig.conf” :

/*
include
*/
#include <u/libu_conf.h>
//...

/*
variables
*/
u_config_t *conf_file,*section,*child;
FILE *fp;
//...

/*
use
*/
//load myconfig.conf with an external file
if(u_config_load_from_file("myconfig.conf",&conf_file)==0)
{
  //add a global key
  u_config_add_child(conf_file,"newkey", &child);
  u_config_set_value(child, "new value");
  
  //change a global key
  child = u_config_get_child(conf_file,"gkey");
  if(child!=NULL)
  {
    if(u_config_set_value(child,"new value")==0)
    {
      printf("key changed\n");
    }
  }
  
  //save into a new file
  fp = fopen("newconfig.conf","w+");
  if(fp)
  {
    u_config_print_to_fp(conf_file,fp,-1);//no return
    printf("file saved\n");
    
    fclose(fp);
  }
  
  u_config_free(conf_file);
}

Example 4 : load and print all the configuration

Objective : load and print all the configuration by using u_config_walk() For example the path of this is “.” (the same of kloned exec)

Example a configuration file :

#myconfig.conf
gkey1 value
section1
{
  s1key1 value
  s1key2 value
}
section2
{
  s2key1 value
  s2key2 value
  subsection21
  {
    sb21key1 value
    sb21key2 value
  }
}

Load and print the content of “myconfig.conf” :

/*
include
*/
#include <u/libu_conf.h>
//...

/*
function to apply at each key by u_config_walk().
*/
void print_config_t(u_config_t *c)
{
  const char *key,*val;
  key = u_config_get_key(c);
  val = u_config_get_value(c);
  if(key!=NULL)
    printf("%s",key);
  if(val!=NULL)
    printf(" : %s",val);
  printf("\n");
}

/*
variables
*/
u_config_t *conf_file;
FILE *fp;
//...

/*
use
*/
//load myconfig.conf with an external file
if(u_config_load_from_file("myconfig.conf",&conf_file)==0)
{
  u_config_walk(c,U_CONFIG_WALK_PREORDER,print_config_t);
  // -> print the name of the section before his children
  
  u_config_walk(c,U_CONFIG_WALK_POSTORDER,print_config_t);
  // -> print the name of the section after his children
  
  u_config_free(conf_file);
}

Example 5 : load and print the configuration with restriction

Objective : load and print only sections whose names are a number For example the path of this is “.” (the same of kloned exec)

Example a configuration file :

#myconfig.conf
gkey1 value
1
{
  key1 value
  key2 value
}
4
{
  key1 value
  key2 value
  subsection21
  {
    key1 value
    key2 value
  }
}
9
{
  key1 value
  key2 value
  key3 value
}

Load “myconfig.conf” and find sections whose names are a number without see the subsection :

/*
include
*/
#include <u/libu_conf.h>
//...

/*
variables
*/
u_config_t *conf_file,*cc;
FILE *fp;
int i;
const char *key;
//...

/*
use
*/
//load myconfig.conf with an external file
if(u_config_load_from_file("myconfig.conf",&conf_file)==0)
{
  for(i = 0; (cc = u_config_get_child_n(c, NULL, i)) != NULL; i++)
  { 
    key = u_config_get_key(c);
    if(key!=NULL && u_atoi(key)>0)
      printf("%s\n",key);
  }
  
  u_config_free(conf_file);
}

Remarks and traps to avoid

Objective : use this library without surprise.

Use a return of get function to modify the value of the same key

Example : How to change the value of myname by a substring of this :

/**
#myconfig.conf
myname It's me Mario
*/

Don’t write this !!! :(

//modify a value by using an alternative of this
const char *value;

value = u_config_get_subkey_value(my_configuration,"myname");
//->value = It's me Mario
u_config_set_key(my_configuration,"myname",value+8);
//->change by Mario
//-->don't work because u_config_set_key() free the old value before read the new value

But write :)

//modify a value by using an alternative of this
const char *value;
char new_value[64];

value = u_config_get_subkey_value(my_configuration,"myname");
//->value = It's me Mario
snprintf(new_value,sizeof new_value,"%s",value+8);
//->new_valuer = Mario
u_config_set_key(my_configuration,"myname",new_value);