ncurses

Fortran and ncurses
Fig. 1: Output of the example ncurses program

A Fortran 2003 interface to the ncurses library can be used to output formatted text to the terminal emulator. It is public domain, but does not feature Unicode support nor forms. Only two files are needed to call ncurses from Fortran:

Both files, including some examples, are also included in the archive ncf.tgz (mirror).

! hello.f90
program main
    use :: ncurses                                      ! Load interface to C library.
    implicit none
    integer :: e, k

    stdscr = initscr()                                  ! Start curses mode.

    e = curs_set(0)                                     ! Disable the cursor.
    e = start_color()                                   ! Start color.

    e = init_pair(1 _c_short, COLOR_GREEN, COLOR_BLACK) ! Initialize colors.
    e = attron(COLOR_PAIR(1))                           ! Enable attribute.
    e = addstr('Hello, ncurses!' // c_null_char)        ! Print the string.
    e = attroff(COLOR_PAIR(1))                          ! Disable attribute.

    e = refresh()                                       ! Update the real screen.
    k = getch()                                         ! Wait for a user keystroke.
    e = endwin()                                        ! End curses mode.
end program main

Compiling ncurses with GCC

You can compile the ncurses example with the GNU Compiler Collection:

$ gcc7 -c macros.c
$ gfortran7 -c ncurses.f90
$ gfortran7 -Wl,-rpath=/usr/local/lib/gcc7/ -I. -L/usr/local/lib/ -o hello \
  hello.f90 ncurses.o macros.o -lncurses

The environment variable LD_LIBRARY_PATH can be used to avoid the additional compiler flag for the shared library path:

$ setenv LD_LIBRARY_PATH /usr/local/lib/
$ gfortran7 -Wl,-rpath=/usr/local/lib/gcc7/ -I. -o hello hello.f90 ncurses.o macros.o \
  -lncurses

Compiling ncurses with LLVM

We create an object file for the auxiliary C routines named macros.o using Clang and then compile the ncurses C library bindings with Flang:

$ clang -c macros.c
$ flang -c ncurses.f90

The ncurses example can be build by linking macros.o and ncurses.o:

$ flang -o hello hello.f90 ncurses.o macros.o -lncurses

The compilation can be further automated by writing a proper Makefile:

CC = clang
FC = flang

CFLAGS  = -Wall
LDFLAGS = -lncurses
OBJ     = macros.o ncurses.o
SRC     = hello.f90
TARGET  = hello

.PHONY: all clean

all: $(TARGET)

$(TARGET): $(OBJ)
	$(FC) $(CFLAGS) -o $(TARGET) $(SRC) $(OBJ) $(LDFLAGS)

macros.o: macros.c
	$(CC) $(CFLAGS) -c macros.c

ncurses.o: ncurses.f90
	$(FC) $(CFLAGS) -c ncurses.f90

clean:
	rm $(TARGET) *.o *.mod

Please note the hard tabs in Makefile. The sources can be compiled with:

$ make

After compilation, we just execute our Fortran application:

$ ./hello