常用解析的配置文件格式
interface eth0{
type = 1
alias = "Data0"
vlan = {1,21,31}
route {
subnet = "192.168.1.0"
mask = 24
}
route {
subnet = "192.168.21.0"
mask = 24
}
route {
subnet = "192.168.31.0"
mask = 24
}
}
interface eth1{
type = 2
alias = "Data1"
vlan = {2}
route {
subnet = "192.168.2.0"
mask = 24
}
}
interface eth2{
type = 1
alias = "Data2"
vlan = {3}
}
代码
#include <stdio.h>
#include <confuse.h>
int main(void)
{
cfg_opt_t rtopts[] =
{
CFG_STR("subnet", "-", CFGF_NODEFAULT),
CFG_INT("mask", 0, CFGF_NODEFAULT),
CFG_END()
};
cfg_opt_t ifopts[] =
{
CFG_INT("type", 0, CFGF_NODEFAULT),
CFG_STR("alias", "-", CFGF_NODEFAULT),
CFG_INT_LIST("vlan", "{}", CFGF_NODEFAULT),
CFG_SEC("route", rtopts, CFGF_MULTI),
CFG_END()
};
cfg_opt_t opts[] =
{
CFG_SEC("interface", ifopts, CFGF_TITLE|CFGF_MULTI),
CFG_END()
};
cfg_t *cfg;
cfg = cfg_init(opts, CFGF_NONE);
int r = cfg_parse(cfg, "default.conf");
if(r == CFG_FILE_ERROR || r == CFG_PARSE_ERROR)
return -1;
int i,j;
int interface_num = cfg_size(cfg, "interface");// interface总个数
for(i = 0; i < interface_num; i++)
{
// 从cfg选择第i个interface section
cfg_t *cfg_interface = cfg_getnsec(cfg, "interface", i);
// 获取interface section的title,以及内部包含的type和alias选项值
printf("\ninterface : %s\n", cfg_title(cfg_interface));
printf("type : %d\n", cfg_getint(cfg_interface, "type"));
printf("alias : %s\n", cfg_getstr(cfg_interface, "alias"));
int vlan_num = cfg_size(cfg_interface, "vlan");
for(j = 0; j < vlan_num; j++)
{
printf("vlan : %d\n", cfg_getnint(cfg_interface, "vlan", j));
}
int route_num = cfg_size(cfg_interface, "route");
for(j = 0; j < route_num; j++)
{
cfg_t *cfg_route = cfg_getnsec(cfg_interface, "route", j);
printf("subnet : %s\n", cfg_getstr(cfg_route, "subnet"));
printf("mask : %d\n", cfg_getint(cfg_route, "mask"));
}
}
cfg_free(cfg);
return 0;
}
options允许定义的类型
CFGF_NONE 0 // 允许选项不存在
CFGF_MULTI 1 // 重复多次
CFGF_LIST 2 // 一个列表
CFGF_NOCASE 4 // 大小写敏感
CFGF_TITLE 8 // 有标题的,只针对于section
CFGF_NODEFAULT 16 // 没有默认值
CFGF_NO_TITLE_DUPES 32 // 存在不重复的标题,只针对section
CFG_STR(name, def, flags) // 字符串
CFG_STR_LIST(name, def, flags) // 字符串列表
CFG_INT(name, def, flags) // 整数
CFG_INT_LIST(name, def, flags) // 整数列表
CFG_FLOAT(name, def, flags)
CFG_FLOAT_LIST(name, def, flags)
CFG_BOOL(name, def, flags)
CFG_BOOL_LIST(name, def, flags)
CFG_SEC(name, opts, flags)
CFG_END()
从配置项中提取配置值
cfg_t *cfg_init(cfg_opt_t *opts, cfg_flag_t flags);
int cfg_parse(cfg_t *cfg, const char *filename);
int cfg_parse_fp(cfg_t *cfg, FILE *fp)
int cfg_parse_buf(cfg_t *cfg, const char *buf);
void cfg_free(cfg_t *cfg);
int cfg_getint(cfg_t *cfg, const char *name);
int cfg_getnint(cfg_t *cfg, const char *name, unsigned int index);
double cfg_getfloat(cfg_t *cfg, const char *name);
double cfg_getnfloat(cfg_t *cfg, const char *name, unsigned int index);
char *cfg_getstr(cfg_t *cfg, const char *name);
char *cfg_getnstr(cfg_t *cfg, const char *name, unsigned int index);
cfg_bool_t cfg_getbool(cfg_t *cfg, const char *name);
cfg_bool_t cfg_getnbool(cfg_t *cfg, const char *name, unsigned int index);
cfg_t *cfg_opt_gettsec(cfg_opt_t *opt, const char *title);
cfg_t *cfg_getnsec(cfg_t *cfg, const char *name, unsigned int index);
cfg_t *cfg_gettsec(cfg_t *cfg, const char *name, const char *title);
cfg_t *cfg_getsec(cfg_t *cfg, const char *name);
unsigned int cfg_size(cfg_t *cfg, const char *name);
const char *cfg_title(cfg_t *cfg);
const char *cfg_name(cfg_t *cfg);
const char *cfg_opt_name(cfg_opt_t *opt);
输出到配置文件
// 虽然提供了各种类型值的设置函数,但是最好的方式还是把自己按格式输出到buff中
// 然后调用cfg_parse_buf,生成新的cfg,然后再保存
int cfg_parse_buf(cfg_t *cfg, const char *buf);
void cfg_opt_print(cfg_opt_t *opt, FILE *fp);
void cfg_print(cfg_t *cfg, FILE *fp);
只列出了部分常用的函数,还可以定义数据格式,解析函数等等功能