ncurses

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

A public-domain Fortran 2003 interface to the ncurses library can be used to output formatted text to the terminal emulator. 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 -I. -L/usr/local/lib/ -Wl,-rpath=/usr/local/lib/gcc7/ -o hello hello.f90 ncurses.o macros.o -lncurses

We can set the environment variable LD_LIBRARY_PATH instead of using a compiler flag for the shared library path:

$ setenv LD_LIBRARY_PATH /usr/local/lib/
$ gfortran7 -I. -Wl,-rpath=/usr/local/lib/gcc7/ -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

all: $(TARGET)

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

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

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

.PHONY: clean

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