A Chicken Scheme wrapper for the C TOML library
Go to file
Martin Tournoij 5221b3d3d6
Fix toml_json.c output (#85)
* Fix toml_json.c output

There were two issues; partly related to changes in upstream toml-test:

- Use appropriate type for local date and times.

- The arrays would get printed as:

      {"type": "array", "value": [...the values...]}

  But this should just be:

      [...the values...]

  It also wouldn't print mixed arrays because 'm' was missing in the
  switch; I adapted this from toml_cat.c.

Before:

	toml-test [./toml_json]: using embedded tests: 328 passed, 87 failed

After:

	toml-test [./toml_json]: using embedded tests: 351 passed, 64 failed

The remaining test failures look like a few minor issues in toml.c,
rather than toml_json.c

* Also fix the "test1" toml-test runner
2023-09-30 12:36:59 -07:00
stdex add test for timestamp millisec 2021-07-04 19:41:16 -07:00
test1 Fix toml_json.c output (#85) 2023-09-30 12:36:59 -07:00
test2 Fix toml_json.c output (#85) 2023-09-30 12:36:59 -07:00
unittest format 2022-01-05 06:02:11 +00:00
.editorconfig format with clang-format 2021-12-25 23:42:50 -08:00
.gitignore add sample program 2020-11-01 18:31:50 -08:00
LICENSE add toml_key_exists() 2021-10-25 23:21:48 -07:00
Makefile fix: make install fail when libtoml.pc does not exist 2023-05-29 12:31:52 -07:00
README.md Fix toml_json.c output (#85) 2023-09-30 12:36:59 -07:00
libtoml.pc.sample fix: Makefile install prefix missing for libtoml.pc #68 2021-12-16 13:36:32 -08:00
sample.toml revised example 2020-12-05 14:19:53 -08:00
toml.c format and comment only 2023-09-18 20:28:16 -07:00
toml.h format and comment only 2023-09-18 20:28:16 -07:00
toml_cat.c format with clang-format 2021-12-25 23:42:50 -08:00
toml_json.c Fix toml_json.c output (#85) 2023-09-30 12:36:59 -07:00
toml_sample.c format with clang-format 2021-12-25 23:42:50 -08:00

README.md

tomlc99

TOML in c99; v1.0 compliant.

If you are looking for a C++ library, you might try this wrapper: https://github.com/cktan/tomlcpp.

Usage

Please see the toml.h file for details. The following is a simple example that parses this config file:

[server]
	host = "www.example.com"
	port = [ 8080, 8181, 8282 ]

These are the usual steps for getting values from a file:

  1. Parse the TOML file.
  2. Traverse and locate a table in TOML.
  3. Extract values from the table.
  4. Free up allocated memory.

Below is an example of parsing the values from the example table.

#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include "toml.h"

static void error(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) {
        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;
}

Accessing Table Content

TOML tables are dictionaries where lookups are done using string keys. In general, all access functions on tables are named toml_*_in(...).

In the normal case, you know the key and its content type, and retrievals can be done using one of these functions:

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);
toml_table_in(tab, key);
toml_array_in(tab, key);

You can also interrogate the keys in a table using an integer index:

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);
}

Accessing Array Content

TOML arrays can be deref-ed using integer indices. In general, all access methods on arrays are named toml_*_at().

To obtain the size of an array:

int size = toml_array_nelem(arr);

To obtain the content of an array, use a valid index and call one of these functions:

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);

toml_datum_t

Some toml_*_at and toml_*_in functions return a toml_datum_t structure. The ok flag in the structure indicates if the function call was successful. If so, you may proceed to read the value corresponding to the type of the content.

For example:

toml_datum_t host = toml_string_in(tab, "host");
if (host.ok) {
	printf("host: %s\n", host.u.s);
	free(host.u.s);   /* FREE applies to string and timestamp types only */
}

** 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. **

Building and installing

A normal make suffices. You can also simply include the toml.c and toml.h files in your project.

Invoking make install will install the header and library files into /usr/local/{include,lib}.

Alternatively, specify make install prefix=/a/file/path to install into /a/file/path/{include,lib}.

Testing

To test against the standard test set provided by toml-lang/toml-test:

% make
% cd test1
% bash build.sh   # do this once
% bash run.sh     # this will run the test suite

To test against the standard test set provided by iarna/toml:

% make
% cd test2
% bash build.sh   # do this once
% bash run.sh     # this will run the test suite