Skip to content

API Reference

FiNeR exposes a single module:

fortran
use finer

The module re-exports everything from the internal modules. The primary user-facing type is file_ini.

file_ini type

Public members

MemberTypeDescription
filenamecharacter(len=:), allocatablePath of the INI file (set automatically by load/save, or set directly)
NsintegerNumber of sections (managed internally; read to loop over sections)
opt_sepcharacter(1)Option name/value separator (default =)

Public methods

MethodDescription
freeFree all dynamic memory, resetting the object
loadLoad INI data from a file or string
has_optionInquire whether an option exists
has_sectionInquire whether a section exists
sectionGet a section name by index
indexGet the index of a named section or option
count_valuesCount the number of space-separated values in an option
addAdd a section or option (updates value if option already exists)
getGet an option value
delDelete a section or option
itemsReturn all option name/value pairs as a 2-D array
loopIterate over options with a do while loop
printPretty-print file data to a Fortran unit
saveSave file data to a physical file

free

Safely resets a file_ini variable, deallocating all sections and options. Use this before re-loading new data into an existing variable.

fortran
use finer
type(file_ini) :: fini

call fini%load(filename='old.ini')
! ... work with old data ...
call fini%free
call fini%load(filename='new.ini')

load

Loads INI data. Either filename or source must be provided; if both are given, filename takes priority.

Signature:

fortran
call fini%load(filename=, source=, separator=, error=)
ArgumentIntentTypeDescription
filenamein, optionalcharacter(*)Path to the INI file
sourcein, optionalcharacter(*)INI content as a string
separatorin, optionalcharacter(1)Option separator (default =)
errorout, optionalintegerError code (0 = success)
fortran
use finer
type(file_ini)                :: fini
character(len=:), allocatable :: source

! Load from file with custom separator
call fini%load(filename='config.ini', separator=':')

! Load from an in-memory string
call fini%free
source = '[section-1]'//new_line('A')// &
         'option-1 = one'//new_line('A')// &
         'option-2 = 2.'//new_line('A')// &
         '           3. ; inline comment'//new_line('A')// &
         '[section-2]'//new_line('A')// &
         'option-1 = foo'
call fini%load(source=source)

has_option

Returns .true. if the named option exists anywhere in the file (or within a specific section). Optionally returns the name of the section containing the first match.

fortran
use finer
type(file_ini)   :: fini
character(100)   :: sec_name
logical          :: found

call fini%load(filename='config.ini')

found = fini%has_option(option_name='host')

! Also get the containing section name
found = fini%has_option(option_name='host', section_name=sec_name)
if (found) print *, 'host is in section: ', trim(sec_name)

INFO

section_name is a fixed-length buffer. If the actual section name is longer than the buffer, the returned name is truncated.


has_section

Returns .true. if the named section exists.

fortran
use finer
type(file_ini) :: fini

call fini%load(filename='config.ini')

if (fini%has_section(section_name='database')) then
  print *, 'database section found'
end if

section

Returns the name of the section at position i. Use with Ns to loop over all sections.

fortran
use finer
type(file_ini)                :: fini
character(len=:), allocatable :: sec_name
integer                       :: s

call fini%load(filename='config.ini')

do s = 1, fini%Ns
  sec_name = fini%section(s)
  print *, 'Section: ', sec_name
end do

index

Returns the index of a section, or of an option within a section. Returns 0 if not found. The optional back=.true. argument returns the last matching occurrence instead of the first.

Signatures:

fortran
i = fini%index(section=, back=)          ! index of section
i = fini%index(section=, option=, back=) ! index of option in section
fortran
use finer
type(file_ini) :: fini
integer        :: s, o

call fini%load(filename='config.ini')

s = fini%index(section='database')
if (s > 0) print *, 'database is section #', s

o = fini%index(section='database', option='host')
if (o > 0) print *, 'host is option #', o, ' in database'

count_values

Counts the number of space-separated tokens in an option's value. Useful for allocating arrays before calling get.

fortran
use finer
type(file_ini)      :: fini
integer, allocatable :: array(:)
integer              :: Nv

call fini%load(source='[foo]'//new_line('A')//'array = 1 2 3 4 5')

Nv = fini%count_values(section_name='foo', option_name='array')
allocate(array(1:Nv))
call fini%get(section_name='foo', option_name='array', val=array)
print *, array   ! 1 2 3 4 5

add

Adds a section, or adds/updates an option within a section. If the section does not exist, it is created automatically. If the option already exists, its value is updated.

Signatures:

fortran
call fini%add(section=)                      ! add section only
call fini%add(section=, option=, val=)       ! add/update option
call fini%add(section=, option=, val=, delimiter=)  ! array with delimiter

val is unlimited polymorphic — pass any intrinsic scalar or array.

fortran
use finer
use penf, only: R8P
type(file_ini) :: fini

call fini%add(section='sec-foo')
call fini%add(section='sec-foo', option='bar',   val=-32.1_R8P)
call fini%add(section='sec-foo', option='baz',   val=' hello FiNeR! ')
call fini%add(section='sec-foo', option='array', val=[1, 2, 3, 4])
call fini%add(section='sec-bar')
call fini%add(section='sec-bar', option='bools', val=[.true., .false., .false.])

get

Retrieves an option value. The receiving variable (val) can be a scalar or an array of any intrinsic type. The optional delimiter argument specifies the separator between array values (default: space).

fortran
use finer
use penf, only: I4P
type(file_ini)       :: fini
integer(I4P)         :: error
integer, allocatable :: arr(:)
character(64)        :: host

call fini%load(filename='config.ini')

call fini%get(section_name='database', option_name='host',  val=host,  error=error)
call fini%get(section_name='foo',      option_name='array', val=arr,   error=error)
if (error == 0) print *, arr

TIP

Always allocate the receiving array to the correct size with count_values before calling get with an array val.


del

Deletes a section (and all its options) or a single option within a section.

fortran
use finer
type(file_ini) :: fini

call fini%load(filename='config.ini')

call fini%del(section_name='sec-foo', option_name='bar')  ! delete one option
call fini%del(section_name='sec-bar')                     ! delete whole section

WARNING

Deleting a section removes all of its options.


items

Returns a (N, 2) allocatable character array where each row holds [option_name, option_value] as strings.

fortran
use finer
type(file_ini)                :: fini
character(len=:), allocatable :: it(:,:)
integer                       :: i

call fini%load(filename='config.ini')

it = fini%items(section_name='database')
do i = 1, size(it, dim=1)
  print *, trim(it(i,1)), ' = ', trim(it(i,2))
end do

loop

Provides a do while iteration over options. Returns .true. and fills option(:) with [name, value] on each call; returns .false. when exhausted and resets the internal counter.

Signatures:

fortran
do while (fini%loop(option=opt))             ! all options in file
do while (fini%loop(section_name=, option=)) ! options in one section
fortran
use finer
type(file_ini)                :: fini
character(len=:), allocatable :: opt(:)

call fini%load(filename='config.ini')

! Iterate over all options in 'database' section
do while (fini%loop(section_name='database', option=opt))
  print *, trim(opt(1)), ' = ', trim(opt(2))
end do

! Iterate over every option in the entire file
do while (fini%loop(option=opt))
  print *, trim(opt(1)), ' = ', trim(opt(2))
end do

print

Pretty-prints all file data to a Fortran I/O unit.

ArgumentIntentTypeDescription
unitinintegerFortran unit number (6 = stdout)
prefin, optionalcharacter(*)Line prefix string
iostatout, optionalintegerI/O status
iomsgout, optionalcharacter(*)I/O error message
retain_commentsin, optionallogicalPrint inline comments (default .false.)
fortran
use finer
type(file_ini) :: fini
integer        :: iostat
character(200) :: iomsg

call fini%load(filename='config.ini')
call fini%print(unit=6, pref='|-->', iostat=iostat, iomsg=iomsg)
call fini%print(unit=6, retain_comments=.true.)

save

Saves file data to a physical file. If filename is not passed, the value of the filename public member is used (which may have been set by a previous load call).

ArgumentIntentTypeDescription
filenamein, optionalcharacter(*)Output file path
iostatout, optionalintegerI/O status
iomsgout, optionalcharacter(*)I/O error message
retain_commentsin, optionallogicalWrite inline comments (default .false.)
fortran
use finer
use penf, only: R8P
type(file_ini) :: fini
integer        :: iostat
character(200) :: iomsg

call fini%add(section='sec-foo', option='bar', val=-32.1_R8P)
call fini%save(filename='foo.ini', iostat=iostat, iomsg=iomsg)
call fini%save(filename='foo-with-comments.ini', retain_comments=.true.)

Error codes

Defined in module finer_backend and re-exported by finer:

ConstantValueMeaning
ERR_OPTION_NAME1Bad option name
ERR_OPTION_VALS2Bad option values
ERR_OPTION3Generic option error
ERR_SECTION_NAME4Bad section name
ERR_SECTION_OPTIONS5Bad section options
ERR_SECTION6Generic section error
ERR_SOURCE_MISSING7No source provided to load