revised example

This commit is contained in:
CK Tan 2020-12-05 14:19:53 -08:00
parent a2d704c7af
commit ae9514e87b
3 changed files with 97 additions and 84 deletions

118
README.md
View File

@ -4,6 +4,13 @@ TOML in c99; v1.0 compliant.
If you are looking for a C++ library, you might try this wrapper: [https://github.com/cktan/tomlcpp](https://github.com/cktan/tomlcpp).
* Compatible with [TOML v1.0.0-rc.3](https://toml.io/en/v1.0.0-rc.3).
* Tested with multiple test suites, including
[BurntSushi/toml-test](https://github.com/BurntSushi/toml-test) and
[iarna/toml-spec-tests](https://github.com/iarna/toml-spec-tests).
* Provides very simple and intuitive interface.
## Usage
Please see the `toml.h` file for details. What follows is a simple example that
@ -12,84 +19,81 @@ parses this config file:
```toml
[server]
host = "www.example.com"
port = 80
port = [ 8080, 8181, 8282 ]
```
The steps for getting values from our file is usually :
1. Parse the whole TOML file.
2. Get a single table from the file.
3. Find a value from the table.
1. Parse the TOML file.
2. Traverse to a table.
3. Extract values from the table.
4. Then, free up that memory if needed.
Below is an example of parsing the values from the example table.
1. Parse the whole TOML file.
```c
FILE* fp;
toml_table_t* conf;
char errbuf[200];
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include "toml.h"
/* Open the file and parse content */
if (0 == (fp = fopen("path/to/file.toml", "r"))) {
return handle_error();
}
conf = toml_parse_file(fp, errbuf, sizeof(errbuf));
fclose(fp);
if (0 == conf) {
return handle_error();
static void fatal(const char* msg, const char* msg1)
{
fprintf(stderr, "ERROR: %s%s\n", msg, msg1?msg1:"");
exit(1);
}
/* Alternatively, use `toml_parse` which takes a string rather than a file. */
conf = toml_parse("A null terminated string that is TOML\0", errbuf, sizeof(errbuf));
```
int main()
{
FILE* fp;
char errbuf[200];
2. Get a single table from the file.
// 1. Read and parse toml file
fp = fopen("sample.toml", "r");
if (!fp) {
fatal("cannot open sample.toml - ", strerror(errno));
}
```c
toml_table_t* server;
toml_table_t* conf = toml_parse_file(fp, errbuf, sizeof(errbuf));
fclose(fp);
/* Locate the [server] table. */
if (0 == (server = toml_table_in(conf, "server"))) {
return handle_error();
}
```
if (!conf) {
fatal("cannot parse - ", errbuf);
}
3. Find a value from the table.
// 2. Traverse to a table.
toml_table_t* server = toml_table_in(conf, "server");
if (!server) {
fatal("missing [server]", "");
}
```c
/* Extract 'host' config value. */
toml_datum_t host = toml_string_in(server, "host");
if (!host.ok) {
toml_free(conf);
return handle_error();
}
// 3. Extract values
toml_datum_t host = toml_string_in(server, "host");
if (!host.ok) {
fatal("cannot read server.host", "");
}
toml_datum_t port = toml_int_in(server, "port");
if (!port.ok) {
toml_free(conf);
toml_array_t* portarray = toml_array_in(server, "port");
if (!portarray) {
fatal("cannot read server.port", "");
}
printf("host: %s\n", host.u.s);
printf("port: ");
for (int i = 0; ; i++) {
toml_datum_t port = toml_int_at(portarray, i);
if (!port.ok) break;
printf("%d ", (int)port.u.i);
}
printf("\n");
// 4. Free memory
free(host.u.s);
return handle_error();
toml_free(conf);
return 0;
}
printf("host %s\n", host.u.s);
printf("port %d\n", port.u.i);
```
4. Then, free up that memory if needed.
```c
/* Use `toml_free` on the table returned from `toml_parse[_file]`.
* NOTE: you only need to `toml_free` the root table returned by `toml_parse[_file]`;
* internal tables do not need to be freed.
*/
toml_free(conf);
/* Free any string values returned from access functions. */
free(host.u.s);
```
#### Accessing Table Content

View File

@ -1,3 +1,3 @@
[server]
host = "example.com"
port = 80
port = [ 8080, 8181, 8282 ]

View File

@ -4,49 +4,58 @@
#include <stdlib.h>
#include "toml.h"
toml_table_t* load()
static void fatal(const char* msg, const char* msg1)
{
fprintf(stderr, "ERROR: %s%s\n", msg, msg1?msg1:"");
exit(1);
}
int main()
{
FILE* fp;
char errbuf[200];
// 1. Read and parse toml file
fp = fopen("sample.toml", "r");
if (!fp) {
fprintf(stderr, "ERROR: cannot open sample.toml - %s\n", strerror(errno));
exit(1);
fatal("cannot open sample.toml - ", strerror(errno));
}
toml_table_t* conf = toml_parse_file(fp, errbuf, sizeof(errbuf));
fclose(fp);
if (!conf) {
fprintf(stderr, "ERROR: cannot parse - %s\n", errbuf);
exit(1);
fatal("cannot parse - ", errbuf);
}
return conf;
}
int main()
{
toml_table_t* conf = load();
// 2. Traverse to a table.
toml_table_t* server = toml_table_in(conf, "server");
if (!server) {
fprintf(stderr, "ERROR: missing [server]\n");
exit(1);
}
toml_datum_t host = toml_string_in(server, "host");
if (!host.ok) {
fprintf(stderr, "ERROR: cannot read server.host.\n");
exit(1);
}
toml_datum_t port = toml_int_in(server, "port");
if (!port.ok) {
fprintf(stderr, "ERROR: cannot read server.port.\n");
exit(1);
fatal("missing [server]", "");
}
printf("host: %s, port %d\n", host.u.s, (int)port.u.i);
// 3. Extract values
toml_datum_t host = toml_string_in(server, "host");
if (!host.ok) {
fatal("cannot read server.host", "");
}
toml_array_t* portarray = toml_array_in(server, "port");
if (!portarray) {
fatal("cannot read server.port", "");
}
printf("host: %s\n", host.u.s);
printf("port: ");
for (int i = 0; ; i++) {
toml_datum_t port = toml_int_at(portarray, i);
if (!port.ok) break;
printf("%d ", (int)port.u.i);
}
printf("\n");
// 4. Free memory
free(host.u.s);
toml_free(conf);
return 0;