Einführung
Einführung#
Dieses Tutorial bietet eine einfache Einführung in die Benutzung von TOML Fortran. Das Lesen und Schreiben von TOML Datenstrukturen wird behandelt, sowie die Erstellung von Datenstrukturen aus TOML Dokumenten außerdem wird diskutiert wie eine Datenstruktur aus einem TOML Dokument erstellt wird oder wieder in ein TOML Dokument konvertiert wird.
Für dieses Projekt werden wir mit fpm arbeiten, aber Du kannst jedes Build-Tool verwenden, mit dem Du dich gut zurecht kommst, schau Dir die Integrations-Anleitung an, um einen passenden Setup zu finden. Wir starten mit der Erstellung eines minimalen Paketmanifests, um TOML Fortran in unserem fpm Projekt zu benutzen.
name = "demo"
[dependencies]
toml-f.git = "https://github.com/toml-f/toml-f.git"
Die öffentliche TOML Fortran API wird in dem Modul tomlf
definiert, und wir werden nur dieses Modul für diesen gesamten Kurs brauchen. Die Hauptdatenstruktur, mit der wir uns in diesem Kurs konkret kommunizieren wird toml_table
und toml_array
Instanzen, die wir mit dem generischen interface get_value
manipulieren können.
module reader
use tomlf, only : toml_table, toml_array, get_value, len
implicit none
private
public :: read_data
contains
subroutine read_data(table, title, spectrum)
type(toml_table), intent(inout) :: table
character(len=:), allocatable, intent(out) :: title
real, allocatable, intent(out) :: spectrum(:)
type(toml_table), pointer :: child
type(toml_array), pointer :: array
logical :: reverse
integer :: ival
! Get character value from entry "title"
call get_value(table, "title", title)
! Get subtable reference from entry "spectrum"
call get_value(table, "spectrum", child)
! Get array reference from entry "data"
call get_value(child, "data", array)
! Read all values from the data array
allocate(spectrum(len(array)))
do ival = 1, size(spectrum)
call get_value(array, ival, spectrum(ival))
end do
! Data is stored in reverse order
call get_value(child, "reverse", reverse, .false.)
if (reverse) spectrum(:) = spectrum(size(spectrum):1:-1)
end subroutine read_data
end module reader
Hinweis: Wir deklarieren die TOML Datenstruktur als mutable, d.h. intent(inout)
statt nur intent(in)
, da das get_value
interface die Datenstruktur verändern kann. Wir beginnen mit einem einfachen Testprogramm, welches nicht einmal ein TOML Dokument liest, sondern nur eine leere Tabelle an den Reader weitergeben.
program defaults
use reader, only : read_data
use tomlf, only : toml_table
implicit none
type(toml_table), allocatable :: table
character(len=:), allocatable :: title
real, allocatable :: spectrum(:)
table = toml_table()
call read_data(table, title, spectrum)
if (allocated(title)) then
print '(a)', "Title: '"//title//"'"
end if
print '(*(g0, 1x))', "Entries:", size(spectrum)
if (size(spectrum) > 0) then
print '(*(g0, 1x))', "Spectrum:", spectrum
end if
end program defaults
Das get_value
interface für die Verarbeitung der TOML Datenstruktur stellt sicher, dass die Datenstruktur vollständig durch den gesamten Prozess gelesen wird und fügt die gewünschten Knoten hinzu, wenn sie nicht vorhanden sind oder füllt sie mit Standardwerten aus. Überzeuge Dich, dass die leere Tabelle während des Lesens wirklich geändert wurde, indem Du einen Serializer an die Datenstruktur übergibst.
block
use tomlf, only : toml_serialize
print '(a)', "# Final TOML data structure"
print '(a)', toml_serialize(table)
end block
! Expected output:
! # Final TOML data structure
! [spectrum]
! data = [ ]
! reverse = false
Dieses Verhalten ist sehr einfach, da wir unsere Standardwerte definieren können, während wir definieren, wie wir die TOML Datenstruktur lesen.
Bemerkung
Das get_value
build interface ist nur eine der Möglichkeiten, um auf die TOML Datenstruktur mit TOML Fortran zuzugreifen. Es nimmt eine opionierten Ansicht auf, wie die Datenstruktur gelesen und verändert werden soll, was für einen Großteil der Anwendungen funktioniert.
Wir lesen jetzt ein echtes TOML Dokument und übergeben es an den Reader.
title = "Example"
spectrum.data = [0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0]
Wir adaptieren unseren Befehlszeilen-Driver, um die Datei input.toml
zu lesen und die Werte wie vorher auszugeben.
program readin
use reader, only : read_data
use tomlf, only : toml_table, toml_parse, toml_error
implicit none
type(toml_table), allocatable :: table
character(len=:), allocatable :: title
real, allocatable :: spectrum(:)
block
integer :: io
type(toml_error), allocatable :: error
open(file="input.toml", newunit=io, status="old")
call toml_parse(table, io, error)
close(io)
if (allocated(error)) then
print '(a)', "Error: "//error%message
stop 1
end if
end block
call read_data(table, title, spectrum)
if (allocated(title)) then
print '(a)', "Title: '"//title//"'"
end if
print '(*(g0, 1x))', "Entries:", size(spectrum)
if (size(spectrum) > 0) then
print '(*(g0, 1x))', "Spectrum:", spectrum
end if
end program readin
Durch das Ausführen des Programms mit fpm kannst Du sehen, dass wir die korrekten Werte aus dem Dokument gelesen haben.
❯ fpm run readin
Title: 'Example'
Entries: 10
Spectrum: 0.00000000 1.00000000 2.00000000 3.00000000 4.00000000 5.00000000 6.00000000 7.00000000 8.00000000 9.00000000
Du kannst das Serializer noch einmal verwenden, um die finale Datenstruktur zu schreiben, wenn Du möchtest, ob das get_value
interface Standardwerte hinzugefügt hat.
Wichtig
In diesem Tutorial hast Du gelernt, einfache Datenstrukturen aus TOML Dokumenten zu lesen. Du kannst nun
die Logik zum Lesen von Daten aus TOML Strukturen definieren
Standardwerte in Deinen Parsern definieren, wenn Du die Eingabestruktur definierst
ein echtes TOML Dokument aus einer Datei lesen
aus Deinen Datenstrukturen TOML Dokumente schreiben