TOML

TOML is a file format often used to store application settings and configurations. It is easy to read and write, and shares some similiarities with the older INI format. The syntax consists of key-value pairs, separated by optional sections. The TOML standard supports the data types String, Integer, Float, Boolean, Datetime, Array, and Table.

The file format is processed by TOML parsers, with the TOML wiki listing some them. The toml-f library is a pure Fortran 2008 implementation that is dual-licenced under MIT and Apache 2.0.

toml-f

The build systems Meson and Ninja are required to compile toml-f. Both dependencies are available on most Unix-like operating systems. On FreeBSD, install the packages devel/meson and devel/ninja:

# pkg install devel/meson devel/ninja

In the next step, clone the toml-f repository or download the master branch, and create a Ninja build script with Meson to compile the source code:

$ git clone https://github.com/toml-f/toml-f
$ cd toml-f/
$ FC=gfortran10 meson setup build
$ meson compile -C build

The FC parameter sets the Fortran compiler to GNU Fortran. The static library libtoml-f.a, the shared library libtoml-f.so, and the module file tomlf.mod for linking are written to build_gcc/ and its subdirectories.

Example

We create a basic TOML file sample.toml with the following content:

# sample.toml
title = "TOML Example"
[owner]
name = "Tom Preston-Werner"
dob = "1979-05-27T07:32:00-08:00"
[database]
server = "10.0.0.1"
ports = [ 8001, 8002, 8003 ]
connection_max = 5000
enabled = true

The example program in Fortran 2008 will read the file and print some of its values to standard output:

! example.f90
program main
    use, intrinsic :: iso_fortran_env, only: stderr => error_unit
    use :: tomlf
    implicit none
    character(len=*), parameter :: FILE_NAME = 'sample.toml'

    character(len=:), allocatable :: title, server
    integer                       :: fu, rc
    logical                       :: file_exists
    type(toml_table), allocatable :: table
    type(toml_table), pointer     :: child

    inquire (file=FILE_NAME, exist=file_exists)

    if (.not. file_exists) then
        write (stderr, '(3a)') 'Error: TOML file "', FILE_NAME, '" not found'
        stop
    end if

    open (action='read', file=FILE_NAME, iostat=rc, newunit=fu)

    if (rc /= 0) then
        write (stderr, '(3a)') 'Error: Reading TOML file "', FILE_NAME, '" failed'
        stop
    end if

    call toml_parse(table, fu)
    close (fu)

    if (.not. allocated(table)) then
        write (stderr, '(a)') 'Error: Parsing failed'
        stop
    end if

    ! Output title.
    call get_value(table, 'title', title, 'N/A')
    print '(2a)', 'Title: ', title

    ! Get [database] section.
    call get_value(table, 'database', child, requested=.false.)

    if (associated(child)) then
        ! Output server address.
        call get_value(child, 'server', server, 'N/A')
        print '(2a)', 'Server: ', server
    end if
end program main

Compile, link, and run the example with:

$ gfortran10 -o example example.f90 libtoml-f.a
$ ./example
Title: TOML Example
Server: 10.0.0.1

References