Re: writing output listing onto screen (or not) and onto file



bru wrote:
Tim Prince wrote:
Bernard Bru wrote:

Is it possible to simplify my code by putting only one
WRITE statement when I want to write output results onto screen
(or not) and onto a file :

Are you asking about facilities provided by most systems for redirecting
output sent to '*' (or, on many systems, unit 6 without an OPEN)?
For example, the tee program, or redirection using '>' on the command line?

Your solution is good for me in the case I want to have results only on
a file.

In the other case I want to have results at the same time on the screen
and on a file!!

Thanks for your ansver

Bernard Bru

Hi, Bernard.
Here is a module I wrote several years ago that I believe does what you
wish. You first write your output line to a character variable (or
array), then call either log_message, log_screen, or log_abort, with
the variable (or array) as the argument. log_message writes to the log
file only. log_screen writes to both the log file and the user's
standard output stream, and log_abort writes to both the log file and
the standard error stream, then aborts program execution.

--Peter

MODULE logfile_mod
! This module contains variables and routines related
! to the log file.
! P. Simon
! Revised: 9 April 2003
! Revised: 27 June 2003, to use FPP/CPP directives supporting
! multiple platforms.
! NOTE: THIS FILE MUST BE COMPILED USING THE FPP
! OR CPP PREPROCESSOR!

CHARACTER(len=132) :: logfile = 'arrayopt.log'
INTEGER, PARAMETER :: log_unit = 9 ! Unit number used
! ! for log messages.

INTERFACE log_message
MODULE PROCEDURE log_message_one
MODULE PROCEDURE log_message_mult
END INTERFACE

INTERFACE log_screen
MODULE PROCEDURE log_screen_one
MODULE PROCEDURE log_screen_mult
END INTERFACE

INTERFACE log_abort
MODULE PROCEDURE log_abort_one
MODULE PROCEDURE log_abort_mult
END INTERFACE

PRIVATE :: log_message_one
PRIVATE :: log_message_mult
PRIVATE :: log_screen_one
PRIVATE :: log_screen_mult
PRIVATE :: log_abort_one
PRIVATE :: log_abort_mult


CONTAINS

SUBROUTINE log_message_one(msg,flu***)
! If necessary, open the log file, append a message to the end.
! Flush the buffer if flu*** is present.

#ifdef _CVF
USE dfport, ONLY: flush ! Needed for Compaq Visual Fortran
#endif

IMPLICIT NONE
CHARACTER(len=*), INTENT(IN) :: msg
INTEGER, INTENT(IN), OPTIONAL :: flu***
LOGICAL :: op

INQUIRE(unit=log_unit, opened=op)
IF (.NOT. op) THEN
OPEN(log_unit, file = logfile, status = 'unknown')
END IF
WRITE(log_unit,'(a)') TRIM(msg)
IF (PRESENT(flu***)) CALL flush(log_unit) ! Flush output buffer.
RETURN
END SUBROUTINE log_message_one

SUBROUTINE log_message_mult(msg,flu***)
! If necessary, open the log file, append a message to the end.

#ifdef _CVF
USE dfport, ONLY: flush ! Needed for Compaq Visual Fortran
#endif

IMPLICIT NONE
CHARACTER(len=*), INTENT(IN) :: msg(:)
INTEGER, INTENT(IN), optional :: flu***
LOGICAL :: op
INTEGER :: i

INQUIRE(unit=log_unit, opened=op)
IF (.NOT. op) THEN
OPEN(log_unit, file = logfile, status = 'unknown')
END IF
DO i = 1, SIZE(msg)
WRITE(log_unit,'(a)') TRIM(msg(i))
END DO
IF (PRESENT(flu***)) CALL flush(log_unit) ! Flush output buffer.
RETURN
END SUBROUTINE log_message_mult

SUBROUTINE log_screen_one(msg,flu***)
! If necessary, open the log file, append message to the end.
! Flush the buffer if flu*** is present. Send message to the
! screen, also.

#ifdef _CVF
USE dfport, ONLY: flush ! Needed for Compaq Visual Fortran
#endif

IMPLICIT NONE
CHARACTER(len=*), INTENT(IN) :: msg
INTEGER, INTENT(IN), OPTIONAL :: flu***
LOGICAL :: op

INQUIRE(unit=log_unit, opened=op)
IF (.NOT. op) THEN
OPEN(log_unit, file = logfile, status = 'unknown')
END IF
WRITE(log_unit,'(a)') TRIM(msg)
WRITE(*,'(a)') TRIM(msg)
IF (PRESENT(flu***)) CALL flush(log_unit) ! Flush output buffer.
RETURN
END SUBROUTINE log_screen_one

SUBROUTINE log_screen_mult(msg,flu***)
! If necessary, open the log file, append a multiline
! message to the end. Send message to users screen, also.

#ifdef _CVF
USE dfport, ONLY: flush ! Needed for Compaq Visual Fortran
#endif

IMPLICIT NONE
CHARACTER(len=*), INTENT(IN) :: msg(:)
INTEGER, INTENT(IN), optional :: flu***
LOGICAL :: op
INTEGER :: i

INQUIRE(unit=log_unit, opened=op)
IF (.NOT. op) THEN
OPEN(log_unit, file = logfile, status = 'unknown')
END IF
DO i = 1, SIZE(msg)
WRITE(log_unit,'(a)') TRIM(msg(i))
WRITE(*,'(a)') TRIM(msg(i))
END DO
IF (PRESENT(flu***)) CALL flush(log_unit) ! Flush output buffer.
RETURN
END SUBROUTINE log_screen_mult

SUBROUTINE log_abort_one(msg)
! If necessary, open the log file, append message to the end,
! abort program execution, after closing the log file.

#ifdef _CVF
USE dfport, ONLY: abort ! Needed for Compaq Visual Fortran
#endif

IMPLICIT NONE
CHARACTER(len=*), INTENT(IN) :: msg
LOGICAL :: op
integer :: iunit

INQUIRE(unit=log_unit, opened=op)
IF (.NOT. op) THEN
OPEN(log_unit, file = logfile, status = 'unknown')
END IF
DO iunit = 0, log_unit, log_unit-iunit
WRITE(iunit,'(a)') ' '
WRITE(iunit,'(a)') ' '
WRITE(iunit,'(a)') '************* ABORTING EXECUTION
*************'
WRITE(iunit,'(a)') TRIM(msg)
WRITE(iunit,'(a)') '************* ABORTING EXECUTION
*************'
END DO
CLOSE(log_unit) ! Finish
CALL abort()
END SUBROUTINE log_abort_one


SUBROUTINE log_abort_mult(msg)
! If necessary, open the log file, append a multiline
! message to the end, then abort program execution,
! after closing the log file.

#ifdef _CVF
USE dfport, ONLY: abort ! Needed for Compaq Visual Fortran
#endif

IMPLICIT NONE
CHARACTER(len=*), INTENT(IN) :: msg(:)
LOGICAL :: op
INTEGER :: i, iunit

INQUIRE(unit=log_unit, opened=op)
IF (.NOT. op) THEN
OPEN(log_unit, file = logfile, status = 'unknown')
END IF
DO iunit = 0, log_unit, log_unit-iunit
WRITE(iunit,'(a)') ' '
WRITE(iunit,'(a)') ' '
WRITE(iunit,'(a)') '************* ABORTING EXECUTION
*************'
DO i = 1, SIZE(msg)
WRITE(iunit,'(a)') TRIM(msg(i))
END DO
WRITE(iunit,'(a)') '************* ABORTING EXECUTION
*************'
END DO
CLOSE(log_unit) ! Finish
CALL abort()
END SUBROUTINE log_abort_mult


END MODULE logfile_mod

.


Quantcast