0
votes

I'm trying to write C code to parse a config file using libconfig

The config file contains a simple element and a group. A group is composed of multiple settings, each has a unique name. ref

Config file :

host_name = "HOST";
device_settings:
{
   rcu1:
   {
     product_id  = 0x0001;
     vendor_id = 0x0217;
  },
  rcu2:
  {
   product_id  = 0x0001;
   vendor_id = 0x0218;
  }
}

I want to parse all RCUs data and store it in a data structre (the storing part is not a problem for now).

So I'm using the simple steps of :

  1. Store the group in a config_setting_t * called section.
  2. get length of section in a varaible called len
  3. Iterrate len time to read RCUs data.

The problem is when i want to read RCU data i get a seg fault.

Code :

#include <libconfig.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

int main()
{
  config_t cfg;
  config_setting_t *root;
  config_setting_t *section;
  config_setting_t *elem;  
  int d, len;

  config_init(&cfg);
  
  if (config_read_file(&cfg,"./config.cfg") != CONFIG_TRUE) {
    printf("[%s:%d] %s \n", config_error_file(&cfg),
                config_error_line(&cfg), config_error_text(&cfg));
    config_destroy(&cfg);
    return -1;
  }
  
    if ((root = config_root_setting(&cfg)) == NULL) {
    printf ("[%s:%d] %s \n", config_error_file(&cfg),
                   config_error_line(&cfg), config_error_text(&cfg));
    config_destroy(&cfg);
    return -1;
  }
  
    /* Device settings */
  if ((section = config_setting_get_member(root, "device_settings")) != NULL)
  {
    len = config_setting_length(section);
    printf("len = %d \n",len);
  }
  
  int i;
  const char* device_id;
  config_setting_t *device = NULL;
    
    printf("device_settings %s a group \n",config_setting_is_group(section)?"is":"isn't");
    
    for(i=0;i<len;i++) {
        printf("iteration i = %d \n",i);
      //device
      if(device = config_setting_get_elem(section, i) != NULL) {
        
        /*device id*/ 
        if ((d = config_setting_lookup_string(device, "device_id",&device_id) != CONFIG_FALSE)) /*seg fault here*/
        {
            // Do stuff
        }
      }
    }
  return 0;
}

Something strange I noticed is when I compile the code i get this warning :

parse.c: In function ‘main’: parse.c:46:14: warning: assignment to ‘config_setting_t *’ {aka ‘struct config_setting_t *’} from ‘int’ makes pointer from integer without a cast [-Wint-conversion] if(device = config_setting_get_elem(section, i) != NULL) {

GDB output :

Program received signal SIGSEGV, Segmentation fault. 0x00007ffff7da78a0 in config_setting_get_member () from /lib/x86_64-linux-gnu/libconfig.so.9

ref to config_setting_get_elem(..)

I can not find what wrong Im doing. Everything looks correct to me.

Can someone see why the seg fault is happening?

1
if (device = config_setting_get_elem(section, i) != NULL) needs to be if ((device = config_setting_get_elem(section, i)) != NULL). Because != has higher precedence than =. Which BTW you did correctly for section.kaylum
that's because I copied the first part from an example.c. Well seen, idk if you can post it as an answer so I can accept it.wael dr

1 Answers

0
votes
if (device = config_setting_get_elem(section, i) != NULL)

needs to be

if ((device = config_setting_get_elem(section, i)) != NULL)

Because != has higher precedence than =.