Search code examples
clibyaml

How to modify an existing YAML node in C?


I am not C programmer but have recently taking interest in it. I am trying to modify a node of a YAML file using the C libyaml library. When I try to modify the node from an event scalar data the compiler doesn't complain but I get segmentation fault errors.

while (!done)
{
    /* Get the next token. */

    if (!yaml_parser_parse(&parser, &event))
        goto parser_error;

    //yaml_parser_scan(&parser, &token);

    /* Check if this is the stream end. */

    if(beginServerNodes && event.type == 8) {
      beginServerNodes = 0;
    }

    if (event.type == YAML_SCALAR_EVENT) {
      if(beginServerNodes == 1) {
        //I WANT TO MODIFY THIS VALUE
        printf("%s\n", event.data.scalar.value);
      }
      if(strcmp("servers",event.data.scalar.value) == 0) {
        beginServerNodes = 1;
      }
    }

    if (event.type == YAML_STREAM_END_EVENT) {
        done = 1;
    }
    /* Emit the token. */

    if (!yaml_emitter_emit(&emitter, &event))
        goto emitter_error;
}

So while in that loop when I attempt to modify the following value

event.data.scalar.value

It must be of type yaml_char_t

  yaml_char_t *newHost = "10.132.16.48:6379:1 redis-001";
  event.data.scalar.value = newHost;
  event.data.scalar.length = sizeof(newHost);

The compiler doesn't complain and the code run by dies with segementation fault. If have seen the examples in the libyaml test directories but nothing is intuitive as far as simply editing a node, at least not to a C newb like myself.


Solution

  • Libyaml expect that the values of each scalar can be removed via free(). So you need to initialize this value with malloc()ed memory:

    const char* newHost = "10.132.16.48:6379:1 redis-001";
    event.data.scalar.value = (yaml_char_t*)strdup(newHost);
    event.data.scalar.length = strlen(newHost);