2017-03-18 21:20:51 +00:00
|
|
|
# tomlc99
|
|
|
|
|
2020-08-18 21:46:20 +00:00
|
|
|
TOML in c99; v1.0 compliant.
|
2017-03-18 21:20:51 +00:00
|
|
|
|
2020-11-01 08:18:30 +00:00
|
|
|
If you are looking for a C++ library, you might try this wrapper: [https://github.com/cktan/tomlcpp](https://github.com/cktan/tomlcpp).
|
2020-11-01 08:17:17 +00:00
|
|
|
|
2020-07-04 23:35:46 +00:00
|
|
|
## Usage
|
2017-03-18 21:20:51 +00:00
|
|
|
|
|
|
|
Please see the `toml.h` file for details. What follows is a simple example that
|
|
|
|
parses this config file:
|
|
|
|
|
2020-07-04 23:35:46 +00:00
|
|
|
```toml
|
2017-03-18 21:20:51 +00:00
|
|
|
[server]
|
2020-07-04 23:35:46 +00:00
|
|
|
host = "www.example.com"
|
|
|
|
port = 80
|
2017-03-18 21:20:51 +00:00
|
|
|
```
|
|
|
|
|
2020-07-04 23:35:46 +00:00
|
|
|
The steps for getting values from our file is usually :
|
2017-03-18 21:20:51 +00:00
|
|
|
|
2020-07-04 23:35:46 +00:00
|
|
|
1. Parse the whole TOML file.
|
2020-12-04 07:16:55 +00:00
|
|
|
2. Traverse and locate a table in TOML.
|
2020-07-04 23:35:46 +00:00
|
|
|
3. Find a value from the table.
|
2020-12-04 07:16:55 +00:00
|
|
|
4. Free up allocated memory.
|
2020-07-04 23:35:46 +00:00
|
|
|
|
|
|
|
Below is an example of parsing the values from the example table.
|
|
|
|
|
|
|
|
1. Parse the whole TOML file.
|
2017-03-18 21:20:51 +00:00
|
|
|
|
2020-07-04 23:35:46 +00:00
|
|
|
```c
|
|
|
|
FILE* fp;
|
|
|
|
toml_table_t* conf;
|
|
|
|
char errbuf[200];
|
2017-03-18 21:20:51 +00:00
|
|
|
|
2020-11-02 01:55:33 +00:00
|
|
|
/* Open the file and parse content */
|
2020-07-04 23:35:46 +00:00
|
|
|
if (0 == (fp = fopen("path/to/file.toml", "r"))) {
|
2019-10-09 23:44:07 +00:00
|
|
|
return handle_error();
|
2020-07-04 23:35:46 +00:00
|
|
|
}
|
|
|
|
conf = toml_parse_file(fp, errbuf, sizeof(errbuf));
|
2020-11-02 01:55:33 +00:00
|
|
|
fclose(fp);
|
2020-07-04 23:35:46 +00:00
|
|
|
if (0 == conf) {
|
2019-10-09 23:44:07 +00:00
|
|
|
return handle_error();
|
2020-07-04 23:35:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Alternatively, use `toml_parse` which takes a string rather than a file. */
|
2020-09-18 16:39:53 +00:00
|
|
|
conf = toml_parse("A null terminated string that is TOML\0", errbuf, sizeof(errbuf));
|
2020-07-04 23:35:46 +00:00
|
|
|
```
|
|
|
|
|
2020-12-04 07:16:55 +00:00
|
|
|
2. Traverse and locate a table in toml.
|
2017-03-18 21:20:51 +00:00
|
|
|
|
2020-07-04 23:35:46 +00:00
|
|
|
```c
|
|
|
|
toml_table_t* server;
|
|
|
|
|
|
|
|
/* Locate the [server] table. */
|
|
|
|
if (0 == (server = toml_table_in(conf, "server"))) {
|
2019-10-09 23:44:07 +00:00
|
|
|
return handle_error();
|
2020-07-04 23:35:46 +00:00
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
3. Find a value from the table.
|
2017-03-18 21:20:51 +00:00
|
|
|
|
2020-07-04 23:35:46 +00:00
|
|
|
```c
|
|
|
|
/* Extract 'host' config value. */
|
2020-11-02 18:08:47 +00:00
|
|
|
toml_datum_t host = toml_string_in(server, "host");
|
2020-11-02 01:52:57 +00:00
|
|
|
if (!host.ok) {
|
|
|
|
toml_free(conf);
|
2019-10-09 23:44:07 +00:00
|
|
|
return handle_error();
|
2020-07-04 23:35:46 +00:00
|
|
|
}
|
|
|
|
|
2020-11-02 18:08:47 +00:00
|
|
|
toml_datum_t port = toml_int_in(server, "port");
|
2020-11-02 01:52:57 +00:00
|
|
|
if (!port.ok) {
|
|
|
|
toml_free(conf);
|
|
|
|
free(host.u.s);
|
2019-10-09 23:44:07 +00:00
|
|
|
return handle_error();
|
2020-07-04 23:35:46 +00:00
|
|
|
}
|
2017-03-18 21:20:51 +00:00
|
|
|
|
2020-11-02 01:52:57 +00:00
|
|
|
printf("host %s\n", host.u.s);
|
|
|
|
printf("port %d\n", port.u.i);
|
2020-07-04 23:35:46 +00:00
|
|
|
|
|
|
|
```
|
2017-03-18 21:20:51 +00:00
|
|
|
|
2020-12-04 07:16:55 +00:00
|
|
|
4. Free up allocated memory.
|
2017-03-18 21:20:51 +00:00
|
|
|
|
2020-07-04 23:35:46 +00:00
|
|
|
```c
|
2020-11-02 02:17:31 +00:00
|
|
|
/* 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.
|
|
|
|
*/
|
2020-07-04 23:35:46 +00:00
|
|
|
toml_free(conf);
|
2017-03-18 21:20:51 +00:00
|
|
|
|
2020-11-02 01:52:57 +00:00
|
|
|
/* Free any string values returned from access functions. */
|
|
|
|
free(host.u.s);
|
2017-03-18 21:20:51 +00:00
|
|
|
```
|
|
|
|
|
2020-11-02 02:17:31 +00:00
|
|
|
#### Accessing Table Content
|
2020-11-02 02:05:37 +00:00
|
|
|
|
2020-11-02 02:17:31 +00:00
|
|
|
TOML tables are dictionaries where lookups are done using string keys. In
|
2020-11-02 02:05:37 +00:00
|
|
|
general, all access methods on tables are named `toml_*_in(...)`.
|
|
|
|
|
2020-12-01 23:04:13 +00:00
|
|
|
In the normal case, you know the key and its content type, and retrievals can be done
|
|
|
|
using one of these functions:
|
2020-11-02 02:05:37 +00:00
|
|
|
```c
|
|
|
|
toml_string_in(tab, key);
|
|
|
|
toml_bool_in(tab, key);
|
|
|
|
toml_int_in(tab, key);
|
|
|
|
toml_double_in(tab, key);
|
|
|
|
toml_timestamp_in(tab, key);
|
2020-11-02 02:17:31 +00:00
|
|
|
toml_table_in(tab, key);
|
|
|
|
toml_array_in(tab, key);
|
2020-11-02 02:05:37 +00:00
|
|
|
```
|
|
|
|
|
2020-12-01 23:04:13 +00:00
|
|
|
You can also interrogate the keys in a table using an integer index:
|
|
|
|
```c
|
|
|
|
toml_table_t* tab = toml_parse_file(...);
|
|
|
|
for (int i = 0; ; i++) {
|
|
|
|
const char* key = toml_key_in(tab, i);
|
|
|
|
if (!key) break;
|
|
|
|
printf("key %d: %s\n", i, key);
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
2020-11-02 02:17:31 +00:00
|
|
|
#### Accessing Array Content
|
|
|
|
|
2020-12-01 23:04:13 +00:00
|
|
|
TOML arrays can be deref-ed using integer indices. In general, all access methods on arrays are named `toml_*_at()`.
|
2020-11-02 02:17:31 +00:00
|
|
|
|
|
|
|
To obtain the size of an array:
|
|
|
|
```c
|
|
|
|
int size = toml_array_nelem(arr);
|
|
|
|
```
|
|
|
|
|
2020-11-02 02:56:36 +00:00
|
|
|
To obtain the content of an array, use a valid index and call one of these functions:
|
2020-11-02 02:17:31 +00:00
|
|
|
```c
|
|
|
|
toml_string_at(arr, idx);
|
|
|
|
toml_bool_at(arr, idx);
|
|
|
|
toml_int_at(arr, idx);
|
|
|
|
toml_double_at(arr, idx);
|
|
|
|
toml_timestamp_at(arr, idx);
|
|
|
|
toml_table_at(arr, idx);
|
|
|
|
toml_array_at(arr, idx);
|
|
|
|
```
|
|
|
|
|
2020-11-02 18:08:47 +00:00
|
|
|
#### toml_datum_t
|
2020-11-02 02:17:31 +00:00
|
|
|
|
2020-11-02 18:08:47 +00:00
|
|
|
Some `toml_*_at` and `toml_*_in` functions return a toml_datum_t
|
2020-11-02 02:17:31 +00:00
|
|
|
structure. The `ok` flag in the structure indicates if the function
|
|
|
|
call was successful. If so, you may proceed to read the value
|
2020-11-09 21:45:25 +00:00
|
|
|
corresponding to the type of the content.
|
2020-11-02 02:17:31 +00:00
|
|
|
|
|
|
|
For example:
|
|
|
|
```
|
2020-11-02 18:08:47 +00:00
|
|
|
toml_datum_t host = toml_string_in(tab, "host");
|
2020-11-02 02:17:31 +00:00
|
|
|
if (host.ok) {
|
|
|
|
printf("host: %s\n", host.u.s);
|
2020-11-13 21:14:16 +00:00
|
|
|
free(host.u.s); /* FREE applies to string and timestamp types only */
|
2020-11-02 02:17:31 +00:00
|
|
|
}
|
|
|
|
```
|
2020-11-02 02:05:37 +00:00
|
|
|
|
2020-11-24 12:54:40 +00:00
|
|
|
** IMPORTANT: if the accessed value is a string or a timestamp, you must call `free(datum.u.s)` or `free(datum.u.ts)` respectively after usage. **
|
2020-11-24 12:47:23 +00:00
|
|
|
|
2020-11-02 02:41:46 +00:00
|
|
|
## Building and installing
|
2017-03-18 21:20:51 +00:00
|
|
|
|
2020-11-02 02:41:46 +00:00
|
|
|
A normal *make* suffices. You can also simply include the
|
2017-03-18 21:20:51 +00:00
|
|
|
`toml.c` and `toml.h` files in your project.
|
|
|
|
|
2020-11-02 02:41:46 +00:00
|
|
|
Invoking `make install` will install the header file in
|
|
|
|
/usr/local/include and library files in /usr/local/lib.
|
2020-11-02 02:39:32 +00:00
|
|
|
|
2020-11-02 02:41:46 +00:00
|
|
|
Alternatively, specify `make install prefix=/a/file/path` to install into
|
|
|
|
/a/file/path/include and /a/file/path/lib/.
|
2020-11-02 02:39:32 +00:00
|
|
|
|
2020-07-04 23:35:46 +00:00
|
|
|
## Testing
|
2017-03-18 21:20:51 +00:00
|
|
|
|
|
|
|
To test against the standard test set provided by BurntSushi/toml-test:
|
|
|
|
|
2020-07-04 23:35:46 +00:00
|
|
|
```sh
|
|
|
|
% make
|
|
|
|
% cd test1
|
|
|
|
% bash build.sh # do this once
|
|
|
|
% bash run.sh # this will run the test suite
|
2019-10-08 23:58:18 +00:00
|
|
|
```
|
|
|
|
|
2017-03-18 21:20:51 +00:00
|
|
|
|
2019-10-08 23:58:18 +00:00
|
|
|
To test against the standard test set provided by iarna/toml:
|
2017-03-18 21:20:51 +00:00
|
|
|
|
2020-07-04 23:35:46 +00:00
|
|
|
```sh
|
|
|
|
% make
|
|
|
|
% cd test2
|
|
|
|
% bash build.sh # do this once
|
|
|
|
% bash run.sh # this will run the test suite
|
2019-10-08 23:58:18 +00:00
|
|
|
```
|