@TOC
TOML是前GitHub CEO端壳, Tom Preston-Werner,于2013年創(chuàng)建的語言枪蘑,其目標是成為一個小規(guī)模的易于使用的語義化配置文件格式损谦。TOML被設(shè)計為可以無二義性的轉(zhuǎn)換為一個哈希表(Hash table)岖免。
toml書寫語法
解析toml文件
這里使用tomlc99庫
#下載庫
git clone https://github.com/cktan/tomlc99.git
cd tomlc99
#創(chuàng)建test.c文件
vi test.c
將以下代碼復(fù)制到test.c
文件中
#ifdef NDEBUG
#undef NDEBUG
#endif
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <stdint.h>
#include <assert.h>
#include "toml.h"
typedef struct node_t node_t;
struct node_t {
const char* key;
toml_table_t* tab;
};
node_t stack[20];
int stacktop = 0;
/*設(shè)置輸出顏色*/
#define red_color "\E[1;31m"
#define color_suffix "\E[0m"
static void print_array_of_tables(toml_array_t* arr, const char* key);
static void print_array(toml_array_t* arr);
/**
* @brief 打印表名
*
* @param arrname 數(shù)組名或者是表名
*/
static void print_table_title(const char* arrname)
{
int i;
printf("%s", arrname ? "[[" : "[");
/*打印上級*/
printf(red_color"開始打印上級:"color_suffix);
for (i = 1; i < stacktop; i++) {
printf("%s", stack[i].key);
if (i + 1 < stacktop)
printf(".");
}
/*打印尾部*/
printf(red_color"打印尾部:"color_suffix);
if (arrname)
printf(".%s]]\n", arrname);
else
printf("]\n");
}
/**
* @brief 打印表
*
* @param curtab
*/
static void print_table(toml_table_t* curtab)
{
int i;
const char* key;
const char* raw;
toml_array_t* arr;
toml_table_t* tab;
/*輪詢KEY*/
for (i = 0; 0 != (key = toml_key_in(curtab, i)); i++) {
/*如果是KV則打印*/
if (0 != (raw = toml_raw_in(curtab, key))) {
printf(red_color"如果是KV則打印\n"color_suffix);
printf("%s = %s\n", key, raw);
/*如果是表中數(shù)組或者KV型數(shù)組*/
} else if (0 != (arr = toml_array_in(curtab, key))) {
/*[[key]]數(shù)組或者KV型數(shù)組*/
if (toml_array_kind(arr) == 't') {
printf(red_color"如果是[[key]]數(shù)組\n"color_suffix);
print_array_of_tables(arr, key);
}
else {
/*KV型數(shù)組*/
printf(red_color"如果是KV型數(shù)組\n"color_suffix);
printf("%s = [\n", key);/*xx = [ss,sss]*/
print_array(arr);
printf(" ]\n");
}
} else if (0 != (tab = toml_table_in(curtab, key))) {
/*如果是[tab.tab]嵌套則分解*/
printf(red_color"如果是[tab.tab]嵌套則分解打印\n"color_suffix);
stack[stacktop].key = key;
stack[stacktop].tab = tab;
stacktop++;
print_table_title(0);
print_table(tab);
stacktop--;
} else {
abort();
}
}
}
/**
* @brief 打印標表中數(shù)組
*
* @param arr 數(shù)組指針
* @param key 數(shù)組名
*/
static void print_array_of_tables(toml_array_t* arr, const char* key)
{
int i;
toml_table_t* tab;
printf("\n");
/*輪詢表中數(shù)組*/
printf(red_color"輪詢表中數(shù)組\n"color_suffix);
for (i = 0; 0 != (tab = toml_table_at(arr, i)); i++) {
print_table_title(key);//[[key]]
print_table(tab);
printf("\n");
}
}
/**
* @brief 打印數(shù)組
*
* @param curarr
*/
static void print_array(toml_array_t* curarr)
{
toml_array_t* arr;
const char* raw;
toml_table_t* tab;
int i;
switch (toml_array_kind(curarr)) {
/*
[
0: yyy,
1: xxx,
2: xxx,
]
*/
case 'v':
for (i = 0; 0 != (raw = toml_raw_at(curarr, i)); i++) {
printf(" %d: %s,\n", i, raw);
}
break;
/*
[
0:
0:
0:xxx
1:xxx
1:
0:xxx
1:xxx
1:
0:
0:xxx
1:xxx
1:
0:xxx
1:xxx
]
*/
case 'a':
for (i = 0; 0 != (arr = toml_array_at(curarr, i)); i++) {
printf(" %d: \n", i);
print_array(arr);
}
break;
case 't':
for (i = 0; 0 != (tab = toml_table_at(curarr, i)); i++) {
print_table(tab);
}
printf("\n");
break;
case '\0':
break;
default:
abort();
}
}
/**
* @brief 解析打印toml文件
*
* @param fp
*/
static void cat(FILE* fp)
{
char errbuf[200];
toml_table_t* tab = toml_parse_file(fp, errbuf, sizeof(errbuf));
if (!tab) {
fprintf(stderr, "ERROR: %s\n", errbuf);
return;
}
stack[stacktop].tab = tab;
stack[stacktop].key = "";
stacktop++;
print_table(tab);
stacktop--;
toml_free(tab);
}
int main(int argc, const char* argv[])
{
int i;
if (argc == 1) {
cat(stdin);
} else {
for (i = 1; i < argc; i++) {
FILE* fp = fopen(argv[i], "r");
if (!fp) {
fprintf(stderr, "ERROR: cannot open %s: %s\n",
argv[i], strerror(errno));
exit(1);
}
cat(fp);
fclose(fp);
}
}
return 0;
}
準備測試的toml文件,寫入到同級目錄的sample.toml
文件中
[Service]
Port = 50000
Timeout = 5000
ConnectRetries = 10
Labels = [ 'MQTT_Protocol' ,'MODBUS_Protocol' ]
StartupMsg = 'mqtt modbus device service started'
CheckInterval = '10s'
[Clients]
[Clients.Data]
Host = 'localhost'
Port = 48080
[Clients.Metadata]
Host = 'localhost'
Port = 48081
[Device]
DataTransform = false
Discovery = false
MaxCmdOps = 128
MaxCmdResultLen = 256
[Logging]
LogLevel = 'DEBUG'
[[DeviceList]]
Name = 'modbus-01_hangzhou-temperature_device-1'
Profile = 'modbus_temperature_device_profile_common'
Description = 'An temperature device'
[DeviceList.Protocols]
[DeviceList.Protocols.modbus-rtu]
Address = '/tmp/slave'
BaudRate = 9600
DataBits = 8
StopBits = 1
Parity = 'N'
UnitID = 1
[[DeviceList.AutoEvents]]
Resource = 'temperature'
OnChange = false
Frequency = '10s'
[[DeviceList.AutoEvents]]
Resource = 'humidity'
OnChange = true
Frequency = '15000ms'
[[DeviceList]]
Name = 'modbus-01_hangzhou-temperature_device-2'
Profile = 'modbus_temperature_device_profile_common'
Description = 'An temperature device'
[DeviceList.Protocols]
[DeviceList.Protocols.modbus-rtu]
Address = '/tmp/slave'
BaudRate = 9600
DataBits = 8
StopBits = 1
Parity = 'N'
UnitID = 2
[[DeviceList.AutoEvents]]
Resource = 'temperature'
OnChange = false
Frequency = '10s'
[[DeviceList.AutoEvents]]
Resource = 'humidity'
OnChange = true
Frequency = '15000ms'
gcc toml.c test.c -o test
#增加執(zhí)行權(quán)限
sudo chmod +x test
#運行解析
./test sample.toml
測試輸出內(nèi)容如下
在這里插入圖片描述