MODFLOW 6  version 6.5.0.dev2
MODFLOW 6 Code Documentation
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 87 of file BlockParser.f90.

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

◆ 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 594 of file BlockParser.f90.

595  ! -- dummy variables
596  class(BlockParserType), intent(inout) :: this
597  !
598  errmsg = "Invalid keyword '"//trim(this%laststring)// &
599  "' detected in block '"//trim(this%blockname)//"'."
600  call dev_feature(errmsg, this%iuext)
601  !
602  return
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 129 of file BlockParser.f90.

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

480  ! -- dummy variables
481  class(BlockParserType), intent(inout) :: this !< BlockParserType object
482  integer(I4B), intent(in) :: ndim !< number of dimensions (1, 2, or 3)
483  character(len=*), intent(out) :: cellid !< cell =id
484  logical, optional, intent(in) :: flag_string !< boolean indicating id cellid is a string
485  ! -- local variables
486  integer(I4B) :: i
487  integer(I4B) :: j
488  integer(I4B) :: lloc
489  integer(I4B) :: istart
490  integer(I4B) :: istop
491  integer(I4B) :: ival
492  integer(I4B) :: istat
493  real(DP) :: rval
494  character(len=10) :: cint
495  character(len=100) :: firsttoken
496  !
497  ! -- process optional variables
498  if (present(flag_string)) then
499  lloc = this%lloc
500  call urword(this%line, lloc, istart, istop, 0, ival, rval, this%iout, &
501  this%iuext)
502  firsttoken = this%line(istart:istop)
503  read (firsttoken, *, iostat=istat) ival
504  if (istat > 0) then
505  call upcase(firsttoken)
506  cellid = firsttoken
507  return
508  end if
509  end if
510  !
511  cellid = ''
512  do i = 1, ndim
513  j = this%GetInteger()
514  write (cint, '(i0)') j
515  if (i == 1) then
516  cellid = cint
517  else
518  cellid = trim(cellid)//' '//cint
519  end if
520  end do
521  !
522  ! -- return
523  return
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 531 of file BlockParser.f90.

532  ! -- dummy variables
533  class(BlockParserType), intent(inout) :: this !< BlockParserType object
534  character(len=*), intent(out) :: line !< current line
535  !
536  ! -- get the current line
537  line = this%line
538  !
539  ! -- return
540  return

◆ 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 299 of file BlockParser.f90.

300  ! -- return variable
301  real(DP) :: r !< double precision real variable
302  ! -- dummy variables
303  class(BlockParserType), intent(inout) :: this !< BlockParserType object
304  ! -- local variables
305  integer(I4B) :: istart
306  integer(I4B) :: istop
307  integer(I4B) :: ival
308  !
309  ! -- get double precision real using urword
310  call urword(this%line, this%lloc, istart, istop, 3, ival, r, &
311  this%iout, this%iuext)
312  !
313  ! -- Make sure variable was read before end of line
314  if (istart == istop .and. istop == len(this%line)) then
315  call this%ReadScalarError('DOUBLE PRECISION')
316  end if
317 
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 252 of file BlockParser.f90.

253  ! -- return variable
254  integer(I4B) :: i !< integer variable
255  ! -- dummy variables
256  class(BlockParserType), intent(inout) :: this !< BlockParserType object
257  ! -- local variables
258  integer(I4B) :: istart
259  integer(I4B) :: istop
260  real(DP) :: rval
261  !
262  ! -- get integer using urword
263  call urword(this%line, this%lloc, istart, istop, 2, i, rval, &
264  this%iout, this%iuext)
265  !
266  ! -- Make sure variable was read before end of line
267  if (istart == istop .and. istop == len(this%line)) then
268  call this%ReadScalarError('INTEGER')
269  end if
270  !
271  ! -- return
272  return
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 280 of file BlockParser.f90.

281  ! -- return variable
282  integer(I4B) :: nlines !< number of lines read
283  ! -- dummy variable
284  class(BlockParserType), intent(inout) :: this !< BlockParserType object
285  !
286  ! -- number of lines read
287  nlines = this%linesRead
288  !
289  ! -- return
290  return

◆ 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 189 of file BlockParser.f90.

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

431  ! -- dummy variables
432  class(BlockParserType), intent(inout) :: this !< BlockParserType object
433  character(len=:), allocatable, intent(out) :: line !< remainder of the line
434  ! -- local variables
435  integer(I4B) :: lastpos
436  integer(I4B) :: newlinelen
437  !
438  ! -- get the rest of the line
439  lastpos = len_trim(this%line)
440  newlinelen = lastpos - this%lloc + 2
441  newlinelen = max(newlinelen, 1)
442  allocate (character(len=newlinelen) :: line)
443  line(:) = this%line(this%lloc:lastpos)
444  line(newlinelen:newlinelen) = ' '
445  !
446  ! -- return
447  return

◆ 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)
402  !
403  ! -- return
404  return
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 413 of file BlockParser.f90.

414  ! -- dummy variables
415  class(BlockParserType), intent(inout) :: this !< BlockParserType object
416  character(len=*), intent(out) :: string !< upper case string
417  !
418  ! -- call base GetString method with convertToUpper variable
419  call this%GetString(string, converttoupper=.true.)
420  !
421  ! -- return
422  return

◆ 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 575 of file BlockParser.f90.

576  ! -- return variable
577  integer(I4B) :: i !< unit number for the block parser
578  ! -- dummy variables
579  class(BlockParserType), intent(inout) :: this !< BlockParserType object
580  !
581  ! -- block parser unit number
582  i = this%iuext
583  !
584  ! -- return
585  return

◆ 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
76  !
77  ! -- return
78  return

◆ 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 345 of file BlockParser.f90.

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

550  ! -- dummy variable
551  class(BlockParserType), intent(inout) :: this !< BlockParserType object
552  logical, intent(in), optional :: terminate !< boolean indicating if the simulation should be terminated
553  ! -- local variables
554  logical :: lterminate
555  !
556  ! -- process optional variables
557  if (present(terminate)) then
558  lterminate = terminate
559  else
560  lterminate = .true.
561  end if
562  !
563  ! -- store error unit
564  call store_error_unit(this%iuext, terminate=lterminate)
565  !
566  ! -- return
567  return
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 455 of file BlockParser.f90.

456  ! -- dummy variables
457  class(BlockParserType), intent(inout) :: this !< BlockParserType object
458  ! -- local variables
459  logical :: endofblock
460  !
461  ! -- look for block termination
462  call this%GetNextLine(endofblock)
463  if (.not. endofblock) then
464  errmsg = "LOOKING FOR 'END "//trim(this%blockname)// &
465  "'. FOUND: "//"'"//trim(this%line)//"'."
466  call store_error(errmsg)
467  call this%StoreErrorUnit()
468  end if
469  !
470  ! -- return
471  return
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 320 of file BlockParser.f90.

321  ! -- dummy variables
322  class(BlockParserType), intent(inout) :: this !< BlockParserType object
323  real(DP), intent(inout) :: r !< double precision real variable
324  logical(LGP), intent(inout) :: success !< whether parsing was successful
325  ! -- local variables
326  integer(I4B) :: istart
327  integer(I4B) :: istop
328  integer(I4B) :: ival
329 
330  call urword(this%line, this%lloc, istart, istop, 3, ival, r, &
331  this%iout, this%iuext)
332 
333  success = .true.
334  if (istart == istop .and. istop == len(this%line)) then
335  success = .false.
336  end if
337 
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 728 of file BlockParser.f90.

730  implicit none
731  ! -- dummy variables
732  type(LongLineReaderType), intent(inout) :: line_reader
733  integer(I4B), intent(in) :: iin !< file unit number
734  integer(I4B), intent(in) :: iout !< output listing file unit
735  logical, intent(inout) :: isfound !< boolean indicating if a block was found
736  integer(I4B), intent(inout) :: lloc !< position in line
737  character(len=:), allocatable, intent(inout) :: line !< line
738  character(len=*), intent(out) :: ctagfound !< block name
739  integer(I4B), intent(inout) :: iuext !< external file unit number
740  ! -- local variables
741  integer(I4B) :: ierr, istart, istop
742  integer(I4B) :: ival, lloc2
743  real(DP) :: rval
744  character(len=100) :: ermsg
745  character(len=:), allocatable :: line2
746  character(len=LINELENGTH) :: fname
747  !
748  ! -- code
749  isfound = .false.
750  ctagfound = ''
751  iuext = iin
752  do
753  lloc = 1
754  call line_reader%rdcom(iin, iout, line, ierr)
755  if (ierr < 0) exit
756  call urword(line, lloc, istart, istop, 1, ival, rval, iin, iout)
757  if (line(istart:istop) == 'BEGIN') then
758  call urword(line, lloc, istart, istop, 1, ival, rval, iin, iout)
759  if (line(istart:istop) /= '') then
760  isfound = .true.
761  ctagfound = line(istart:istop)
762  call line_reader%rdcom(iin, iout, line2, ierr)
763  if (ierr < 0) exit
764  lloc2 = 1
765  call urword(line2, lloc2, istart, istop, 1, ival, rval, iout, iin)
766  if (line2(istart:istop) == 'OPEN/CLOSE') then
767  iuext = io_getunit()
768  call urword(line2, lloc2, istart, istop, 0, ival, rval, iout, iin)
769  fname = line2(istart:istop)
770  call openfile(iuext, iout, fname, 'OPEN/CLOSE')
771  else
772  call line_reader%bkspc(iin)
773  end if
774  else
775  ermsg = 'Block name missing in file.'
776  call store_error(ermsg)
777  call store_error_unit(iin)
778  end if
779  exit
780  end if
781  end do
782  return
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 612 of file BlockParser.f90.

614  implicit none
615  ! -- dummy variables
616  type(LongLineReaderType), intent(inout) :: line_reader
617  integer(I4B), intent(in) :: iin !< file unit
618  integer(I4B), intent(in) :: iout !< output listing file unit
619  character(len=*), intent(in) :: ctag !< block tag
620  integer(I4B), intent(out) :: ierr !< error
621  logical, intent(inout) :: isfound !< boolean indicating if the block was found
622  integer(I4B), intent(inout) :: lloc !< position in line
623  character(len=:), allocatable, intent(inout) :: line !< line
624  integer(I4B), intent(inout) :: iuext !< external file unit number
625  logical, optional, intent(in) :: blockRequired !< boolean indicating if the block is required
626  logical, optional, intent(in) :: supportopenclose !< boolean indicating if the block supports open/close
627  ! -- local variables
628  integer(I4B) :: istart
629  integer(I4B) :: istop
630  integer(I4B) :: ival
631  integer(I4B) :: lloc2
632  real(DP) :: rval
633  character(len=:), allocatable :: line2
634  character(len=LINELENGTH) :: fname
635  character(len=MAXCHARLEN) :: ermsg
636  logical :: supportoc, blockRequiredLocal
637  !
638  ! -- code
639  if (present(blockrequired)) then
640  blockrequiredlocal = blockrequired
641  else
642  blockrequiredlocal = .true.
643  end if
644  supportoc = .false.
645  if (present(supportopenclose)) then
646  supportoc = supportopenclose
647  end if
648  iuext = iin
649  isfound = .false.
650  mainloop: do
651  lloc = 1
652  call line_reader%rdcom(iin, iout, line, ierr)
653  if (ierr < 0) then
654  if (blockrequiredlocal) then
655  ermsg = 'Required block "'//trim(ctag)// &
656  '" not found. Found end of file instead.'
657  call store_error(ermsg)
658  call store_error_unit(iuext)
659  end if
660  ! block not found so exit
661  exit
662  end if
663  call urword(line, lloc, istart, istop, 1, ival, rval, iin, iout)
664  if (line(istart:istop) == 'BEGIN') then
665  call urword(line, lloc, istart, istop, 1, ival, rval, iin, iout)
666  if (line(istart:istop) == ctag) then
667  isfound = .true.
668  if (supportoc) then
669  ! Look for OPEN/CLOSE on 1st line after line starting with BEGIN
670  call line_reader%rdcom(iin, iout, line2, ierr)
671  if (ierr < 0) exit
672  lloc2 = 1
673  call urword(line2, lloc2, istart, istop, 1, ival, rval, iin, iout)
674  if (line2(istart:istop) == 'OPEN/CLOSE') then
675  ! -- Get filename and preserve case
676  call urword(line2, lloc2, istart, istop, 0, ival, rval, iin, iout)
677  fname = line2(istart:istop)
678  ! If line contains '(BINARY)' or 'SFAC', handle this block elsewhere
679  chk: do
680  call urword(line2, lloc2, istart, istop, 1, ival, rval, iin, iout)
681  if (line2(istart:istop) == '') exit chk
682  if (line2(istart:istop) == '(BINARY)' .or. &
683  line2(istart:istop) == 'SFAC') then
684  call line_reader%bkspc(iin)
685  exit mainloop
686  end if
687  end do chk
688  iuext = io_getunit()
689  call openfile(iuext, iout, fname, 'OPEN/CLOSE')
690  else
691  call line_reader%bkspc(iin)
692  end if
693  end if
694  else
695  if (blockrequiredlocal) then
696  ermsg = 'Error: Required block "'//trim(ctag)// &
697  '" not found. Found block "'//line(istart:istop)// &
698  '" instead.'
699  call store_error(ermsg)
700  call store_error_unit(iuext)
701  else
702  call line_reader%bkspc(iin)
703  end if
704  end if
705  exit mainloop
706  else if (line(istart:istop) == 'END') then
707  call urword(line, lloc, istart, istop, 1, ival, rval, iin, iout)
708  if (line(istart:istop) == ctag) then
709  ermsg = 'Error: Looking for BEGIN '//trim(ctag)// &
710  ' but found END '//line(istart:istop)// &
711  ' instead.'
712  call store_error(ermsg)
713  call store_error_unit(iuext)
714  end if
715  end if
716  end do mainloop
717  !
718  ! -- return
719  return
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 792 of file BlockParser.f90.

793  implicit none
794  ! -- dummy variables
795  integer(I4B), intent(in) :: iin !< file unit number
796  integer(I4B), intent(in) :: iout !< output listing file unit number
797  character(len=*), intent(in) :: key !< keyword in block
798  character(len=*), intent(in) :: ctag !< block name
799  integer(I4B), intent(inout) :: lloc !< position in line
800  character(len=*), intent(inout) :: line !< line
801  integer(I4B), intent(inout) :: ierr !< error
802  integer(I4B), intent(inout) :: iuext !< external file unit number
803  ! -- local variables
804  character(len=LENBIGLINE) :: ermsg
805  integer(I4B) :: istart
806  integer(I4B) :: istop
807  integer(I4B) :: ival
808  real(DP) :: rval
809  ! -- format
810 1 format('ERROR. "', a, '" DETECTED WITHOUT "', a, '". ', '"END', 1x, a, &
811  '" MUST BE USED TO END ', a, '.')
812 2 format('ERROR. "', a, '" DETECTED BEFORE "END', 1x, a, '". ', '"END', 1x, a, &
813  '" MUST BE USED TO END ', a, '.')
814  !
815  ! -- code
816  ierr = 1
817  select case (key)
818  case ('END')
819  call urword(line, lloc, istart, istop, 1, ival, rval, iout, iin)
820  if (line(istart:istop) /= ctag) then
821  write (ermsg, 1) trim(key), trim(ctag), trim(ctag), trim(ctag)
822  call store_error(ermsg)
823  call store_error_unit(iin)
824  else
825  ierr = 0
826  if (iuext /= iin) then
827  ! -- close external file
828  close (iuext)
829  iuext = iin
830  end if
831  end if
832  case ('BEGIN')
833  write (ermsg, 2) trim(key), trim(ctag), trim(ctag), trim(ctag)
834  call store_error(ermsg)
835  call store_error_unit(iin)
836  end select
837  !
838  ! -- return
839  return
Here is the call graph for this function:
Here is the caller graph for this function: