toml/tomlc99/README.md

194 lines
4.7 KiB
Markdown
Raw Permalink Normal View History

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
2021-01-28 02:53:31 +00:00
* Compatible with [TOML v1.0.0](https://toml.io/en/v1.0.0).
2020-12-05 22:19:53 +00:00
* Tested with multiple test suites, including
[toml-lang/toml-test](https://github.com/toml-lang/toml-test) and
2020-12-05 22:19:53 +00:00
[iarna/toml-spec-tests](https://github.com/iarna/toml-spec-tests).
* Provides very simple and intuitive interface.
## Usage
2017-03-18 21:20:51 +00:00
2022-03-28 12:54:28 +00:00
Please see the `toml.h` file for details. The following is a simple example that
2017-03-18 21:20:51 +00:00
parses this config file:
```toml
2017-03-18 21:20:51 +00:00
[server]
host = "www.example.com"
2020-12-05 22:19:53 +00:00
port = [ 8080, 8181, 8282 ]
2017-03-18 21:20:51 +00:00
```
2022-03-28 12:54:28 +00:00
These are the usual steps for getting values from a file:
2017-03-18 21:20:51 +00:00
2020-12-05 22:19:53 +00:00
1. Parse the TOML file.
2020-12-04 07:16:55 +00:00
2. Traverse and locate a table in TOML.
2020-12-05 22:19:53 +00:00
3. Extract values from the table.
2020-12-04 07:16:55 +00:00
4. Free up allocated memory.
Below is an example of parsing the values from the example table.
```c
2020-12-05 22:19:53 +00:00
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include "toml.h"
2020-12-23 07:09:36 +00:00
static void error(const char* msg, const char* msg1)
2020-12-05 22:19:53 +00:00
{
2020-12-23 07:09:36 +00:00
fprintf(stderr, "ERROR: %s%s\n", msg, msg1?msg1:"");
exit(1);
}
2017-03-18 21:20:51 +00:00
2020-12-05 22:19:53 +00:00
int main()
{
2020-12-23 07:09:36 +00:00
FILE* fp;
char errbuf[200];
// 1. Read and parse toml file
fp = fopen("sample.toml", "r");
if (!fp) {
error("cannot open sample.toml - ", strerror(errno));
}
toml_table_t* conf = toml_parse_file(fp, errbuf, sizeof(errbuf));
fclose(fp);
if (!conf) {
error("cannot parse - ", errbuf);
}
// 2. Traverse to a table.
toml_table_t* server = toml_table_in(conf, "server");
if (!server) {
error("missing [server]", "");
}
// 3. Extract values
toml_datum_t host = toml_string_in(server, "host");
if (!host.ok) {
error("cannot read server.host", "");
}
toml_array_t* portarray = toml_array_in(server, "port");
if (!portarray) {
error("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;
}
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-12-05 23:45:30 +00:00
general, all access functions on tables are named `toml_*_in(...)`.
2020-11-02 02:05:37 +00:00
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-12-04 22:30:15 +00:00
Invoking `make install` will install the header and library files into
/usr/local/{include,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
2020-12-04 22:30:15 +00:00
/a/file/path/{include,lib}.
2020-11-02 02:39:32 +00:00
## Testing
2017-03-18 21:20:51 +00:00
To test against the standard test set provided by toml-lang/toml-test:
2017-03-18 21:20:51 +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
```sh
% make
% cd test2
% bash build.sh # do this once
% bash run.sh # this will run the test suite
```