MODFLOW 6  version 6.7.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 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 84 of file BlockParser.f90.

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

550  ! -- dummy variables
551  class(BlockParserType), intent(inout) :: this
552  !
553  errmsg = "Invalid keyword '"//trim(this%laststring)// &
554  "' detected in block '"//trim(this%blockname)//"'."
555  call dev_feature(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 123 of file BlockParser.f90.

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

447  ! -- dummy variables
448  class(BlockParserType), intent(inout) :: this !< BlockParserType object
449  integer(I4B), intent(in) :: ndim !< number of dimensions (1, 2, or 3)
450  character(len=*), intent(out) :: cellid !< cell =id
451  logical, optional, intent(in) :: flag_string !< boolean indicating id cellid is a string
452  ! -- local variables
453  integer(I4B) :: i
454  integer(I4B) :: j
455  integer(I4B) :: lloc
456  integer(I4B) :: istart
457  integer(I4B) :: istop
458  integer(I4B) :: ival
459  integer(I4B) :: istat
460  real(DP) :: rval
461  character(len=10) :: cint
462  character(len=100) :: firsttoken
463  !
464  ! -- process optional variables
465  if (present(flag_string)) then
466  lloc = this%lloc
467  call urword(this%line, lloc, istart, istop, 0, ival, rval, this%iout, &
468  this%iuext)
469  firsttoken = this%line(istart:istop)
470  read (firsttoken, *, iostat=istat) ival
471  if (istat > 0) then
472  call upcase(firsttoken)
473  cellid = firsttoken
474  return
475  end if
476  end if
477  !
478  cellid = ''
479  do i = 1, ndim
480  j = this%GetInteger()
481  write (cint, '(i0)') j
482  if (i == 1) then
483  cellid = cint
484  else
485  cellid = trim(cellid)//' '//cint
486  end if
487  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 495 of file BlockParser.f90.

496  ! -- dummy variables
497  class(BlockParserType), intent(inout) :: this !< BlockParserType object
498  character(len=*), intent(out) :: line !< current line
499  !
500  ! -- get the current line
501  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 281 of file BlockParser.f90.

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

241  ! -- return variable
242  integer(I4B) :: i !< integer variable
243  ! -- dummy variables
244  class(BlockParserType), intent(inout) :: this !< BlockParserType object
245  ! -- local variables
246  integer(I4B) :: istart
247  integer(I4B) :: istop
248  real(DP) :: rval
249  !
250  ! -- get integer using urword
251  call urword(this%line, this%lloc, istart, istop, 2, i, rval, &
252  this%iout, this%iuext)
253  !
254  ! -- Make sure variable was read before end of line
255  if (istart == istop .and. istop == len(this%line)) then
256  call this%ReadScalarError('INTEGER')
257  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 265 of file BlockParser.f90.

266  ! -- return variable
267  integer(I4B) :: nlines !< number of lines read
268  ! -- dummy variable
269  class(BlockParserType), intent(inout) :: this !< BlockParserType object
270  !
271  ! -- number of lines read
272  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 180 of file BlockParser.f90.

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

404  ! -- dummy variables
405  class(BlockParserType), intent(inout) :: this !< BlockParserType object
406  character(len=:), allocatable, intent(out) :: line !< remainder of the line
407  ! -- local variables
408  integer(I4B) :: lastpos
409  integer(I4B) :: newlinelen
410  !
411  ! -- get the rest of the line
412  lastpos = len_trim(this%line)
413  newlinelen = lastpos - this%lloc + 2
414  newlinelen = max(newlinelen, 1)
415  allocate (character(len=newlinelen) :: line)
416  line(:) = this%line(this%lloc:lastpos)
417  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 354 of file BlockParser.f90.

355  ! -- dummy variables
356  class(BlockParserType), intent(inout) :: this !< BlockParserType object
357  character(len=*), intent(out) :: string !< string
358  logical, optional, intent(in) :: convertToUpper !< boolean indicating if the string should be converted to upper case, default false
359  ! -- local variables
360  integer(I4B) :: istart
361  integer(I4B) :: istop
362  integer(I4B) :: ival
363  integer(I4B) :: ncode
364  real(DP) :: rval
365  !
366  ! -- process optional variables
367  if (present(converttoupper)) then
368  if (converttoupper) then
369  ncode = 1
370  else
371  ncode = 0
372  end if
373  else
374  ncode = 0
375  end if
376  !
377  call urword(this%line, this%lloc, istart, istop, ncode, &
378  ival, rval, this%iout, this%iuext)
379  string = this%line(istart:istop)
380  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 389 of file BlockParser.f90.

390  ! -- dummy variables
391  class(BlockParserType), intent(inout) :: this !< BlockParserType object
392  character(len=*), intent(out) :: string !< upper case string
393  !
394  ! -- call base GetString method with convertToUpper variable
395  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 533 of file BlockParser.f90.

534  ! -- return variable
535  integer(I4B) :: i !< unit number for the block parser
536  ! -- dummy variables
537  class(BlockParserType), intent(inout) :: this !< BlockParserType object
538  !
539  ! -- block parser unit number
540  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 63 of file BlockParser.f90.

64  ! -- dummy variables
65  class(BlockParserType), intent(inout) :: this !< BlockParserType object
66  integer(I4B), intent(in) :: inunit !< input file unit number
67  integer(I4B), intent(in) :: iout !< listing file unit number
68  !
69  ! -- initialize values
70  this%inunit = inunit
71  this%iuext = inunit
72  this%iuactive = inunit
73  this%iout = iout
74  this%blockName = ''
75  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 327 of file BlockParser.f90.

328  ! -- dummy variables
329  class(BlockParserType), intent(inout) :: this !< BlockParserType object
330  character(len=*), intent(in) :: vartype !< string of variable type
331  ! -- local variables
332  character(len=MAXCHARLEN - 100) :: linetemp
333  !
334  ! -- use linetemp as line may be longer than MAXCHARLEN
335  linetemp = this%line
336  !
337  ! -- write the message
338  write (errmsg, '(3a)') 'Error in block ', trim(this%blockName), '.'
339  write (errmsg, '(4a)') &
340  trim(errmsg), ' Could not read variable of type ', trim(vartype), &
341  " from the following line: '"
342  write (errmsg, '(3a)') &
343  trim(errmsg), trim(adjustl(this%line)), "'."
344  call store_error(errmsg)
345  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 510 of file BlockParser.f90.

511  ! -- dummy variable
512  class(BlockParserType), intent(inout) :: this !< BlockParserType object
513  logical, intent(in), optional :: terminate !< boolean indicating if the simulation should be terminated
514  ! -- local variables
515  logical :: lterminate
516  !
517  ! -- process optional variables
518  if (present(terminate)) then
519  lterminate = terminate
520  else
521  lterminate = .true.
522  end if
523  !
524  ! -- store error unit
525  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 425 of file BlockParser.f90.

426  ! -- dummy variables
427  class(BlockParserType), intent(inout) :: this !< BlockParserType object
428  ! -- local variables
429  logical :: endofblock
430  !
431  ! -- look for block termination
432  call this%GetNextLine(endofblock)
433  if (.not. endofblock) then
434  errmsg = "LOOKING FOR 'END "//trim(this%blockname)// &
435  "'. FOUND: "//"'"//trim(this%line)//"'."
436  call store_error(errmsg)
437  call this%StoreErrorUnit()
438  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 302 of file BlockParser.f90.

303  ! -- dummy variables
304  class(BlockParserType), intent(inout) :: this !< BlockParserType object
305  real(DP), intent(inout) :: r !< double precision real variable
306  logical(LGP), intent(inout) :: success !< whether parsing was successful
307  ! -- local variables
308  integer(I4B) :: istart
309  integer(I4B) :: istop
310  integer(I4B) :: ival
311 
312  call urword(this%line, this%lloc, istart, istop, 3, ival, r, &
313  this%iout, this%iuext)
314 
315  success = .true.
316  if (istart == istop .and. istop == len(this%line)) then
317  success = .false.
318  end if
319 
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 678 of file BlockParser.f90.

680  implicit none
681  ! -- dummy variables
682  type(LongLineReaderType), intent(inout) :: line_reader
683  integer(I4B), intent(in) :: iin !< file unit number
684  integer(I4B), intent(in) :: iout !< output listing file unit
685  logical, intent(inout) :: isfound !< boolean indicating if a block was found
686  integer(I4B), intent(inout) :: lloc !< position in line
687  character(len=:), allocatable, intent(inout) :: line !< line
688  character(len=*), intent(out) :: ctagfound !< block name
689  integer(I4B), intent(inout) :: iuext !< external file unit number
690  ! -- local variables
691  integer(I4B) :: ierr, istart, istop
692  integer(I4B) :: ival, lloc2
693  real(DP) :: rval
694  character(len=100) :: ermsg
695  character(len=:), allocatable :: line2
696  character(len=LINELENGTH) :: fname
697  !
698  ! -- code
699  isfound = .false.
700  ctagfound = ''
701  iuext = iin
702  do
703  lloc = 1
704  call line_reader%rdcom(iin, iout, line, ierr)
705  if (ierr < 0) exit
706  call urword(line, lloc, istart, istop, 1, ival, rval, iin, iout)
707  if (line(istart:istop) == 'BEGIN') then
708  call urword(line, lloc, istart, istop, 1, ival, rval, iin, iout)
709  if (line(istart:istop) /= '') then
710  isfound = .true.
711  ctagfound = line(istart:istop)
712  call line_reader%rdcom(iin, iout, line2, ierr)
713  if (ierr < 0) exit
714  lloc2 = 1
715  call urword(line2, lloc2, istart, istop, 1, ival, rval, iout, iin)
716  if (line2(istart:istop) == 'OPEN/CLOSE') then
717  iuext = io_getunit()
718  call urword(line2, lloc2, istart, istop, 0, ival, rval, iout, iin)
719  fname = line2(istart:istop)
720  call openfile(iuext, iout, fname, 'OPEN/CLOSE')
721  else
722  call line_reader%bkspc(iin)
723  end if
724  else
725  ermsg = 'Block name missing in file.'
726  call store_error(ermsg)
727  call store_error_unit(iin)
728  end if
729  exit
730  end if
731  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 565 of file BlockParser.f90.

567  implicit none
568  ! -- dummy variables
569  type(LongLineReaderType), intent(inout) :: line_reader
570  integer(I4B), intent(in) :: iin !< file unit
571  integer(I4B), intent(in) :: iout !< output listing file unit
572  character(len=*), intent(in) :: ctag !< block tag
573  integer(I4B), intent(out) :: ierr !< error
574  logical, intent(inout) :: isfound !< boolean indicating if the block was found
575  integer(I4B), intent(inout) :: lloc !< position in line
576  character(len=:), allocatable, intent(inout) :: line !< line
577  integer(I4B), intent(inout) :: iuext !< external file unit number
578  logical, optional, intent(in) :: blockRequired !< boolean indicating if the block is required
579  logical, optional, intent(in) :: supportopenclose !< boolean indicating if the block supports open/close
580  ! -- local variables
581  integer(I4B) :: istart
582  integer(I4B) :: istop
583  integer(I4B) :: ival
584  integer(I4B) :: lloc2
585  real(DP) :: rval
586  character(len=:), allocatable :: line2
587  character(len=LINELENGTH) :: fname
588  character(len=MAXCHARLEN) :: ermsg
589  logical :: supportoc, blockRequiredLocal
590  !
591  ! -- code
592  if (present(blockrequired)) then
593  blockrequiredlocal = blockrequired
594  else
595  blockrequiredlocal = .true.
596  end if
597  supportoc = .false.
598  if (present(supportopenclose)) then
599  supportoc = supportopenclose
600  end if
601  iuext = iin
602  isfound = .false.
603  mainloop: do
604  lloc = 1
605  call line_reader%rdcom(iin, iout, line, ierr)
606  if (ierr < 0) then
607  if (blockrequiredlocal) then
608  ermsg = 'Required block "'//trim(ctag)// &
609  '" not found. Found end of file instead.'
610  call store_error(ermsg)
611  call store_error_unit(iuext)
612  end if
613  ! block not found so exit
614  exit
615  end if
616  call urword(line, lloc, istart, istop, 1, ival, rval, iin, iout)
617  if (line(istart:istop) == 'BEGIN') then
618  call urword(line, lloc, istart, istop, 1, ival, rval, iin, iout)
619  if (line(istart:istop) == ctag) then
620  isfound = .true.
621  if (supportoc) then
622  ! Look for OPEN/CLOSE on 1st line after line starting with BEGIN
623  call line_reader%rdcom(iin, iout, line2, ierr)
624  if (ierr < 0) exit
625  lloc2 = 1
626  call urword(line2, lloc2, istart, istop, 1, ival, rval, iin, iout)
627  if (line2(istart:istop) == 'OPEN/CLOSE') then
628  ! -- Get filename and preserve case
629  call urword(line2, lloc2, istart, istop, 0, ival, rval, iin, iout)
630  fname = line2(istart:istop)
631  ! If line contains '(BINARY)' or 'SFAC', handle this block elsewhere
632  chk: do
633  call urword(line2, lloc2, istart, istop, 1, ival, rval, iin, iout)
634  if (line2(istart:istop) == '') exit chk
635  if (line2(istart:istop) == '(BINARY)' .or. &
636  line2(istart:istop) == 'SFAC') then
637  call line_reader%bkspc(iin)
638  exit mainloop
639  end if
640  end do chk
641  iuext = io_getunit()
642  call openfile(iuext, iout, fname, 'OPEN/CLOSE')
643  else
644  call line_reader%bkspc(iin)
645  end if
646  end if
647  else
648  if (blockrequiredlocal) then
649  ermsg = 'Error: Required block "'//trim(ctag)// &
650  '" not found. Found block "'//line(istart:istop)// &
651  '" instead.'
652  call store_error(ermsg)
653  call store_error_unit(iuext)
654  else
655  call line_reader%bkspc(iin)
656  end if
657  end if
658  exit mainloop
659  else if (line(istart:istop) == 'END') then
660  call urword(line, lloc, istart, istop, 1, ival, rval, iin, iout)
661  if (line(istart:istop) == ctag) then
662  ermsg = 'Error: Looking for BEGIN '//trim(ctag)// &
663  ' but found END '//line(istart:istop)// &
664  ' instead.'
665  call store_error(ermsg)
666  call store_error_unit(iuext)
667  end if
668  end if
669  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 741 of file BlockParser.f90.

742  implicit none
743  ! -- dummy variables
744  integer(I4B), intent(in) :: iin !< file unit number
745  integer(I4B), intent(in) :: iout !< output listing file unit number
746  character(len=*), intent(in) :: key !< keyword in block
747  character(len=*), intent(in) :: ctag !< block name
748  integer(I4B), intent(inout) :: lloc !< position in line
749  character(len=*), intent(inout) :: line !< line
750  integer(I4B), intent(inout) :: ierr !< error
751  integer(I4B), intent(inout) :: iuext !< external file unit number
752  ! -- local variables
753  character(len=LENBIGLINE) :: ermsg
754  integer(I4B) :: istart
755  integer(I4B) :: istop
756  integer(I4B) :: ival
757  real(DP) :: rval
758  ! -- format
759 1 format('ERROR. "', a, '" DETECTED WITHOUT "', a, '". ', '"END', 1x, a, &
760  '" MUST BE USED TO END ', a, '.')
761 2 format('ERROR. "', a, '" DETECTED BEFORE "END', 1x, a, '". ', '"END', 1x, a, &
762  '" MUST BE USED TO END ', a, '.')
763  !
764  ! -- code
765  ierr = 1
766  select case (key)
767  case ('END')
768  call urword(line, lloc, istart, istop, 1, ival, rval, iout, iin)
769  if (line(istart:istop) /= ctag) then
770  write (ermsg, 1) trim(key), trim(ctag), trim(ctag), trim(ctag)
771  call store_error(ermsg)
772  call store_error_unit(iin)
773  else
774  ierr = 0
775  if (iuext /= iin) then
776  ! -- close external file
777  close (iuext)
778  iuext = iin
779  end if
780  end if
781  case ('BEGIN')
782  write (ermsg, 2) trim(key), trim(ctag), trim(ctag), trim(ctag)
783  call store_error(ermsg)
784  call store_error_unit(iin)
785  end select
Here is the call graph for this function:
Here is the caller graph for this function: