MODFLOW 6  version 6.9.0.dev0
USGS Modular Hydrologic Model
blockparsermodule Module Reference

This module contains block parser methods. More...

Data Types

type  blockparsertype
 

Functions/Subroutines

subroutine initialize (this, inunit, iout)
 @ brief Initialize the block parser More...
 
subroutine clear (this)
 @ brief Close the block parser More...
 
subroutine getblock (this, blockName, isFound, ierr, supportOpenClose, blockRequired, blockNameFound)
 @ brief Get block More...
 
subroutine getnextline (this, endOfBlock)
 @ brief Get the next line More...
 
integer(i4b) function getinteger (this)
 @ brief Get a integer More...
 
integer(i4b) function getlinesread (this)
 @ brief Get the number of lines read More...
 
real(dp) function getdouble (this)
 @ brief Get a double precision real More...
 
subroutine trygetdouble (this, r, success)
 
subroutine trygetinteger (this, i, success)
 
subroutine readscalarerror (this, vartype)
 @ brief Issue a read error More...
 
subroutine getstring (this, string, convertToUpper)
 @ brief Get a string More...
 
subroutine getstringcaps (this, string)
 @ brief Get an upper case string More...
 
subroutine getremainingline (this, line)
 @ brief Get the rest of a line More...
 
subroutine terminateblock (this)
 @ brief Ensure that the block is closed More...
 
subroutine getcellid (this, ndim, cellid, flag_string)
 @ brief Get a cellid More...
 
subroutine getcurrentline (this, line)
 @ brief Get the current line More...
 
subroutine storeerrorunit (this, terminate)
 @ brief Store the unit number More...
 
integer(i4b) function getunit (this)
 @ brief Get the unit number More...
 
subroutine devopt (this)
 @ brief Disable development option in release mode More...
 
subroutine, public uget_block (line_reader, iin, iout, ctag, ierr, isfound, lloc, line, iuext, blockRequired, supportopenclose)
 Find a block in a file. More...
 
subroutine, public uget_any_block (line_reader, iin, iout, isfound, lloc, line, ctagfound, iuext)
 Find the next block in a file. More...
 
subroutine, public uterminate_block (iin, iout, key, ctag, lloc, line, ierr, iuext)
 Evaluate if the end of a block has been found. More...
 

Detailed Description

This module contains the generic block parser type and methods that are used to parse MODFLOW 6 block data.

Function/Subroutine Documentation

◆ clear()

subroutine blockparsermodule::clear ( class(blockparsertype), intent(inout)  this)
private

Method to clear the block parser, which closes file(s) and clears member variables.

Parameters
[in,out]thisBlockParserType object

Definition at line 85 of file BlockParser.f90.

86  ! -- dummy variables
87  class(BlockParserType), intent(inout) :: this !< BlockParserType object
88  ! -- local variables
89  logical :: lop
90  !
91  ! Close any connected files
92  if (this%inunit > 0) then
93  inquire (unit=this%inunit, opened=lop)
94  if (lop) then
95  close (this%inunit)
96  end if
97  end if
98  !
99  if (this%iuext /= this%inunit .and. this%iuext > 0) then
100  inquire (unit=this%iuext, opened=lop)
101  if (lop) then
102  close (this%iuext)
103  end if
104  end if
105  !
106  ! Clear all member variables
107  this%inunit = 0
108  this%iuext = 0
109  this%iuactive = 0
110  this%iout = 0
111  this%lloc = 0
112  this%linesRead = 0
113  this%blockName = ''
114  this%line = ''
115  deallocate (this%line)

◆ devopt()

subroutine blockparsermodule::devopt ( class(blockparsertype), intent(inout)  this)
private

Terminate with an error if in release mode (IDEVELOPMODE = 0). Enables options for development and testing while disabling for public release.

Definition at line 570 of file BlockParser.f90.

571  ! -- dummy variables
572  class(BlockParserType), intent(inout) :: this
573  !
574  errmsg = "Invalid keyword '"//trim(this%laststring)// &
575  "' detected in block '"//trim(this%blockname)//"'."
576  call developmode(errmsg, this%iuext)
Here is the call graph for this function:

◆ getblock()

subroutine blockparsermodule::getblock ( class(blockparsertype), intent(inout)  this,
character(len=*), intent(in)  blockName,
logical, intent(out)  isFound,
integer(i4b), intent(out)  ierr,
logical, intent(in), optional  supportOpenClose,
logical, intent(in), optional  blockRequired,
character(len=*), intent(inout), optional  blockNameFound 
)
private

Method to get the block from a file. The file is read until the blockname is found.

Parameters
[in,out]thisBlockParserType object
[in]blocknameblock name to search for
[out]isfoundboolean indicating if the block name was found
[out]ierrreturn error code, 0 indicates block was found
[in]supportopencloseboolean indicating if the block supports open/close, default false
[in]blockrequiredboolean indicating if the block is required, default true
[in,out]blocknamefoundoptional return value of block name found

Definition at line 124 of file BlockParser.f90.

126  ! -- dummy variables
127  class(BlockParserType), intent(inout) :: this !< BlockParserType object
128  character(len=*), intent(in) :: blockName !< block name to search for
129  logical, intent(out) :: isFound !< boolean indicating if the block name was found
130  integer(I4B), intent(out) :: ierr !< return error code, 0 indicates block was found
131  logical, intent(in), optional :: supportOpenClose !< boolean indicating if the block supports open/close, default false
132  logical, intent(in), optional :: blockRequired !< boolean indicating if the block is required, default true
133  character(len=*), intent(inout), optional :: blockNameFound !< optional return value of block name found
134  ! -- local variables
135  logical :: continueRead
136  logical :: supportOpenCloseLocal
137  logical :: blockRequiredLocal
138  !
139  ! -- process optional variables
140  if (present(supportopenclose)) then
141  supportopencloselocal = supportopenclose
142  else
143  supportopencloselocal = .false.
144  end if
145  !
146  if (present(blockrequired)) then
147  blockrequiredlocal = blockrequired
148  else
149  blockrequiredlocal = .true.
150  end if
151  continueread = blockrequiredlocal
152  this%blockName = blockname
153  this%blockNameFound = ''
154  !
155  if (blockname == '*') then
156  call uget_any_block(this%line_reader, this%inunit, this%iout, &
157  isfound, this%lloc, this%line, blocknamefound, &
158  this%iuext)
159  if (isfound) then
160  this%blockNameFound = blocknamefound
161  ierr = 0
162  else
163  ierr = 1
164  end if
165  else
166  call uget_block(this%line_reader, this%inunit, this%iout, &
167  this%blockName, ierr, isfound, &
168  this%lloc, this%line, this%iuext, continueread, &
169  supportopencloselocal)
170  if (isfound) this%blockNameFound = this%blockName
171  end if
172  this%iuactive = this%iuext
173  this%linesRead = 0
Here is the call graph for this function:

◆ getcellid()

subroutine blockparsermodule::getcellid ( class(blockparsertype), intent(inout)  this,
integer(i4b), intent(in)  ndim,
character(len=*), intent(out)  cellid,
logical, intent(in), optional  flag_string 
)
private

Method to get a cellid from a line.

Parameters
[in,out]thisBlockParserType object
[in]ndimnumber of dimensions (1, 2, or 3)
[out]cellidcell =id
[in]flag_stringboolean indicating id cellid is a string

Definition at line 467 of file BlockParser.f90.

468  ! -- dummy variables
469  class(BlockParserType), intent(inout) :: this !< BlockParserType object
470  integer(I4B), intent(in) :: ndim !< number of dimensions (1, 2, or 3)
471  character(len=*), intent(out) :: cellid !< cell =id
472  logical, optional, intent(in) :: flag_string !< boolean indicating id cellid is a string
473  ! -- local variables
474  integer(I4B) :: i
475  integer(I4B) :: j
476  integer(I4B) :: lloc
477  integer(I4B) :: istart
478  integer(I4B) :: istop
479  integer(I4B) :: ival
480  integer(I4B) :: istat
481  real(DP) :: rval
482  character(len=10) :: cint
483  character(len=100) :: firsttoken
484  !
485  ! -- process optional variables
486  if (present(flag_string)) then
487  lloc = this%lloc
488  call urword(this%line, lloc, istart, istop, 0, ival, rval, this%iout, &
489  this%iuext)
490  firsttoken = this%line(istart:istop)
491  read (firsttoken, *, iostat=istat) ival
492  if (istat > 0) then
493  call upcase(firsttoken)
494  cellid = firsttoken
495  return
496  end if
497  end if
498  !
499  cellid = ''
500  do i = 1, ndim
501  j = this%GetInteger()
502  write (cint, '(i0)') j
503  if (i == 1) then
504  cellid = cint
505  else
506  cellid = trim(cellid)//' '//cint
507  end if
508  end do
Here is the call graph for this function:

◆ getcurrentline()

subroutine blockparsermodule::getcurrentline ( class(blockparsertype), intent(inout)  this,
character(len=*), intent(out)  line 
)
private

Method to get the current line.

Parameters
[in,out]thisBlockParserType object
[out]linecurrent line

Definition at line 516 of file BlockParser.f90.

517  ! -- dummy variables
518  class(BlockParserType), intent(inout) :: this !< BlockParserType object
519  character(len=*), intent(out) :: line !< current line
520  !
521  ! -- get the current line
522  line = this%line

◆ getdouble()

real(dp) function blockparsermodule::getdouble ( class(blockparsertype), intent(inout)  this)
private

Function to get adouble precision floating point number from the current line.

Returns
double precision real variable
Parameters
[in,out]thisBlockParserType object

Definition at line 282 of file BlockParser.f90.

283  ! -- return variable
284  real(DP) :: r !< double precision real variable
285  ! -- dummy variables
286  class(BlockParserType), intent(inout) :: this !< BlockParserType object
287  ! -- local variables
288  integer(I4B) :: istart
289  integer(I4B) :: istop
290  integer(I4B) :: ival
291  !
292  ! -- get double precision real using urword
293  call urword(this%line, this%lloc, istart, istop, 3, ival, r, &
294  this%iout, this%iuext)
295  !
296  ! -- Make sure variable was read before end of line
297  if (istart == istop .and. istop == len(this%line)) then
298  call this%ReadScalarError('DOUBLE PRECISION')
299  end if
300 
Here is the call graph for this function:

◆ getinteger()

integer(i4b) function blockparsermodule::getinteger ( class(blockparsertype), intent(inout)  this)
private

Function to get a integer from the current line.

Returns
integer variable
Parameters
[in,out]thisBlockParserType object

Definition at line 241 of file BlockParser.f90.

242  ! -- return variable
243  integer(I4B) :: i !< integer variable
244  ! -- dummy variables
245  class(BlockParserType), intent(inout) :: this !< BlockParserType object
246  ! -- local variables
247  integer(I4B) :: istart
248  integer(I4B) :: istop
249  real(DP) :: rval
250  !
251  ! -- get integer using urword
252  call urword(this%line, this%lloc, istart, istop, 2, i, rval, &
253  this%iout, this%iuext)
254  !
255  ! -- Make sure variable was read before end of line
256  if (istart == istop .and. istop == len(this%line)) then
257  call this%ReadScalarError('INTEGER')
258  end if
Here is the call graph for this function:

◆ getlinesread()

integer(i4b) function blockparsermodule::getlinesread ( class(blockparsertype), intent(inout)  this)
private

Function to get the number of lines read from the current block.

Returns
number of lines read
Parameters
[in,out]thisBlockParserType object

Definition at line 266 of file BlockParser.f90.

267  ! -- return variable
268  integer(I4B) :: nlines !< number of lines read
269  ! -- dummy variable
270  class(BlockParserType), intent(inout) :: this !< BlockParserType object
271  !
272  ! -- number of lines read
273  nlines = this%linesRead

◆ getnextline()

subroutine blockparsermodule::getnextline ( class(blockparsertype), intent(inout)  this,
logical, intent(out)  endOfBlock 
)
private

Method to get the next line from a file.

Parameters
[in,out]thisBlockParserType object
[out]endofblockboolean indicating if the end of the block was read

Definition at line 181 of file BlockParser.f90.

182  ! -- dummy variables
183  class(BlockParserType), intent(inout) :: this !< BlockParserType object
184  logical, intent(out) :: endOfBlock !< boolean indicating if the end of the block was read
185  ! -- local variables
186  integer(I4B) :: ierr
187  integer(I4B) :: ival
188  integer(I4B) :: istart
189  integer(I4B) :: istop
190  real(DP) :: rval
191  character(len=10) :: key
192  logical :: lineread
193  !
194  ! -- initialize local variables
195  endofblock = .false.
196  ierr = 0
197  lineread = .false.
198  !
199  ! -- read next line
200  loop1: do
201  if (lineread) exit loop1
202  call this%line_reader%rdcom(this%iuext, this%iout, this%line, ierr)
203  this%lloc = 1
204  call urword(this%line, this%lloc, istart, istop, 0, ival, rval, &
205  this%iout, this%iuext)
206  key = this%line(istart:istop)
207  call upcase(key)
208  if (key == 'END' .or. key == 'BEGIN') then
209  call uterminate_block(this%inunit, this%iout, key, &
210  this%blockNameFound, this%lloc, this%line, &
211  ierr, this%iuext)
212  this%iuactive = this%iuext
213  endofblock = .true.
214  lineread = .true.
215  elseif (key == '') then
216  ! End of file reached.
217  ! If this is an OPEN/CLOSE file, close the file and read the next
218  ! line from this%inunit.
219  if (this%iuext /= this%inunit) then
220  close (this%iuext)
221  this%iuext = this%inunit
222  this%iuactive = this%inunit
223  else
224  errmsg = 'Unexpected end of file reached.'
225  call store_error(errmsg)
226  call this%StoreErrorUnit()
227  end if
228  else
229  this%lloc = 1
230  this%linesRead = this%linesRead + 1
231  lineread = .true.
232  end if
233  end do loop1
Here is the call graph for this function:

◆ getremainingline()

subroutine blockparsermodule::getremainingline ( class(blockparsertype), intent(inout)  this,
character(len=:), intent(out), allocatable  line 
)
private

Method to get the rest of the line from the current line.

Parameters
[in,out]thisBlockParserType object
[out]lineremainder of the line

Definition at line 424 of file BlockParser.f90.

425  ! -- dummy variables
426  class(BlockParserType), intent(inout) :: this !< BlockParserType object
427  character(len=:), allocatable, intent(out) :: line !< remainder of the line
428  ! -- local variables
429  integer(I4B) :: lastpos
430  integer(I4B) :: newlinelen
431  !
432  ! -- get the rest of the line
433  lastpos = len_trim(this%line)
434  newlinelen = lastpos - this%lloc + 2
435  newlinelen = max(newlinelen, 1)
436  allocate (character(len=newlinelen) :: line)
437  line(:) = this%line(this%lloc:lastpos)
438  line(newlinelen:newlinelen) = ' '

◆ getstring()

subroutine blockparsermodule::getstring ( class(blockparsertype), intent(inout)  this,
character(len=*), intent(out)  string,
logical, intent(in), optional  convertToUpper 
)
private

Method to get a string from the current line and optionally convert it to upper case.

Parameters
[in,out]thisBlockParserType object
[in]converttoupperboolean indicating if the string should be converted to upper case, default false

Definition at line 375 of file BlockParser.f90.

376  ! -- dummy variables
377  class(BlockParserType), intent(inout) :: this !< BlockParserType object
378  character(len=*), intent(out) :: string !< string
379  logical, optional, intent(in) :: convertToUpper !< boolean indicating if the string should be converted to upper case, default false
380  ! -- local variables
381  integer(I4B) :: istart
382  integer(I4B) :: istop
383  integer(I4B) :: ival
384  integer(I4B) :: ncode
385  real(DP) :: rval
386  !
387  ! -- process optional variables
388  if (present(converttoupper)) then
389  if (converttoupper) then
390  ncode = 1
391  else
392  ncode = 0
393  end if
394  else
395  ncode = 0
396  end if
397  !
398  call urword(this%line, this%lloc, istart, istop, ncode, &
399  ival, rval, this%iout, this%iuext)
400  string = this%line(istart:istop)
401  this%laststring = this%line(istart:istop)
Here is the call graph for this function:

◆ getstringcaps()

subroutine blockparsermodule::getstringcaps ( class(blockparsertype), intent(inout)  this,
character(len=*), intent(out)  string 
)
private

Method to get a string from the current line and convert it to upper case.

Parameters
[in,out]thisBlockParserType object
[out]stringupper case string

Definition at line 410 of file BlockParser.f90.

411  ! -- dummy variables
412  class(BlockParserType), intent(inout) :: this !< BlockParserType object
413  character(len=*), intent(out) :: string !< upper case string
414  !
415  ! -- call base GetString method with convertToUpper variable
416  call this%GetString(string, converttoupper=.true.)

◆ getunit()

integer(i4b) function blockparsermodule::getunit ( class(blockparsertype), intent(inout)  this)
private

Function to get the unit number for the block parser.

Returns
unit number for the block parser
Parameters
[in,out]thisBlockParserType object

Definition at line 554 of file BlockParser.f90.

555  ! -- return variable
556  integer(I4B) :: i !< unit number for the block parser
557  ! -- dummy variables
558  class(BlockParserType), intent(inout) :: this !< BlockParserType object
559  !
560  ! -- block parser unit number
561  i = this%iuext

◆ initialize()

subroutine blockparsermodule::initialize ( class(blockparsertype), intent(inout)  this,
integer(i4b), intent(in)  inunit,
integer(i4b), intent(in)  iout 
)
private

Method to initialize the block parser.

Parameters
[in,out]thisBlockParserType object
[in]inunitinput file unit number
[in]ioutlisting file unit number

Definition at line 64 of file BlockParser.f90.

65  ! -- dummy variables
66  class(BlockParserType), intent(inout) :: this !< BlockParserType object
67  integer(I4B), intent(in) :: inunit !< input file unit number
68  integer(I4B), intent(in) :: iout !< listing file unit number
69  !
70  ! -- initialize values
71  this%inunit = inunit
72  this%iuext = inunit
73  this%iuactive = inunit
74  this%iout = iout
75  this%blockName = ''
76  this%linesRead = 0

◆ readscalarerror()

subroutine blockparsermodule::readscalarerror ( class(blockparsertype), intent(inout)  this,
character(len=*), intent(in)  vartype 
)
private

Method to issue an unable to read error.

Parameters
[in,out]thisBlockParserType object
[in]vartypestring of variable type

Definition at line 348 of file BlockParser.f90.

349  ! -- dummy variables
350  class(BlockParserType), intent(inout) :: this !< BlockParserType object
351  character(len=*), intent(in) :: vartype !< string of variable type
352  ! -- local variables
353  character(len=MAXCHARLEN - 100) :: linetemp
354  !
355  ! -- use linetemp as line may be longer than MAXCHARLEN
356  linetemp = this%line
357  !
358  ! -- write the message
359  write (errmsg, '(3a)') 'Error in block ', trim(this%blockName), '.'
360  write (errmsg, '(4a)') &
361  trim(errmsg), ' Could not read variable of type ', trim(vartype), &
362  " from the following line: '"
363  write (errmsg, '(3a)') &
364  trim(errmsg), trim(adjustl(this%line)), "'."
365  call store_error(errmsg)
366  call this%StoreErrorUnit()
Here is the call graph for this function:

◆ storeerrorunit()

subroutine blockparsermodule::storeerrorunit ( class(blockparsertype), intent(inout)  this,
logical, intent(in), optional  terminate 
)
private

Method to store the unit number for the file that caused a read error. Default is to terminate the simulation when this method is called.

Parameters
[in,out]thisBlockParserType object
[in]terminateboolean indicating if the simulation should be terminated

Definition at line 531 of file BlockParser.f90.

532  ! -- dummy variable
533  class(BlockParserType), intent(inout) :: this !< BlockParserType object
534  logical, intent(in), optional :: terminate !< boolean indicating if the simulation should be terminated
535  ! -- local variables
536  logical :: lterminate
537  !
538  ! -- process optional variables
539  if (present(terminate)) then
540  lterminate = terminate
541  else
542  lterminate = .true.
543  end if
544  !
545  ! -- store error unit
546  call store_error_unit(this%iuext, terminate=lterminate)
Here is the call graph for this function:

◆ terminateblock()

subroutine blockparsermodule::terminateblock ( class(blockparsertype), intent(inout)  this)
private

Method to ensure that the block is closed with an "end".

Parameters
[in,out]thisBlockParserType object

Definition at line 446 of file BlockParser.f90.

447  ! -- dummy variables
448  class(BlockParserType), intent(inout) :: this !< BlockParserType object
449  ! -- local variables
450  logical :: endofblock
451  !
452  ! -- look for block termination
453  call this%GetNextLine(endofblock)
454  if (.not. endofblock) then
455  errmsg = "LOOKING FOR 'END "//trim(this%blockname)// &
456  "'. FOUND: "//"'"//trim(this%line)//"'."
457  call store_error(errmsg)
458  call this%StoreErrorUnit()
459  end if
Here is the call graph for this function:

◆ trygetdouble()

subroutine blockparsermodule::trygetdouble ( class(blockparsertype), intent(inout)  this,
real(dp), intent(inout)  r,
logical(lgp), intent(inout)  success 
)
private
Parameters
[in,out]thisBlockParserType object
[in,out]rdouble precision real variable
[in,out]successwhether parsing was successful

Definition at line 303 of file BlockParser.f90.

304  ! -- dummy variables
305  class(BlockParserType), intent(inout) :: this !< BlockParserType object
306  real(DP), intent(inout) :: r !< double precision real variable
307  logical(LGP), intent(inout) :: success !< whether parsing was successful
308  ! -- local variables
309  integer(I4B) :: istart
310  integer(I4B) :: istop
311  integer(I4B) :: ival
312 
313  call urword(this%line, this%lloc, istart, istop, 3, ival, r, &
314  this%iout, this%iuext)
315 
316  success = .true.
317  if (istart == istop .and. istop == len(this%line)) then
318  success = .false.
319  end if
320 
Here is the call graph for this function:

◆ trygetinteger()

subroutine blockparsermodule::trygetinteger ( class(blockparsertype), intent(inout)  this,
integer(i4b), intent(inout)  i,
logical(lgp), intent(inout)  success 
)
private
Parameters
[in,out]thisBlockParserType object
[in,out]iinteger variable
[in,out]successwhether parsing was successful

Definition at line 323 of file BlockParser.f90.

324  ! -- dummy variables
325  class(BlockParserType), intent(inout) :: this !< BlockParserType object
326  integer(I4B), intent(inout) :: i !< integer variable
327  logical(LGP), intent(inout) :: success !< whether parsing was successful
328  ! -- local variables
329  integer(I4B) :: istart
330  integer(I4B) :: istop
331  real(DP) :: rval
332 
333  call urword(this%line, this%lloc, istart, istop, 2, i, rval, &
334  this%iout, this%iuext)
335 
336  success = .true.
337  if (istart == istop .and. istop == len(this%line)) then
338  success = .false.
339  end if
340 
Here is the call graph for this function:

◆ uget_any_block()

subroutine, public blockparsermodule::uget_any_block ( type(longlinereadertype), intent(inout)  line_reader,
integer(i4b), intent(in)  iin,
integer(i4b), intent(in)  iout,
logical, intent(inout)  isfound,
integer(i4b), intent(inout)  lloc,
character(len=:), intent(inout), allocatable  line,
character(len=*), intent(out)  ctagfound,
integer(i4b), intent(inout)  iuext 
)

Subroutine to read from a file until next block is found. Return isfound with true, if found, and return the block name.

Parameters
[in]iinfile unit number
[in]ioutoutput listing file unit
[in,out]isfoundboolean indicating if a block was found
[in,out]llocposition in line
[out]ctagfoundblock name
[in,out]iuextexternal file unit number

Definition at line 699 of file BlockParser.f90.

701  implicit none
702  ! -- dummy variables
703  type(LongLineReaderType), intent(inout) :: line_reader
704  integer(I4B), intent(in) :: iin !< file unit number
705  integer(I4B), intent(in) :: iout !< output listing file unit
706  logical, intent(inout) :: isfound !< boolean indicating if a block was found
707  integer(I4B), intent(inout) :: lloc !< position in line
708  character(len=:), allocatable, intent(inout) :: line !< line
709  character(len=*), intent(out) :: ctagfound !< block name
710  integer(I4B), intent(inout) :: iuext !< external file unit number
711  ! -- local variables
712  integer(I4B) :: ierr, istart, istop
713  integer(I4B) :: ival, lloc2
714  real(DP) :: rval
715  character(len=100) :: ermsg
716  character(len=:), allocatable :: line2
717  character(len=LINELENGTH) :: fname
718  !
719  ! -- code
720  isfound = .false.
721  ctagfound = ''
722  iuext = iin
723  do
724  lloc = 1
725  call line_reader%rdcom(iin, iout, line, ierr)
726  if (ierr < 0) exit
727  call urword(line, lloc, istart, istop, 1, ival, rval, iin, iout)
728  if (line(istart:istop) == 'BEGIN') then
729  call urword(line, lloc, istart, istop, 1, ival, rval, iin, iout)
730  if (line(istart:istop) /= '') then
731  isfound = .true.
732  ctagfound = line(istart:istop)
733  call line_reader%rdcom(iin, iout, line2, ierr)
734  if (ierr < 0) exit
735  lloc2 = 1
736  call urword(line2, lloc2, istart, istop, 1, ival, rval, iout, iin)
737  if (line2(istart:istop) == 'OPEN/CLOSE') then
738  iuext = io_getunit()
739  call urword(line2, lloc2, istart, istop, 0, ival, rval, iout, iin)
740  fname = line2(istart:istop)
741  call openfile(iuext, iout, fname, 'OPEN/CLOSE')
742  else
743  call line_reader%bkspc(iin)
744  end if
745  else
746  ermsg = 'Block name missing in file.'
747  call store_error(ermsg)
748  call store_error_unit(iin)
749  end if
750  exit
751  end if
752  end do
Here is the call graph for this function:
Here is the caller graph for this function:

◆ uget_block()

subroutine, public blockparsermodule::uget_block ( type(longlinereadertype), intent(inout)  line_reader,
integer(i4b), intent(in)  iin,
integer(i4b), intent(in)  iout,
character(len=*), intent(in)  ctag,
integer(i4b), intent(out)  ierr,
logical, intent(inout)  isfound,
integer(i4b), intent(inout)  lloc,
character(len=:), intent(inout), allocatable  line,
integer(i4b), intent(inout)  iuext,
logical, intent(in), optional  blockRequired,
logical, intent(in), optional  supportopenclose 
)

Subroutine to read from a file until the tag (ctag) for a block is is found. Return isfound with true, if found.

Parameters
[in]iinfile unit
[in]ioutoutput listing file unit
[in]ctagblock tag
[out]ierrerror
[in,out]isfoundboolean indicating if the block was found
[in,out]llocposition in line
[in,out]iuextexternal file unit number
[in]blockrequiredboolean indicating if the block is required
[in]supportopencloseboolean indicating if the block supports open/close

Definition at line 586 of file BlockParser.f90.

588  implicit none
589  ! -- dummy variables
590  type(LongLineReaderType), intent(inout) :: line_reader
591  integer(I4B), intent(in) :: iin !< file unit
592  integer(I4B), intent(in) :: iout !< output listing file unit
593  character(len=*), intent(in) :: ctag !< block tag
594  integer(I4B), intent(out) :: ierr !< error
595  logical, intent(inout) :: isfound !< boolean indicating if the block was found
596  integer(I4B), intent(inout) :: lloc !< position in line
597  character(len=:), allocatable, intent(inout) :: line !< line
598  integer(I4B), intent(inout) :: iuext !< external file unit number
599  logical, optional, intent(in) :: blockRequired !< boolean indicating if the block is required
600  logical, optional, intent(in) :: supportopenclose !< boolean indicating if the block supports open/close
601  ! -- local variables
602  integer(I4B) :: istart
603  integer(I4B) :: istop
604  integer(I4B) :: ival
605  integer(I4B) :: lloc2
606  real(DP) :: rval
607  character(len=:), allocatable :: line2
608  character(len=LINELENGTH) :: fname
609  character(len=MAXCHARLEN) :: ermsg
610  logical :: supportoc, blockRequiredLocal
611  !
612  ! -- code
613  if (present(blockrequired)) then
614  blockrequiredlocal = blockrequired
615  else
616  blockrequiredlocal = .true.
617  end if
618  supportoc = .false.
619  if (present(supportopenclose)) then
620  supportoc = supportopenclose
621  end if
622  iuext = iin
623  isfound = .false.
624  mainloop: do
625  lloc = 1
626  call line_reader%rdcom(iin, iout, line, ierr)
627  if (ierr < 0) then
628  if (blockrequiredlocal) then
629  ermsg = 'Required block "'//trim(ctag)// &
630  '" not found. Found end of file instead.'
631  call store_error(ermsg)
632  call store_error_unit(iuext)
633  end if
634  ! block not found so exit
635  exit
636  end if
637  call urword(line, lloc, istart, istop, 1, ival, rval, iin, iout)
638  if (line(istart:istop) == 'BEGIN') then
639  call urword(line, lloc, istart, istop, 1, ival, rval, iin, iout)
640  if (line(istart:istop) == ctag) then
641  isfound = .true.
642  if (supportoc) then
643  ! Look for OPEN/CLOSE on 1st line after line starting with BEGIN
644  call line_reader%rdcom(iin, iout, line2, ierr)
645  if (ierr < 0) exit
646  lloc2 = 1
647  call urword(line2, lloc2, istart, istop, 1, ival, rval, iin, iout)
648  if (line2(istart:istop) == 'OPEN/CLOSE') then
649  ! -- Get filename and preserve case
650  call urword(line2, lloc2, istart, istop, 0, ival, rval, iin, iout)
651  fname = line2(istart:istop)
652  ! If line contains '(BINARY)' or 'SFAC', handle this block elsewhere
653  chk: do
654  call urword(line2, lloc2, istart, istop, 1, ival, rval, iin, iout)
655  if (line2(istart:istop) == '') exit chk
656  if (line2(istart:istop) == '(BINARY)' .or. &
657  line2(istart:istop) == 'SFAC') then
658  call line_reader%bkspc(iin)
659  exit mainloop
660  end if
661  end do chk
662  iuext = io_getunit()
663  call openfile(iuext, iout, fname, 'OPEN/CLOSE')
664  else
665  call line_reader%bkspc(iin)
666  end if
667  end if
668  else
669  if (blockrequiredlocal) then
670  ermsg = 'Error: Required block "'//trim(ctag)// &
671  '" not found. Found block "'//line(istart:istop)// &
672  '" instead.'
673  call store_error(ermsg)
674  call store_error_unit(iuext)
675  else
676  call line_reader%bkspc(iin)
677  end if
678  end if
679  exit mainloop
680  else if (line(istart:istop) == 'END') then
681  call urword(line, lloc, istart, istop, 1, ival, rval, iin, iout)
682  if (line(istart:istop) == ctag) then
683  ermsg = 'Error: Looking for BEGIN '//trim(ctag)// &
684  ' but found END '//line(istart:istop)// &
685  ' instead.'
686  call store_error(ermsg)
687  call store_error_unit(iuext)
688  end if
689  end if
690  end do mainloop
Here is the call graph for this function:
Here is the caller graph for this function:

◆ uterminate_block()

subroutine, public blockparsermodule::uterminate_block ( integer(i4b), intent(in)  iin,
integer(i4b), intent(in)  iout,
character(len=*), intent(in)  key,
character(len=*), intent(in)  ctag,
integer(i4b), intent(inout)  lloc,
character(len=*), intent(inout)  line,
integer(i4b), intent(inout)  ierr,
integer(i4b), intent(inout)  iuext 
)

Subroutine to evaluate if the end of a block has been found. Abnormal termination if 'begin' is found or if 'end' encountered with incorrect tag.

Parameters
[in]iinfile unit number
[in]ioutoutput listing file unit number
[in]keykeyword in block
[in]ctagblock name
[in,out]llocposition in line
[in,out]ierrerror
[in,out]iuextexternal file unit number

Definition at line 762 of file BlockParser.f90.

763  implicit none
764  ! -- dummy variables
765  integer(I4B), intent(in) :: iin !< file unit number
766  integer(I4B), intent(in) :: iout !< output listing file unit number
767  character(len=*), intent(in) :: key !< keyword in block
768  character(len=*), intent(in) :: ctag !< block name
769  integer(I4B), intent(inout) :: lloc !< position in line
770  character(len=*), intent(inout) :: line !< line
771  integer(I4B), intent(inout) :: ierr !< error
772  integer(I4B), intent(inout) :: iuext !< external file unit number
773  ! -- local variables
774  character(len=LENBIGLINE) :: ermsg
775  integer(I4B) :: istart
776  integer(I4B) :: istop
777  integer(I4B) :: ival
778  real(DP) :: rval
779  ! -- format
780 1 format('ERROR. "', a, '" DETECTED WITHOUT "', a, '". ', '"END', 1x, a, &
781  '" MUST BE USED TO END ', a, '.')
782 2 format('ERROR. "', a, '" DETECTED BEFORE "END', 1x, a, '". ', '"END', 1x, a, &
783  '" MUST BE USED TO END ', a, '.')
784  !
785  ! -- code
786  ierr = 1
787  select case (key)
788  case ('END')
789  call urword(line, lloc, istart, istop, 1, ival, rval, iout, iin)
790  if (line(istart:istop) /= ctag) then
791  write (ermsg, 1) trim(key), trim(ctag), trim(ctag), trim(ctag)
792  call store_error(ermsg)
793  call store_error_unit(iin)
794  else
795  ierr = 0
796  if (iuext /= iin) then
797  ! -- close external file
798  close (iuext)
799  iuext = iin
800  end if
801  end if
802  case ('BEGIN')
803  write (ermsg, 2) trim(key), trim(ctag), trim(ctag), trim(ctag)
804  call store_error(ermsg)
805  call store_error_unit(iin)
806  end select
Here is the call graph for this function:
Here is the caller graph for this function: