MODFLOW 6  version 6.5.0.dev2
MODFLOW 6 Code Documentation
LongLineReader.f90
Go to the documentation of this file.
1 !> @brief This module contains the LongLineReaderType
2 !!
3 !! The LongLineReader is a utility for reading text lines
4 !! from mf6 input files. It calls u9rdcom (which calls
5 !! get_line) to read the first non-commented line of an
6 !! input file. The LongLineReader can emulate the Fortran
7 !! backspace command by calling the bkspc method, which stores
8 !! the current line in last_line, and will return last_line
9 !! upon the next call to rdcom. The LongLineReader was
10 !! implemented to replace all Fortran backspace calls, due
11 !! to a bug in ifort and ifx that prevented the backspace
12 !! command from working properly with non-advancing IO.
13 !!
14 !<
16 
17  use, intrinsic :: iso_fortran_env, only: iostat_end
18  use kindmodule, only: i4b
19  use simmodule, only: store_error
20  use inputoutputmodule, only: u9rdcom
21 
22  implicit none
23 
24  private
25  public :: longlinereadertype
26 
27  !> @brief LongLineReaderType
28  !!
29  !! Object for reading input from mf6 input files
30  !!
31  !<
33 
34  character(len=:), allocatable :: line
35  character(len=:), allocatable :: last_line
36  integer(I4B) :: nbackspace = 0
37  integer(I4B) :: iostat = 0
38  integer(I4B) :: last_unit = 0
39 
40  contains
41 
42  procedure :: bkspc
43  procedure :: rdcom
44 
45  end type longlinereadertype
46 
47 contains
48 
49  !> @brief Return the first non-comment line
50  !!
51  !! Skip through any comments and return the first
52  !! non-commented line. If an end of file was
53  !! encountered previously, then return a blank line.
54  !! If a backspace was called prior to this call,
55  !! then do not read a new line and return last_line
56  !! instead.
57  !!
58  !<
59  subroutine rdcom(this, iu, iout, line, ierr)
60  class(longlinereadertype) :: this
61  integer(I4B), intent(in) :: iu
62  integer(I4B), intent(in) :: iout
63  character(len=:), intent(inout), allocatable :: line
64  integer(I4B), intent(inout) :: ierr
65 
66  ierr = 0
67 
68  ! If using this reader to read from a new file
69  ! then reset state
70  if (iu /= this%last_unit) then
71  this%nbackspace = 0
72  this%iostat = 0
73  end if
74 
75  if (this%nbackspace == 1) then
76  ! If backspace was called, then return last line
77  if (allocated(line)) deallocate (line)
78  allocate (character(len=len(this%last_line) + 1) :: line)
79  line(:) = this%last_line(:)
80  this%nbackspace = 0
81  else
82  ! if end of file was reached previously, then return a
83  ! blank line and return ierr as IOSTAT_END
84  if (this%iostat == iostat_end) then
85  line = ' '
86  ierr = iostat_end
87  else
88  call u9rdcom(iu, iout, line, ierr)
89  end if
90  this%last_line = line
91  this%iostat = ierr
92  end if
93  this%last_unit = iu
94  return
95  end subroutine rdcom
96 
97  !> @brief Emulate a Fortran backspace
98  !!
99  !! Emulate a fortran backspace call by storing
100  !! the current line in long_line
101  !!
102  !<
103  subroutine bkspc(this, iin)
104  class(longlinereadertype) :: this
105  integer(I4B), intent(in) :: iin
106  if (this%nbackspace > 0) then
107  call store_error( &
108  "Programming error in LongLineReaderType%bkspc(). Backspace &
109  & called more than once for an open file.", &
110  terminate=.true.)
111  else
112  this%nbackspace = 1
113  end if
114  return
115  end subroutine bkspc
116 
117 end module longlinereadermodule
subroutine, public u9rdcom(iin, iout, line, ierr)
Read until non-comment line found and then return line.
This module defines variable data types.
Definition: kind.f90:8
This module contains the LongLineReaderType.
subroutine bkspc(this, iin)
Emulate a Fortran backspace.
subroutine rdcom(this, iu, iout, line, ierr)
Return the first non-comment line.
This module contains simulation methods.
Definition: Sim.f90:10
subroutine, public store_error(msg, terminate)
Store an error message.
Definition: Sim.f90:92