the popped character.
Get the next character from the file (or string).
Type | Visibility | Attributes | Name | Initial | |||
---|---|---|---|---|---|---|---|
integer(kind=IK), | public | :: | ios | ||||
integer(kind=IK), | public | :: | str_len | ||||
character(kind=CK,len=1), | public | :: | c | ||||
logical(kind=LK), | public | :: | ignore |
recursive function pop_char(unit, str, eof, skip_ws) result(popped)
implicit none
character(kind=CK,len=1) :: popped !! the popped character.
integer(IK),intent(in) :: unit !! file unit number (if parsing from a file)
character(kind=CK,len=*),intent(in) :: str !! JSON string (if parsing from a string) -- only used if unit=0
logical(LK),intent(out) :: eof !! true if the end of the file has been reached.
logical(LK),intent(in),optional :: skip_ws !! to ignore whitespace.
integer(IK) :: ios,str_len
character(kind=CK,len=1) :: c
logical(LK) :: ignore
if (.not. exception_thrown) then
eof = .false.
if (.not. present(skip_ws)) then
ignore = .false.
else
ignore = skip_ws
end if
do
if (pushed_index > 0) then
! there is a character pushed back on, most likely from the number parsing
! NOTE: this can only occur if reading from a file when use_unformatted_stream=.false.
c = pushed_char(pushed_index:pushed_index)
pushed_index = pushed_index - 1
else
if (unit/=0) then !read from the file
!read the next character:
if (use_unformatted_stream) then
read(unit=unit,pos=ipos,iostat=ios) c
else
read(unit=unit,fmt='(A1)',advance='NO',iostat=ios) c
end if
ipos = ipos + 1
!....note: maybe try read the file in chunks...
!.... or use asynchronous read with double buffering
! (see Modern Fortran: Style and Usage)
else !read from the string
str_len = len(str) !length of the string
if (ipos<=str_len) then
c = str(ipos:ipos)
ios = 0
else
ios = IOSTAT_END !end of the string
end if
ipos = ipos + 1
end if
char_count = char_count + 1 !character count in the current line
if (IS_IOSTAT_END(ios)) then !end of file
char_count = 0
eof = .true.
exit
elseif (IS_IOSTAT_EOR(ios) .or. c==newline) then !end of record
char_count = 0
line_count = line_count + 1
cycle
end if
end if
if (any(c == control_chars)) then
! non printing ascii characters
cycle
else if (ignore .and. c == space) then
cycle
else
popped = c
exit
end if
end do
end if
end function pop_char