Namelist Error Checking

Fortran namelists are a quick and dirty way of reading and writing variables to and from a file. It is actually the only high-level file access feature built into the Fortran language, in the sense of being able to read and write a complex formatted file with one line of code. Nowadays, I would recommend against using this feature since the format is not really a standard and varies from compiler to compiler, and there aren’t good parsers available for other languages (with the notable exception of Python). There are better configuration file formats available today such as JSON. However, namelists can still be encountered in legacy applications, and may still be useful to the lazy programmer.

One of the problems with namelists is that all the variables in the file have to correspond exactly in name, type, rank, and size to variables declared in your code. Syntax errors in the file are not easily detected and a failed read due to an unexpected variable will usually just return a non-zero status code that isn’t really much help in diagnosing the problem.

However, there is a way to output the line where the failure occurred on a namelist read, which can be quite useful for debugging. Say your code is expecting a namelist containing three real variables a, b, and c. However, the file contains the unexpected variable d like so:

&my_namelist
a = 1.0,
b = 2.0,
d = 3.0,
c = 4.0
\

Now consider the following Fortran code to read it:

program namelist_test

  use iso_fortran_env, wp => real64

  implicit none

  real(wp) :: a,b,c ! namelist variables
  integer  :: istat,iunit
  character(len=1000) :: line

  namelist /my_namelist/ a,b,c

  open(newunit=iunit,file='my_namelist.nml',&
       status='OLD')

  read(iunit, nml=my_namelist, iostat=istat)

  if (istat/=0) then
    backspace(iunit)
    read(iunit,fmt='(A)') line
    write(error_unit,'(A)') &
       'Invalid line in namelist: '//trim(line)
  end if

  close(iunit)

end program namelist_test

The READ statement will fail with a non-zero istat code. Then we simply use the BACKSPACE function, which moves the file position back one record (the record where the read failed). Then we can simply read this line and print it. This code produces the following error message:

Invalid line in namelist: d = 3.0,

Tagged with: ,
One comment on “Namelist Error Checking
  1. Stefano says:

    Wonderful trick!

    You are always a source of inspiration!

    Thank you Jacob!

Leave a Reply

Your email address will not be published. Required fields are marked *

*