Namelists

Namelists are an I/O feature for format-free input and output of variables by key-value assignments that were first introduced by some FORTRAN 77 compilers, but then became a Fortran 90 standard later. Most compilers offer extensions to the Namelist standard. Fortran variables can be read from and written to plain-text files in a standardised format, usually with file ending .nml.

The namelist statement is used to define the identifier and the variables that a part of the Namelist.

integer            :: foo
integer            :: bar
character(len=128) :: str

namelist /EXAMPLE/ foo, bar, str

Keys inside a Namelist are case-insensitive, i. e., FOO and foo refer to the same variable. Each Namelist starts with &<name> and ends with a single /. The list EXAMPLE contains the integers foo and bar, as well as the character string str:

! namelist.nml
&EXAMPLE
FOO=5,
BAR=17,
STR='Hello, World!'
/

It is possible to store multiple Namelists in a single file. The files can contain Fortran comments. In order to read a Namelist from stdin or file, we just pass it via the nml argument to the read statement:

read (nml=EXAMPLE, unit=fu)

We can write Namelists to stdout or file in the very same way by setting the nml specifier in the write statement:

write (nml=EXAMPLE, unit=fu)

Reading Namelist Files

The Namelist EXAMPLE is given in file namelist.nml:

&EXAMPLE
X=100
Y=500
R(1)=10.5
R(2)=20.25
ALICE%ID=1
ALICE%NAME='Alice'
ALICE%AGE=27
/

The Fortran program in example.f90 reads the Namelist file and outputs some of its values. If the read operation fails, the default values are shown instead.

! example.f90
program main
    use, intrinsic :: iso_fortran_env, only: stderr => error_unit
    implicit none

    type :: person_type
        integer           :: id
        character(len=32) :: name
        integer           :: age
    end type person_type

    integer           :: x, y
    real              :: r(2)
    type(person_type) :: alice

    ! Set initial values.
    alice = person_type(-1, 'Jane Doe', 0)
    x = 0; y = 0
    r = [ 0.0, 0.0 ]

    ! Read from file.
    call read_namelist('namelist.nml', alice, x, y, r)

    ! Output some values.
    print '(a, i0)', 'PERSON ID:   ', alice%id
    print '(2a)',    'PERSON NAME: ', alice%name
    print '(a, i0)', 'PERSON AGE:  ', alice%age
contains
    subroutine read_namelist(file_path, person, x, y, r)
        !! Reads Namelist from given file.
        character(len=*),  intent(in)  :: file_path
        type(person_type), intent(out) :: person
        integer,           intent(out) :: x, y
        real,              intent(out) :: r(2)
        integer                        :: fu, rc

        ! Namelist definition.
        namelist /EXAMPLE/ x, y, r, person

        ! Check whether file exists.
        inquire (file=file_path, iostat=rc)

        if (rc /= 0) then
            write (stderr, '(3a)') 'Error: input file "', trim(file_path), '" does not exist.'
            return
        end if

        ! Open and read Namelist file.
        open (action='read', file=file_path, iostat=rc, newunit=fu)
        read (nml=EXAMPLE, iostat=rc, unit=fu)

        if (rc /= 0) then
            write (stderr, '(a)') 'Error: invalid Namelist format.'
        end if

        close (fu)
    end subroutine read_namelist
end program main

Compile and run the program with:

$ gfortran10 -o example example.f90
$ ./example
PERSON ID:   1
PERSON NAME: Alice
PERSON AGE:  27

Libraries