Contents
1 The very basic "Hello World" example
2 Basic terminal output
3 String manipulation routines
4 Environment variables
5 Command line parameters

The very basic "Hello World" example

Releated source code files:

  • tutorial001a.f90

The very basic "Hello world" example reads in the Feat2 package as follows:

program tutorial001a

  use fsystem
  use genoutput
  implicit none

  ! Initialisation
  call system_init()
  call output_init("")

  ! Print a message
  call output_line ("Hello world. This is FEAT-2. Tutorial 001a.")

  ! Cleanup
  call output_done()

end program

In the very beginning, the modules "fsystem" and "genoutput" are included and initialised:

  use fsystem
  use genoutput

The module fsystem contains basic system-wide definitions and specifications. It has to be initialised with call system_init() in the very beginning of every program.

Similarly, the module genoutput (abbrev. for "general output") provides basic output routines for printing text to the terminal. It has to be initialised by one of the output_init routines - for very basic use, a simple call output_init("") is enough.

Afterwards, the command

  call output_line ("Hello world. This is FEAT-2. Tutorial 001a.")

prints a message to the terminal. The command output_line the basic text output command for messages to the terminal and a replacement for print and write (*,*). Without any parameters, it just prints the text message to the terminal. However, it provides additional output features like printing the text to a log file, adding a time stamp to the text, preventing line breaks etc. We come to this in a later tutorial.

The final call

  call output_done()

cleans up the output subsystem. Afterwards, the program is finished.

Note that there is currently no cleanup command like system_done. This is currently not necessary but might change in the future.

Basic terminal output

Releated source code files:

  • tutorial001b.f90

To print data to the terminal, there exist a large variety of printing and formatting commands. The output routines in genoutput contains basic printing capabilities, while the system module fsystem.f90 provides a lot of string manipulation routines for formatting of integer and real values. These can be combined with standard string manipulation routines like TRIM and ADJUSTL to provide structured output to the terminal.

Line breaks and separator lines

Some very commonly used routines from the genoutput module read as follows:

  • output_lbrk() - prints an empty line to the terminal
  • output_separator (...) - prints a separator line to the terminal. The parameter defines the type of the separator line, e.g. ** OU_SEP_STAR - a line containing stars ** OU_SEP_MINUS - a line made of "-" signs

So a piece of code

call output_lbrk()
call output_separator (OU_SEP_STAR)
call output_line ("This is FEAT-2. Tutorial 001b.")    
call output_separator (OU_SEP_MINUS)

prints the output

**************************************************************
This is FEAT-2. Tutorial 001b.
--------------------------------------------------------------

Data formatting

For formatting strings, a couple of sys_sXXXX routines from the module fsystem provides basic functionality. These routines allow to directly convert integers, reals, double precision values and logical data into strings with a specified number of digits. The following routines are commonly used:

  • sys_si(n,digits ) - Convert an integer to a string, right-adjusted, filled with digits spaces.
  • sys_siL(n,digits) - Left-adjusted version
  • sys_sd(n,digits) - Convert an double to a string with digits digits, right-adjusted.
  • sys_sdL(n,digits) - Left-adjusted version
  • sys_sd(n,digits) - Convert an double to a string in scientific notation with digits digits, right-adjusted.
  • sys_sdL(n,digits) - Left-adjusted version
  • sys_sl(digits) - Convert a logical to a string, right-adjusted

These routines usually have to be combined with TRIM and // for concatenation of strings and can this way be used to properly format tables of data during terminal output. So a code like

call output_line (trim(sys_si(0,3)) // "|" // trim(sys_sdEL(2.0_DP ** 0,10)) // "|" )
call output_line (trim(sys_si(1,3)) // "|" // trim(sys_sdEL(2.0_DP ** 1,10)) // "|" )
call output_line (trim(sys_si(4,3)) // "|" // trim(sys_sdEL(2.0_DP ** 4,10)) // "|" )

gives output of the following form:

  0|1.0000000000E+00|
  1|2.0000000000E+00|
  4|1.6000000000E+01|

A more extended example for output can be found in tutorial001b.f90,

! Print a message
call output_lbrk()
call output_separator (OU_SEP_STAR)
call output_line ("This is FEAT-2. Tutorial 001b.")    
call output_separator (OU_SEP_MINUS)

call output_line ("Let us print a table -- right-adjusted.")
call output_lbrk()
call output_line ("  n          x^n")
call output_line ("-----------------")
call output_line (sys_si(0,3) // "|" // sys_sd(2.0_DP ** 0,10) // "|")
call output_line (sys_si(1,3) // "|" // sys_sd(2.0_DP ** 1,10) // "|")
call output_line (sys_si(4,3) // "|" // sys_sd(2.0_DP ** 4,10) // "|")
call output_lbrk()

call output_separator (OU_SEP_MINUS)
call output_line ("Let us print a table -- left-adjusted.")
call output_lbrk()
call output_line ("  n          x^n")
call output_line ("-----------------")
call output_line (sys_siL(0,3) // "|" // sys_sdL(2.0_DP ** 0,10) // "|")
call output_line (sys_siL(1,3) // "|" // sys_sdL(2.0_DP ** 1,10) // "|")
call output_line (sys_siL(4,3) // "|" // sys_sdL(2.0_DP ** 4,10) // "|")
call output_lbrk()

call output_separator (OU_SEP_MINUS)
call output_line ("Let us print a table -- nicely adjusted.")
call output_lbrk()
call output_line ("  n              x^n")
call output_line ("---------------------")
call output_line (trim(sys_si(0,3)) // "|" // sys_adjustr(sys_sdL(2.0_DP ** 0,10),16) // "|" )
call output_line (trim(sys_si(1,3)) // "|" // sys_adjustr(sys_sdL(2.0_DP ** 1,10),16) // "|" )
call output_line (trim(sys_si(4,3)) // "|" // sys_adjustr(sys_sdL(2.0_DP ** 4,10),16) // "|" )
call output_lbrk()

call output_separator (OU_SEP_MINUS)
call output_line ("Let us print a table -- scientific.")
call output_lbrk()
call output_line ("  n              x^n")
call output_line ("---------------------")
call output_line (trim(sys_si(0,3)) // "|" // trim(sys_sdEL(2.0_DP ** 0,10)) // "|" )
call output_line (trim(sys_si(1,3)) // "|" // trim(sys_sdEL(2.0_DP ** 1,10)) // "|" )
call output_line (trim(sys_si(4,3)) // "|" // trim(sys_sdEL(2.0_DP ** 4,10)) // "|" )
call output_lbrk()

Output without line breaks

The above example also demonstrates an additional feature of the genoutput subsystem. The routine output_line provides an additional optional parameter bnolinebreak that can be used to prevent a like break during the output. Thus, a code like

call output_line ( "This is", bnolinebreak=.true. )
call output_line ( "a piece", bnolinebreak=.true. )
call output_line ( "of code" )

will produce an output

This is a piece of code

in one line, applying a like break only at the end.

String manipulation routines

Releated source code files:

  • tutorial001c.f90

The module fsystem provides extended capacibilities for string manipulation. At first, there are routines that provide converting strings to uppercase, lower case, replacing characters and removing quotes around a string. A straightforward example can be found in tutorial001c.f90 which reads as follows:

! =================================
! Conversion to upper case / lower case
! =================================
call output_line ("'This is a test' => " // sys_upcase ("'This is a test'") )
call output_line ("'This is a test' => " // sys_lowcase("'This is a test'") )

! =================================
! Character replacement
! =================================
call output_line ("'This is a test' => " // sys_charreplace("'This is a test'"," ","-") )

! =================================
! Dequoting. Partial output without line break
! =================================
sstring = "'This is a test'"
call output_line ( trim(sstring) // " =>", bnolinebreak=.true. )
call sys_dequote ( sstring )
call output_line ( " " // trim(sstring) )

The routines sys_upcase and sys_lowcase provide the basic functionality for converting strings to upper or lower case. These routines also exist in a "subroutine" implementation which can be invoked by a call,

  • call sys_toupper(...)
  • call sys_tolower(...)

This variant is usually a bit faster as it avoids temporary memory on the stack.

The subroutine sys_dequote can be used to "dequote" a string, i.e., to remove quotes around it. It replaces the original string. sys_charreplace on the other side replaces one character by another and returns the modified string; in the example, all space characters " " are replaced by commas ",".

String tokenizing

Releated source code files:

  • tutorial001d.f90

One feature of the string manipulation routines in the module fsystem is the ability to tokenise strings. This is a very important feature for reading data from data files. An example can be found in tutorial001d.f90:

sstring = "0.1 0.2 'This is a test' 0.3"
...

call sys_countTokens (sstring,ntokens," ")
call output_line ("Number of tokens: " // trim(sys_siL(ntokens,10)) )

istart = 1
itoken = 0

do while (istart .ne. 0)
  itoken = itoken + 1
  call sys_getNextToken (sstring,stoken,istart)
  call output_line ("Token " // trim(sys_siL(itoken,10)) // ": " // trim(stoken) )
end do

The routine sys_countTokens counts the number of tokens in a string sstring where the separator is specified here as a space character " ". The tokens themself can be extracted using the routine sys_getNextToken. For the first call, sys_getNextToken has to be called with istart=1. sys_getNextToken extracts the token and writes it to stoken. istart always points to the index of the current token in the string and will be set to 0 if the last token is reached.

By default, the routine sys_getNextToken recognizes strings in quotes like 'This is a test' and returns them as one token. This can be prevented by the additional optional modified bquoting.

Environment variables

Related source files:

  • tutorial001e.f90

The system library fsystem provides the ability to work with environment variables (such as the PATH variable). Environment variables can be extracted using the function sys_getenv_string as it can be seen in the example tutorial001e.f90:

character(LEN=2048) :: sresult
...

if (.not. sys_getenv_string("PATH", sresult)) then
  call output_line ("Cannot get the PATH variable..")
else
  call output_line ("$PATH = " // trim(sresult))
end if

The first parameter defines the name of the variable to be returned (here PATH), the second receives the result. The return code tells whether the variable exist or not.

Note 1: Environment variables come in very handy in the benchmark subsystem of the Feat2 library. This is described in another tutorial.

Note 2: Defining environment variables is of course system dependent and usually done via the command line. On Linux/Unix systems with tghe bash command line interpreter, an environment variable is defined by

MYVAR=some_data
export MYVAR

For tcsh based command line interpreters, the command

setenv MYVAR some_data

is used instead. On Windows-based sytems, one uses the command

set MYVAR=some_data

or defines the value using the environment settings of the Windows system itself.

Command line parameters

Related source files:

  • tutorial001f.f90

Using the routines sys_ncommandLineArgs and sys_getcommandLineArg from the fsystem library allows to work with command line parameters. The commands for extracting this information from the call to a program is system dependend and encapsuled in these routines. A very simple example how to work with command line parameters can be found in tutorial001f.f90:

nargc = sys_ncommandLineArgs()
...

do iarg=1,nargc
  call sys_getcommandLineArg(iarg,sargv)
  ...
end do

The routine sys_ncommandLineArgs() returns the number of command line arguments and sys_getcommandLineArg the corresponding argument. Thus, if the application is invoked via

./myapp param1 param2 param3

there is

  • nargc = sys_ncommandLineArgs() => nargc=3
  • call sys_getcommandLineArg(1,sargv) => sargv="param1"
  • call sys_getcommandLineArg(2,sargv) => sargv="param2"
  • call sys_getcommandLineArg(3,sargv) => sargv="param3"

Parsing command line parameters

The module fsystem also provides parsing capabilities for command line parameters using the routine sys_parseCommandLineArg. A call of the form

call sys_parseCommandLineArg ("--file=myfile.txt",soption,svalue)

returns

  • soption = "file"
  • svalue = "myfile.txt`

which is the most commonly used way how to use this technique. sys_parseCommandLineArg however provides some additional features that also detect the type of the command line parameter (returned in an optional variable iformat). A more detailed overview can be found in the file tutorial001f.f90.