使用C语言和libcyaml库解析yaml配置文件

C语言的yaml库有 libyaml 和 libcyaml (The Official YAML Web Site)

个人觉得libcyaml比较好用,libcyaml项目地址:GitHub - tlsa/libcyaml: C library for reading and writing YAML.

libcyaml编译没有难度,按照说明编译即可,需要注意的是提前安装libyaml-dev:

sudo apt install libyaml-dev
下面直接上例子:
~/test
    -include
        -cyaml
            cyaml.h
    -lib
        libcyaml.a
    1.yaml
    main.c
    Makefile
1.yaml
# slave 1
Name: "drive_1"
Pos: 1
Vendor_ID: 0x00000A1E
Product_ID: 0x00000305
Sdo:
  - Description: "To disable [AL. 090.1], set [Pr. PC41.0 [AL. 090.1 Homing incomplete] detection selection] to '1' (disabled)."
    Index: 0x2129
    SubIndex: 0x00
    BitLen: 32
    Value: 1
  - Description: "Pr. PD01.2_Input signal automatic ON selection"
    Index: 0x2181
    SubIndex: 0x00
    BitLen: 32
    Value: 0x00000C00
  - Description: "Reset alarm. Writing '1EA5h' resets an alarm."
    Index: 0x2A46
    SubIndex: 0x00
    BitLen: 16
    Value: 0x1EA5
main.c
/*
 * SPDX-License-Identifier: ISC
 *
 * Copyright (C) 2018 Michael Drake <tlsa@netsurf-browser.org>
 */
 
#include <stdlib.h>
#include <stdio.h>
 
#include <cyaml/cyaml.h>
 
/******************************************************************************
 * C data structure for storing a project plan.
 *
 * This is what we want to load the YAML into.
 ******************************************************************************/
 
/* Structure for storing a sdo item */
struct sdo {
    char *description;
    int *index;
    int *subindex;
    int *bitlen;
    int *value;
};
 
/* Structure for storing a slave */
struct slave {
    char *name;
    int *pos;
    int *vendor_id;
    int *product_id;
    struct sdo *sdos;
    unsigned sdos_count;
};
 
/******************************************************************************
 * CYAML schema to tell libcyaml about both expected YAML and data structure.
 *
 * (Our CYAML schema is just a bunch of static const data.)
 ******************************************************************************/
 
/* The sdo mapping's field definitions schema is an array.
 *
 * All the field entries will refer to their parent mapping's structure,
 * in this case, `struct task`.
 */
static const cyaml_schema_field_t sdo_fields_schema[] = {
    /* The first field in the mapping is description.
     *
     * YAML key: "Description".
     * C structure member for this key: "description".
     *
     * Its CYAML type is string pointer, and we have no minimum or maximum
     * string length constraints.
     */
    CYAML_FIELD_STRING_PTR(
            "Description", CYAML_FLAG_POINTER,
            struct sdo, description, 0, CYAML_UNLIMITED),
 
    CYAML_FIELD_UINT("Index", CYAML_FLAG_DEFAULT, struct sdo, index),
    CYAML_FIELD_UINT("SubIndex", CYAML_FLAG_DEFAULT, struct sdo, subindex),
    CYAML_FIELD_UINT("BitLen", CYAML_FLAG_DEFAULT, struct sdo, bitlen),
    CYAML_FIELD_UINT("Value", CYAML_FLAG_DEFAULT, struct sdo, value),
    
    
 
    /* The field array must be terminated by an entry with a NULL key.
     * Here we use the CYAML_FIELD_END macro for that. */
    CYAML_FIELD_END
};
 
/* The value for a sdo is a mapping.
 *
 * Its fields are defined in sdo_fields_schema.
 */
static const cyaml_schema_value_t sdo_schema = {
    CYAML_VALUE_MAPPING(CYAML_FLAG_DEFAULT,
            struct sdo, sdo_fields_schema),
};
 
 
/* The plan mapping's field definitions schema is an array.
 *
 * All the field entries will refer to their parent mapping's structure,
 * in this case, `struct plan`.
 */
static const cyaml_schema_field_t slave_fields_schema[] = {
 
    CYAML_FIELD_STRING_PTR(
            "Name", CYAML_FLAG_POINTER,
            struct slave, name, 0, CYAML_UNLIMITED),
 
    CYAML_FIELD_UINT(
            "Pos", CYAML_FLAG_DEFAULT, 
            struct slave, pos),
 
    CYAML_FIELD_UINT(
            "Vendor_ID", CYAML_FLAG_DEFAULT, 
            struct slave, vendor_id),
 
    CYAML_FIELD_UINT(
            "Product_ID", CYAML_FLAG_DEFAULT, 
            struct slave, product_id),
 
 
    CYAML_FIELD_SEQUENCE(
            "Sdo", CYAML_FLAG_POINTER,
            struct slave, sdos,
            &sdo_schema, 0, CYAML_UNLIMITED),
 
    /* The field array must be terminated by an entry with a NULL key.
     * Here we use the CYAML_FIELD_END macro for that. */
    CYAML_FIELD_END
};
 
 
/* Top-level schema.  The top level value for the plan is a mapping.
 *
 * Its fields are defined in plan_fields_schema.
 */
static const cyaml_schema_value_t slave_schema = {
    CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
            struct slave, slave_fields_schema),
};
 
 
 
/******************************************************************************
 * Actual code to load and save YAML doc using libcyaml.
 ******************************************************************************/
 
/* Our CYAML config.
 *
 * If you want to change it between calls, don't make it const.
 *
 * Here we have a very basic config.
 */
static const cyaml_config_t config = {
    .log_fn = cyaml_log,            /* Use the default logging function. */
    .mem_fn = cyaml_mem,            /* Use the default memory allocator. */
    .log_level = CYAML_LOG_WARNING, /* Logging errors and warnings only. */
};
 
/* Main entry point from OS. */
int main(int argc, char *argv[])
{
    cyaml_err_t err;
    struct slave *slave;
    enum {
        ARG_PROG_NAME,
        ARG_PATH_IN,
        ARG_PATH_OUT,
        ARG__COUNT,
    };
 
    // /* Handle args */
    // if (argc != ARG__COUNT) {
    //     fprintf(stderr, "Usage:\n");
    //     fprintf(stderr, "  %s <INPUT> <OUTPUT>\n", argv[ARG_PROG_NAME]);
    //     return EXIT_FAILURE;
    // }
 
    /* Load input file. */
    err = cyaml_load_file(argv[ARG_PATH_IN], &config,
            &slave_schema, (void **) &slave, NULL);
    if (err != CYAML_OK) {
        fprintf(stderr, "ERROR: %s\n", cyaml_strerror(err));
        return EXIT_FAILURE;
    }
 
    /* Use the data. */
    printf("Project: %s\n", slave->name);
    for (unsigned i = 0; i < slave->sdos_count; i++) {
        printf("%u. Description: %s\n", i + 1, slave->sdos[i].description);
        printf("Index: 0x%x\n", slave->sdos[i].index);
        printf("SubIndex: %d\n", slave->sdos[i].subindex);
        printf("BitLen: %d\n", slave->sdos[i].bitlen);
        printf("Value: 0x%x\n", slave->sdos[i].value);
    }
 
    // /* Modify the data */
    // plan->tasks[0].estimate.days += 3;
    // plan->tasks[0].estimate.weeks += 1;
 
    // /* Save data to new YAML file. */
    // err = cyaml_save_file(argv[ARG_PATH_OUT], &config,
    //         &plan_schema, plan, 0);
    // if (err != CYAML_OK) {
    //     fprintf(stderr, "ERROR: %s\n", cyaml_strerror(err));
    //     cyaml_free(&config, &plan_schema, plan, 0);
    //     return EXIT_FAILURE;
    // }
 
    /* Free the data */
    cyaml_free(&config, &slave_schema, slave, 0);
 
    return EXIT_SUCCESS;
}
Makefile
INCLUDE = -I include
CFLAGS += $(INCLUDE)
CFLAGS += -std=c11 -Wall -Wextra -pedantic \
        -Wconversion -Wwrite-strings -Wcast-align -Wpointer-arith \
        -Winit-self -Wshadow -Wstrict-prototypes -Wmissing-prototypes \
        -Wredundant-decls -Wundef -Wvla -Wdeclaration-after-statement
LDFLAGS += -lyaml -Llib -lcyaml
 
all: main
 
main: main.c
    $(CC) $(CPPFLAGS) $(CFLAGS) -o $@ $^ $(LDFLAGS)
————————————————
版权声明:本文为CSDN博主「liu_jiankang」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_41573966/article/details/125060965

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值