43 #include "../base/base_uses.f90"
52 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'cp_parser_methods'
54 INTERFACE parser_get_object
55 MODULE PROCEDURE parser_get_integer, &
71 TYPE(cp_parser_type),
INTENT(IN) :: parser
75 res =
", File: '"//trim(parser%input_file_name)//
"', Line: "// &
76 trim(adjustl(cp_to_string(parser%input_line_number)))// &
77 ", Column: "//trim(adjustl(cp_to_string(parser%icol)))
78 IF (parser%icol == -1)
THEN
79 res(len_trim(res):) =
" (EOF)"
80 ELSE IF (max(1, parser%icol1) <= parser%icol2)
THEN
81 res(len_trim(res):) =
", Chunk: <"// &
82 parser%input_line(max(1, parser%icol1):parser%icol2)//
">"
93 SUBROUTINE parser_store_status(parser)
95 TYPE(cp_parser_type),
INTENT(INOUT) :: parser
97 cpassert(
ASSOCIATED(parser%status))
98 parser%status%in_use = .true.
99 parser%status%old_input_line = parser%input_line
100 parser%status%old_input_line_number = parser%input_line_number
101 parser%status%old_icol = parser%icol
102 parser%status%old_icol1 = parser%icol1
103 parser%status%old_icol2 = parser%icol2
107 END SUBROUTINE parser_store_status
115 SUBROUTINE parser_retrieve_status(parser)
117 TYPE(cp_parser_type),
INTENT(INOUT) :: parser
120 IF (parser%buffer%buffer_id /= parser%status%buffer%buffer_id)
THEN
123 parser%status%in_use = .false.
124 parser%input_line = parser%status%old_input_line
125 parser%input_line_number = parser%status%old_input_line_number
126 parser%icol = parser%status%old_icol
127 parser%icol1 = parser%status%old_icol1
128 parser%icol2 = parser%status%old_icol2
133 END SUBROUTINE parser_retrieve_status
148 TYPE(cp_parser_type),
INTENT(INOUT) :: parser
149 INTEGER,
INTENT(IN) :: nline
150 LOGICAL,
INTENT(out),
OPTIONAL :: at_end
152 CHARACTER(LEN=*),
PARAMETER :: routinen =
'parser_read_line'
154 INTEGER :: handle, iline, istat
156 CALL timeset(routinen, handle)
158 IF (
PRESENT(at_end)) at_end = .false.
162 CALL parser_get_line_from_buffer(parser, istat)
167 IF (
PRESENT(at_end))
THEN
176 CALL cp_abort(__location__, &
177 "An I/O error occurred (IOSTAT = "// &
178 trim(adjustl(cp_to_string(istat)))//
")"// &
181 CALL timestop(handle)
187 IF (nline > 0) parser%icol = 0
189 CALL timestop(handle)
199 SUBROUTINE parser_get_line_from_buffer(parser, istat)
201 TYPE(cp_parser_type),
INTENT(INOUT) :: parser
202 INTEGER,
INTENT(OUT) :: istat
206 IF (parser%buffer%present_line_number == parser%buffer%size)
THEN
207 IF (
ASSOCIATED(parser%buffer%sub_buffer))
THEN
212 CALL parser_read_line_low(parser)
215 parser%buffer%present_line_number = parser%buffer%present_line_number + 1
216 parser%input_line_number = parser%buffer%input_line_numbers(parser%buffer%present_line_number)
217 parser%input_line = parser%buffer%input_lines(parser%buffer%present_line_number)
218 IF ((parser%buffer%istat /= 0) .AND. &
219 (parser%buffer%last_line_number == parser%buffer%present_line_number))
THEN
220 istat = parser%buffer%istat
223 END SUBROUTINE parser_get_line_from_buffer
231 SUBROUTINE parser_read_line_low(parser)
233 TYPE(cp_parser_type),
INTENT(INOUT) :: parser
235 CHARACTER(LEN=*),
PARAMETER :: routinen =
'parser_read_line_low'
237 INTEGER :: handle, iline, imark, islen, istat, &
238 last_buffered_line_number
239 LOGICAL :: non_white_found, &
240 this_line_is_white_or_comment
242 CALL timeset(routinen, handle)
244 parser%buffer%input_lines =
""
245 IF (parser%para_env%is_source())
THEN
248 parser%buffer%buffer_id = parser%buffer%buffer_id + 1
249 parser%buffer%present_line_number = 0
250 parser%buffer%last_line_number = parser%buffer%size
251 last_buffered_line_number = parser%buffer%input_line_numbers(parser%buffer%size)
252 DO WHILE (iline /= parser%buffer%size)
255 last_buffered_line_number = last_buffered_line_number + 1
258 parser%buffer%input_line_numbers(iline) = last_buffered_line_number
259 READ (unit=parser%input_unit, fmt=
"(A)", iostat=istat) parser%buffer%input_lines(iline)
265 islen = len_trim(parser%buffer%input_lines(iline))
266 this_line_is_white_or_comment = is_comment_line(parser, parser%buffer%input_lines(iline))
267 IF (.NOT. this_line_is_white_or_comment .AND. parser%apply_preprocessing)
THEN
268 imark = index(parser%buffer%input_lines(iline) (1:islen),
"$")
271 parser%input_file_name, parser%buffer%input_line_numbers(iline))
272 islen = len_trim(parser%buffer%input_lines(iline))
274 imark = index(parser%buffer%input_lines(iline) (1:islen),
"@")
277 parser%input_file_name, parser%buffer%input_line_numbers(iline), &
279 islen = len_trim(parser%buffer%input_lines(iline))
281 last_buffered_line_number = 0
287 this_line_is_white_or_comment = is_comment_line(parser, parser%buffer%input_lines(iline))
289 ELSE IF (istat < 0)
THEN
290 IF (parser%inpp%io_stack_level > 0)
THEN
293 parser%buffer%input_line_numbers(iline), parser%input_unit)
295 last_buffered_line_number = parser%buffer%input_line_numbers(iline)
303 parser%buffer%istat = istat
304 parser%buffer%last_line_number = iline
305 parser%buffer%input_line_numbers(iline:) = 0
306 parser%buffer%input_lines(iline:) =
""
311 IF (.NOT. parser%parse_white_lines)
THEN
312 non_white_found = .NOT. this_line_is_white_or_comment
314 non_white_found = .true.
316 IF (.NOT. non_white_found)
THEN
318 last_buffered_line_number = last_buffered_line_number - 1
323 CALL broadcast_input_information(parser)
325 CALL timestop(handle)
327 END SUBROUTINE parser_read_line_low
336 SUBROUTINE broadcast_input_information(parser)
338 TYPE(cp_parser_type),
INTENT(INOUT) :: parser
340 CHARACTER(len=*),
PARAMETER :: routinen =
'broadcast_input_information'
343 TYPE(mp_para_env_type),
POINTER :: para_env
345 CALL timeset(routinen, handle)
347 para_env => parser%para_env
348 IF (para_env%num_pe > 1)
THEN
349 CALL para_env%bcast(parser%buffer%buffer_id)
350 CALL para_env%bcast(parser%buffer%present_line_number)
351 CALL para_env%bcast(parser%buffer%last_line_number)
352 CALL para_env%bcast(parser%buffer%istat)
353 CALL para_env%bcast(parser%buffer%input_line_numbers)
354 CALL para_env%bcast(parser%buffer%input_lines)
357 CALL timestop(handle)
359 END SUBROUTINE broadcast_input_information
369 ELEMENTAL FUNCTION is_comment_line(parser, line)
RESULT(resval)
371 TYPE(cp_parser_type),
INTENT(IN) :: parser
372 CHARACTER(LEN=*),
INTENT(IN) :: line
375 CHARACTER(LEN=1) :: thischar
379 DO icol = 1, len(line)
380 thischar = line(icol:icol)
382 IF (.NOT. is_comment(parser, thischar)) resval = .false.
387 END FUNCTION is_comment_line
398 ELEMENTAL FUNCTION is_comment(parser, testchar)
RESULT(resval)
400 TYPE(cp_parser_type),
INTENT(IN) :: parser
401 CHARACTER(LEN=1),
INTENT(IN) :: testchar
406 IF (any(parser%comment_character == testchar)) resval = .true.
408 END FUNCTION is_comment
422 TYPE(cp_parser_type),
INTENT(INOUT) :: parser
423 INTEGER,
INTENT(IN) :: nline
424 LOGICAL,
INTENT(out),
OPTIONAL :: at_end
430 IF (
PRESENT(at_end))
THEN
437 ELSE IF (
PRESENT(at_end))
THEN
451 TYPE(cp_parser_type),
INTENT(INOUT) :: parser
459 IF (parser%icol == -1)
THEN
469 parser%icol = parser%icol + 1
472 IF ((parser%icol > len_trim(parser%input_line)) .OR. &
473 is_comment(parser, parser%input_line(parser%icol:parser%icol)))
THEN
480 IF (.NOT.
is_whitespace(parser%input_line(parser%icol:parser%icol)))
THEN
482 IF (parser%input_line(parser%icol:parser%icol) == parser%continuation_character)
THEN
483 inner_loop:
DO i = parser%icol + 1, len_trim(parser%input_line)
485 IF (is_comment(parser, parser%input_line(i:i)))
THEN
489 parser%icol2 = len_trim(parser%input_line)
490 CALL cp_abort(__location__, &
491 "Found a non-blank token which is not a comment after the line continuation character '"// &
497 CALL cp_abort(__location__, &
498 "Unexpected end of file (EOF) found after line continuation"// &
504 parser%icol = parser%icol - 1
505 parser%icol1 = parser%icol
506 parser%icol2 = parser%icol
524 SUBROUTINE parser_next_token(parser, string_length)
526 TYPE(cp_parser_type),
INTENT(INOUT) :: parser
527 INTEGER,
INTENT(IN),
OPTIONAL :: string_length
529 CHARACTER(LEN=1) :: token
530 INTEGER :: i, len_trim_inputline, length
533 IF (
PRESENT(string_length))
THEN
535 cpabort(
"string length > max_line_length")
537 length = string_length
544 len_trim_inputline = len_trim(parser%input_line)
551 IF (parser%icol == -1) &
554 length = min(len_trim_inputline - parser%icol1 + 1, length)
555 parser%icol1 = parser%icol + 1
556 parser%icol2 = parser%icol + length
557 i = index(parser%input_line(parser%icol1:parser%icol2), parser%quote_character)
558 IF (i > 0) parser%icol2 = parser%icol + i
559 parser%icol = parser%icol2
566 IF (parser%icol == -1)
THEN
576 parser%icol = parser%icol + 1
579 IF (parser%icol > len_trim_inputline)
THEN
585 token = parser%input_line(parser%icol:parser%icol)
590 ELSE IF (is_comment(parser, token))
THEN
593 parser%first_separator = .true.
595 ELSE IF (token == parser%quote_character)
THEN
597 parser%icol1 = parser%icol + 1
598 parser%icol2 = parser%icol + index(parser%input_line(parser%icol1:), parser%quote_character)
599 IF (parser%icol2 == parser%icol)
THEN
600 parser%icol1 = parser%icol
601 parser%icol2 = parser%icol
602 CALL cp_abort(__location__, &
605 parser%icol = parser%icol2
606 parser%icol2 = parser%icol2 - 1
607 parser%first_separator = .true.
610 ELSE IF (token == parser%continuation_character)
THEN
612 inner_loop1:
DO i = parser%icol + 1, len_trim_inputline
615 ELSE IF (is_comment(parser, parser%input_line(i:i)))
THEN
619 parser%icol2 = len_trim_inputline
620 CALL cp_abort(__location__, &
621 "Found a non-blank token which is not a comment after the line continuation character '"// &
627 CALL cp_abort(__location__, &
628 "Unexpected end of file (EOF) found after line continuation"//trim(
parser_location(parser)))
630 len_trim_inputline = len_trim(parser%input_line)
632 ELSE IF (index(parser%separators, token) > 0)
THEN
633 IF (parser%first_separator)
THEN
634 parser%first_separator = .false.
637 parser%icol1 = parser%icol
638 parser%icol2 = parser%icol
639 CALL cp_abort(__location__, &
640 "Unexpected separator token '"//token// &
644 parser%icol1 = parser%icol
645 parser%first_separator = .true.
653 parser%icol = parser%icol + 1
654 IF (parser%icol > len_trim_inputline)
EXIT outer_loop2
655 token = parser%input_line(parser%icol:parser%icol)
656 IF (
is_whitespace(token) .OR. is_comment(parser, token) .OR. &
657 (token == parser%continuation_character))
THEN
659 ELSE IF (index(parser%separators, token) > 0)
THEN
660 parser%first_separator = .false.
665 parser%icol2 = parser%icol - 1
667 IF (parser%input_line(parser%icol:parser%icol) == &
668 parser%continuation_character) parser%icol = parser%icol2
672 END SUBROUTINE parser_next_token
692 TYPE(cp_parser_type),
INTENT(INOUT) :: parser
693 INTEGER,
INTENT(IN),
OPTIONAL :: string_length
694 CHARACTER(LEN=3) :: test_result
696 CHARACTER(LEN=max_line_length) :: error_message, string
698 LOGICAL :: ilist_in_use
704 CALL parser_store_status(parser)
707 ilist_in_use = parser%ilist%in_use .AND. (parser%ilist%ipresent < parser%ilist%iend)
708 IF (ilist_in_use)
THEN
710 CALL parser_retrieve_status(parser)
715 IF (
PRESENT(string_length))
THEN
716 CALL parser_next_token(parser, string_length=string_length)
718 CALL parser_next_token(parser)
722 IF (parser%icol1 > parser%icol2)
THEN
724 CALL parser_retrieve_status(parser)
728 string = parser%input_line(parser%icol1:parser%icol2)
733 CALL parser_retrieve_status(parser)
738 IF (string(1:n) == parser%end_section)
THEN
740 CALL parser_retrieve_status(parser)
747 IF (len_trim(error_message) == 0)
THEN
749 CALL parser_retrieve_status(parser)
756 IF (len_trim(error_message) == 0)
THEN
758 CALL parser_retrieve_status(parser)
763 CALL parser_retrieve_status(parser)
785 search_from_begin_of_file)
787 TYPE(cp_parser_type),
INTENT(INOUT) :: parser
788 CHARACTER(LEN=*),
INTENT(IN) :: string
789 LOGICAL,
INTENT(IN) :: ignore_case
790 LOGICAL,
INTENT(OUT) :: found
791 CHARACTER(LEN=*),
INTENT(OUT),
OPTIONAL :: line
792 LOGICAL,
INTENT(IN),
OPTIONAL :: begin_line, search_from_begin_of_file
794 CHARACTER(LEN=LEN(string)) :: pattern
795 CHARACTER(LEN=max_line_length+1) :: current_line
797 LOGICAL :: at_end, begin, do_reset
802 IF (
PRESENT(begin_line)) begin = begin_line
803 IF (
PRESENT(search_from_begin_of_file)) do_reset = search_from_begin_of_file
804 IF (
PRESENT(line)) line =
""
818 current_line = parser%input_line
819 IF (ignore_case)
CALL uppercase(current_line)
820 ipattern = index(current_line, trim(pattern))
822 IF (ipattern > 0)
THEN
824 parser%icol = ipattern - 1
825 IF (
PRESENT(line))
THEN
826 IF (len(line) < len_trim(parser%input_line))
THEN
827 CALL cp_warn(__location__, &
828 "The returned input line has more than "// &
829 trim(adjustl(cp_to_string(len(line))))// &
830 " characters and is therefore too long to fit in the "// &
831 "specified variable"// &
841 IF (begin) parser%icol = 0
845 IF (
PRESENT(line)) line = parser%input_line
846 IF (.NOT. begin)
CALL parser_next_token(parser)
862 ELEMENTAL FUNCTION integer_object(string)
RESULT(contains_integer_object)
864 CHARACTER(LEN=*),
INTENT(IN) :: string
865 LOGICAL :: contains_integer_object
867 INTEGER :: i, idots, istar, n
869 contains_integer_object = .true.
873 contains_integer_object = .false.
877 idots = index(string(1:n),
"..")
878 istar = index(string(1:n),
"*")
881 contains_integer_object = is_integer(string(1:idots - 1)) .AND. &
882 is_integer(string(idots + 2:n))
883 ELSE IF (istar /= 0)
THEN
885 DO WHILE (istar /= 0)
886 IF (.NOT. is_integer(string(i:i + istar - 2)))
THEN
887 contains_integer_object = .false.
891 istar = index(string(i:n),
"*")
893 contains_integer_object = is_integer(string(i:n))
895 contains_integer_object = is_integer(string(1:n))
898 END FUNCTION integer_object
905 ELEMENTAL FUNCTION is_integer(string)
RESULT(check)
907 CHARACTER(LEN=*),
INTENT(IN) :: string
920 IF ((index(
"+-", string(1:1)) > 0) .AND. (n == 1))
THEN
925 IF (index(
"+-0123456789", string(1:1)) == 0)
THEN
931 IF (index(
"0123456789", string(i:i)) == 0)
THEN
937 END FUNCTION is_integer
951 SUBROUTINE parser_get_integer(parser, object, newline, skip_lines, &
952 string_length, at_end)
954 TYPE(cp_parser_type),
INTENT(INOUT) :: parser
955 INTEGER,
INTENT(OUT) :: object
956 LOGICAL,
INTENT(IN),
OPTIONAL :: newline
957 INTEGER,
INTENT(IN),
OPTIONAL :: skip_lines, string_length
958 LOGICAL,
INTENT(out),
OPTIONAL :: at_end
960 CHARACTER(LEN=max_line_length) :: error_message
964 IF (
PRESENT(skip_lines))
THEN
970 IF (
PRESENT(newline))
THEN
971 IF (newline) nline = nline + 1
975 IF (
PRESENT(at_end))
THEN
977 IF (my_at_end)
RETURN
978 ELSE IF (my_at_end)
THEN
982 IF (parser%ilist%in_use)
THEN
985 IF (
PRESENT(string_length))
THEN
986 CALL parser_next_token(parser, string_length=string_length)
988 CALL parser_next_token(parser)
990 IF (parser%icol1 > parser%icol2)
THEN
991 parser%icol1 = parser%icol
992 parser%icol2 = parser%icol
993 CALL cp_abort(__location__, &
994 "An integer type object was expected, found end of line"// &
998 IF (index(parser%input_line(parser%icol1:parser%icol2),
"..") /= 0)
THEN
999 CALL ilist_setup(parser%ilist, parser%input_line(parser%icol1:parser%icol2))
1003 IF (integer_object(parser%input_line(parser%icol1:parser%icol2)))
THEN
1004 IF (parser%ilist%in_use)
THEN
1005 object = parser%ilist%ipresent
1008 CALL read_integer_object(parser%input_line(parser%icol1:parser%icol2), object, error_message)
1009 IF (len_trim(error_message) > 0)
THEN
1014 CALL cp_abort(__location__, &
1015 "An integer type object was expected, found <"// &
1016 parser%input_line(parser%icol1:parser%icol2)//
">"// &
1020 END SUBROUTINE parser_get_integer
1036 SUBROUTINE parser_get_logical(parser, object, newline, skip_lines, &
1037 string_length, at_end)
1039 TYPE(cp_parser_type),
INTENT(INOUT) :: parser
1040 LOGICAL,
INTENT(OUT) :: object
1041 LOGICAL,
INTENT(IN),
OPTIONAL :: newline
1042 INTEGER,
INTENT(IN),
OPTIONAL :: skip_lines, string_length
1043 LOGICAL,
INTENT(out),
OPTIONAL :: at_end
1045 CHARACTER(LEN=max_line_length) :: input_string
1046 INTEGER :: input_string_length, nline
1047 LOGICAL :: my_at_end
1049 cpassert(.NOT. parser%ilist%in_use)
1050 IF (
PRESENT(skip_lines))
THEN
1056 IF (
PRESENT(newline))
THEN
1057 IF (newline) nline = nline + 1
1061 IF (
PRESENT(at_end))
THEN
1063 IF (my_at_end)
RETURN
1064 ELSE IF (my_at_end)
THEN
1068 IF (
PRESENT(string_length))
THEN
1069 CALL parser_next_token(parser, string_length=string_length)
1071 CALL parser_next_token(parser)
1074 input_string_length = parser%icol2 - parser%icol1 + 1
1076 IF (input_string_length == 0)
THEN
1077 parser%icol1 = parser%icol
1078 parser%icol2 = parser%icol
1079 CALL cp_abort(__location__, &
1080 "A string representing a logical object was expected, found end of line"// &
1084 input_string(:input_string_length) = parser%input_line(parser%icol1:parser%icol2)
1088 SELECT CASE (trim(input_string))
1089 CASE (
"0",
"F",
".F.",
"FALSE",
".FALSE.",
"N",
"NO",
"OFF")
1091 CASE (
"1",
"T",
".T.",
"TRUE",
".TRUE.",
"Y",
"YES",
"ON")
1094 CALL cp_abort(__location__, &
1095 "A string representing a logical object was expected, found <"// &
1099 END SUBROUTINE parser_get_logical
1113 SUBROUTINE parser_get_real(parser, object, newline, skip_lines, string_length, &
1116 TYPE(cp_parser_type),
INTENT(INOUT) :: parser
1117 REAL(kind=
dp),
INTENT(OUT) :: object
1118 LOGICAL,
INTENT(IN),
OPTIONAL :: newline
1119 INTEGER,
INTENT(IN),
OPTIONAL :: skip_lines, string_length
1120 LOGICAL,
INTENT(out),
OPTIONAL :: at_end
1122 CHARACTER(LEN=max_line_length) :: error_message
1124 LOGICAL :: my_at_end
1126 cpassert(.NOT. parser%ilist%in_use)
1128 IF (
PRESENT(skip_lines))
THEN
1134 IF (
PRESENT(newline))
THEN
1135 IF (newline) nline = nline + 1
1139 IF (
PRESENT(at_end))
THEN
1141 IF (my_at_end)
RETURN
1142 ELSE IF (my_at_end)
THEN
1146 IF (
PRESENT(string_length))
THEN
1147 CALL parser_next_token(parser, string_length=string_length)
1149 CALL parser_next_token(parser)
1152 IF (parser%icol1 > parser%icol2)
THEN
1153 parser%icol1 = parser%icol
1154 parser%icol2 = parser%icol
1155 CALL cp_abort(__location__, &
1156 "A floating point type object was expected, found end of the line"// &
1161 CALL read_float_object(parser%input_line(parser%icol1:parser%icol2), object, error_message)
1162 IF (len_trim(error_message) > 0)
THEN
1166 END SUBROUTINE parser_get_real
1181 SUBROUTINE parser_get_string(parser, object, lower_to_upper, newline, skip_lines, &
1182 string_length, at_end)
1184 TYPE(cp_parser_type),
INTENT(INOUT) :: parser
1185 CHARACTER(LEN=*),
INTENT(OUT) :: object
1186 LOGICAL,
INTENT(IN),
OPTIONAL :: lower_to_upper, newline
1187 INTEGER,
INTENT(IN),
OPTIONAL :: skip_lines, string_length
1188 LOGICAL,
INTENT(out),
OPTIONAL :: at_end
1190 INTEGER :: input_string_length, nline
1191 LOGICAL :: my_at_end
1194 cpassert(.NOT. parser%ilist%in_use)
1195 IF (
PRESENT(skip_lines))
THEN
1201 IF (
PRESENT(newline))
THEN
1202 IF (newline) nline = nline + 1
1206 IF (
PRESENT(at_end))
THEN
1208 IF (my_at_end)
RETURN
1209 ELSE IF (my_at_end)
THEN
1210 CALL cp_abort(__location__, &
1214 IF (
PRESENT(string_length))
THEN
1215 CALL parser_next_token(parser, string_length=string_length)
1217 CALL parser_next_token(parser)
1220 input_string_length = parser%icol2 - parser%icol1 + 1
1222 IF (input_string_length <= 0)
THEN
1223 CALL cp_abort(__location__, &
1224 "A string type object was expected, found end of line"// &
1226 ELSE IF (input_string_length > len(object))
THEN
1227 CALL cp_abort(__location__, &
1228 "The input string <"//parser%input_line(parser%icol1:parser%icol2)// &
1229 "> has more than "//cp_to_string(len(object))// &
1230 " characters and is therefore too long to fit in the "// &
1232 object = parser%input_line(parser%icol1:parser%icol1 + len(object) - 1)
1234 object(:input_string_length) = parser%input_line(parser%icol1:parser%icol2)
1238 IF (
PRESENT(lower_to_upper))
THEN
1239 IF (lower_to_upper)
CALL uppercase(object)
1242 END SUBROUTINE parser_get_string
1259 CHARACTER(LEN=*),
INTENT(IN) :: string
1260 REAL(kind=
dp),
INTENT(OUT) :: object
1261 CHARACTER(LEN=*),
INTENT(OUT) :: error_message
1263 INTEGER,
PARAMETER :: maxlen = 5
1265 CHARACTER(LEN=maxlen) :: func
1266 INTEGER :: i, ileft, iop, iright, is, islash, &
1268 LOGICAL :: parsing_done
1269 REAL(kind=
dp) :: fsign, z
1276 n = len_trim(string)
1278 parsing_done = .false.
1280 DO WHILE (.NOT. parsing_done)
1282 islash = index(string(i:n),
"/")
1283 istar = index(string(i:n),
"*")
1284 IF ((islash == 0) .AND. (istar == 0))
THEN
1287 parsing_done = .true.
1288 ELSE IF ((islash > 0) .AND. (istar > 0))
THEN
1289 iop = min(islash, istar)
1290 ELSE IF (islash > 0)
THEN
1292 ELSE IF (istar > 0)
THEN
1295 ileft = index(string(i:min(n, i + maxlen + 1)),
"(")
1298 is = ichar(string(i:i))
1302 func = string(i + 1:i + ileft - 2)
1305 func = string(i + 1:i + ileft - 2)
1308 func = string(i:i + ileft - 2)
1310 iright = index(string(i:n),
")")
1311 READ (unit=string(i + ileft:i + iright - 2), fmt=*, iostat=istat) z
1312 IF (istat /= 0)
THEN
1313 error_message =
"A floating point type object as argument for function <"// &
1314 trim(func)//
"> is expected, found <"// &
1315 string(i + ileft:i + iright - 2)//
">"
1334 error_message =
"Unknown function <"//trim(func)//
"> found"
1338 READ (unit=string(i:i + iop - 2), fmt=*, iostat=istat) z
1339 IF (istat /= 0)
THEN
1340 error_message =
"A floating point type object was expected, found <"// &
1341 string(i:i + iop - 2)//
">"
1347 ELSE IF (string(i - 1:i - 1) ==
"*")
THEN
1350 IF (z == 0.0_dp)
THEN
1351 error_message =
"Division by zero found <"// &
1352 string(i:i + iop - 2)//
">"
1375 CHARACTER(LEN=*),
INTENT(IN) :: string
1376 INTEGER,
INTENT(OUT) :: object
1377 CHARACTER(LEN=*),
INTENT(OUT) :: error_message
1379 CHARACTER(LEN=20) :: fmtstr
1380 INTEGER :: i, iop, istat, n
1381 INTEGER(KIND=int_8) :: iz8, object8
1382 LOGICAL :: parsing_done
1388 n = len_trim(string)
1390 parsing_done = .false.
1392 DO WHILE (.NOT. parsing_done)
1396 iop = index(string(i:n),
"*")
1403 parsing_done = .true.
1406 IF (iop - 1 > 0)
THEN
1410 WRITE (fmtstr, fmt=
'(A,I0,A)')
'(I', iop - 1,
')'
1411 READ (unit=string(i:i + iop - 2), fmt=fmtstr, iostat=istat) iz8
1413 IF (istat /= 0)
THEN
1414 error_message =
"An integer type object was expected, found <"// &
1415 string(i:i + iop - 2)//
">"
1421 object8 = object8*iz8
1423 IF (abs(object8) > huge(0))
THEN
1424 error_message =
"The specified integer number <"//string(i:i + iop - 2)// &
1425 "> exceeds the allowed range of a 32-bit integer number."
1430 object = int(object8)
various routines to log and control the output. The idea is that decisions about where to log should ...
a module to allow simple buffering of read lines of a parser
recursive subroutine, public copy_buffer_type(buffer_in, buffer_out, force)
Copies buffer types.
subroutine, public initialize_sub_buffer(sub_buffer, buffer)
Initializes sub buffer structure.
subroutine, public finalize_sub_buffer(sub_buffer, buffer)
Finalizes sub buffer structure.
a module to allow simple internal preprocessing in input files.
subroutine, public ilist_update(ilist)
updates the integer listing type
subroutine, public ilist_setup(ilist, token)
setup the integer listing type
subroutine, public ilist_reset(ilist)
updates the integer listing type
a module to allow simple internal preprocessing in input files.
subroutine, public inpp_expand_variables(inpp, input_line, input_file_name, input_line_number)
expand all ${VAR} or $VAR variable entries on the input string (LTR, no nested vars)
subroutine, public inpp_end_include(inpp, input_file_name, input_line_number, input_unit)
Restore older file status from stack after EOF on include file.
subroutine, public inpp_process_directive(inpp, input_line, input_file_name, input_line_number, input_unit)
process internal preprocessor directives like @INCLUDE, @SET, @IF/@ENDIF
Utility routines to read data from files. Kept as close as possible to the old parser because.
subroutine, public parser_read_line(parser, nline, at_end)
Read the next line from a logical unit "unit" (I/O node only). Skip (nline-1) lines and skip also all...
elemental subroutine, public read_integer_object(string, object, error_message)
Returns an integer number read from a string including products of integer numbers like iz1*iz2*iz3.
subroutine, public parser_skip_space(parser)
Skips the whitespaces.
subroutine, public parser_get_next_line(parser, nline, at_end)
Read the next input line and broadcast the input information. Skip (nline-1) lines and skip also all ...
character(len=3) function, public parser_test_next_token(parser, string_length)
Test next input object.
character(len=default_path_length+default_string_length) function, public parser_location(parser)
return a description of the part of the file actually parsed
elemental subroutine, public read_float_object(string, object, error_message)
Returns a floating point number read from a string including fraction like z1/z2.
subroutine, public parser_search_string(parser, string, ignore_case, found, line, begin_line, search_from_begin_of_file)
Search a string pattern in a file defined by its logical unit number "unit". A case sensitive search ...
Utility routines to read data from files. Kept as close as possible to the old parser because.
subroutine, public parser_reset(parser)
Resets the parser: rewinding the unit and re-initializing all parser structures.
Defines the basic variable types.
integer, parameter, public max_line_length
integer, parameter, public int_8
integer, parameter, public dp
integer, parameter, public default_string_length
integer, parameter, public default_path_length
Definition of mathematical constants and functions.
real(kind=dp), parameter, public radians
Interface to the message passing library MPI.
Utilities for string manipulations.
elemental logical function, public is_whitespace(testchar)
returns .true. if the character passed is a whitespace char.
elemental subroutine, public uppercase(string)
Convert all lower case characters in a string to upper case.