46#include "../base/base_uses.f90"
51 LOGICAL,
PRIVATE,
PARAMETER :: debug_this_module = .true.
52 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'input_parsing'
70 LOGICAL,
INTENT(in),
OPTIONAL :: root_section
72 CHARACTER(len=*),
PARAMETER :: routinen =
'section_vals_parse'
74 CHARACTER(len=max_line_length) :: token
75 INTEGER :: desc_level, handle, ik, imatch, irs, is, &
77 LOGICAL :: at_end, compatible_end, root_sect, &
85 CALL timeset(routinen, handle)
87 NULLIFY (previous_list, previous_last)
90 IF (
PRESENT(root_section)) root_sect = root_section
92 cpassert(
ASSOCIATED(section_vals))
95 cpassert(section_vals%ref_count > 0)
96 IF (root_sect .AND. parser%icol1 > parser%icol2)
THEN
97 CALL cp_abort(__location__, &
98 "Error 1: this routine must be called just after having parsed the start of the section " &
101 section => section_vals%section
103 token = trim(adjustl(parser%input_line(parser%icol1:parser%icol2)))
105 IF (token /= parser%section_character//section%name)
THEN
106 CALL cp_abort(__location__, &
107 "Error 2: this routine must be called just after having parsed the start of the section " &
111 IF (.NOT. section%repeats .AND.
SIZE(section_vals%values, 2) /= 0)
THEN
112 CALL cp_abort(__location__,
"Section "//trim(section%name)// &
116 irs =
SIZE(section_vals%values, 2)
118 IF (
ALLOCATED(section%deprecation_notice))
THEN
119 CALL cp_warn(__location__, &
120 "The specified section '"//trim(section%name)// &
121 "' is deprecated and may be removed in a future version: "// &
122 section%deprecation_notice)
125 IF (
ASSOCIATED(section%keywords(-1)%keyword))
THEN
126 keyword => section%keywords(-1)%keyword
129 CALL val_create_parsing(el, type_of_var=keyword%type_of_var, &
130 n_var=keyword%n_var, default_value=keyword%lone_keyword_value, &
131 enum=keyword%enum, unit=keyword%unit, &
132 default_units=default_units, &
136 section_vals%values(-1, irs)%list => new_val
141 lower_to_upper=.true., at_end=at_end)
142 token = trim(adjustl(token))
145 CALL cp_abort(__location__, &
146 "unexpected end of file while parsing section "// &
151 IF (token(1:1) == parser%section_character)
THEN
152 IF (token ==
"&END")
THEN
154 compatible_end = .true.
157 lower_to_upper=.true.)
158 IF (token /=
"SECTION" .AND. token /= section%name)
THEN
159 compatible_end = .false.
164 lower_to_upper=.true.)
165 IF (token /= section%name)
THEN
166 print *, trim(token),
"/=", trim(section%name)
167 compatible_end = .false.
170 IF (.NOT. compatible_end)
THEN
171 CALL cp_abort(__location__, &
172 "non-compatible end of section "//trim(section%name)//
" "// &
181 default_units=default_units, parser=parser)
184 IF (output_unit > 0)
THEN
185 WRITE (output_unit, *)
186 WRITE (output_unit,
'(T2,A)')
"Possible matches for unknown subsection "
187 WRITE (output_unit, *)
188 WRITE (output_unit,
'(T2,A)') trim(token(2:))
189 WRITE (output_unit, *)
196 CALL cp_abort(__location__, &
197 "unknown subsection "//trim(token(2:))//
" of section " &
198 //trim(section%name))
202 lower_to_upper=.true.)
203 IF (token(1:1) == parser%section_character)
THEN
204 IF (token ==
"&END")
THEN
213 IF (token ==
"DESCRIBE")
THEN
214 IF (output_unit > 0)
WRITE (output_unit,
"(/,' ****** DESCRIPTION ******',/)")
219 whole_section = .true.
221 whole_section = .false.
223 lower_to_upper=.true.)
225 IF (.NOT.
ASSOCIATED(keyword))
THEN
226 CALL cp_warn(__location__, &
227 "unknown keyword to describe "//trim(token)// &
228 " in section "//trim(section%name))
233 IF (whole_section)
THEN
234 CALL section_describe(section, output_unit, desc_level, hide_root=.NOT. root_sect)
236 IF (output_unit > 0)
WRITE (output_unit,
"(/,' ****** =========== ******',/)")
241 parser%icol = parser%icol1 - 1
243 IF (.NOT.
ASSOCIATED(section%keywords(0)%keyword))
THEN
244 IF (output_unit > 0)
THEN
245 WRITE (output_unit, *)
246 WRITE (output_unit,
'(T2,A)')
"Possible matches for unknown keyword "
247 WRITE (output_unit, *)
248 WRITE (output_unit,
'(T2,A)') trim(token)
249 WRITE (output_unit, *)
253 WRITE (output_unit,
'(T2,A,1X,I0)') &
257 CALL cp_abort(__location__, &
258 "found an unknown keyword "//trim(token)// &
259 " in section "//trim(section%name))
262 keyword => section%keywords(ik)%keyword
263 IF (
ASSOCIATED(keyword))
THEN
264 IF (keyword%removed)
THEN
265 IF (
ALLOCATED(keyword%deprecation_notice))
THEN
266 CALL cp_abort(__location__, &
267 "The specified keyword '"//trim(token)//
"' is not available anymore: "// &
268 keyword%deprecation_notice)
270 CALL cp_abort(__location__, &
271 "The specified keyword '"//trim(token)// &
272 "' is not available anymore, please consult the manual.")
276 IF (
ALLOCATED(keyword%deprecation_notice))
THEN
277 CALL cp_warn(__location__, &
278 "The specified keyword '"//trim(token)// &
279 "' is deprecated and may be removed in a future version: "// &
280 keyword%deprecation_notice)
284 IF (ik /= 0 .AND. keyword%type_of_var ==
lchar_t)
THEN
287 CALL val_create_parsing(el, type_of_var=keyword%type_of_var, &
288 n_var=keyword%n_var, default_value=keyword%lone_keyword_value, &
289 enum=keyword%enum, unit=keyword%unit, &
290 default_units=default_units, parser=parser)
291 IF (
ASSOCIATED(el))
THEN
294 last_val => section_vals%values(ik, irs)%list
295 IF (.NOT.
ASSOCIATED(last_val))
THEN
296 section_vals%values(ik, irs)%list => new_val
298 IF (.NOT. keyword%repeats)
THEN
299 CALL cp_abort(__location__, &
300 "Keyword "//trim(token)// &
301 " in section "//trim(section%name)//
" should not repeat.")
303 IF (
ASSOCIATED(last_val, previous_list))
THEN
304 last_val => previous_last
306 previous_list => last_val
308 DO WHILE (
ASSOCIATED(last_val%rest))
309 last_val => last_val%rest
311 last_val%rest => new_val
312 previous_last => new_val
319 CALL timestop(handle)
336 SUBROUTINE val_create_parsing(val, type_of_var, n_var, enum, &
337 parser, unit, default_units, default_value)
339 INTEGER,
INTENT(in) :: type_of_var, n_var
344 TYPE(
val_type),
OPTIONAL,
POINTER :: default_value
346 CHARACTER(len=*),
PARAMETER :: routinen =
'val_create_parsing'
348 CHARACTER(len=default_string_length) :: c_val, info, location
349 CHARACTER(len=default_string_length), &
350 DIMENSION(:),
POINTER :: c_val_p
351 INTEGER :: handle, i, i_val
352 INTEGER,
DIMENSION(:),
POINTER :: i_val_p
353 LOGICAL :: check, eol, l_val, quoted
354 LOGICAL,
DIMENSION(:),
POINTER :: l_val_p
355 REAL(kind=
dp) :: r_val
356 REAL(kind=
dp),
DIMENSION(:),
POINTER :: r_val_p
362 CALL timeset(routinen, handle)
364 cpassert(.NOT.
ASSOCIATED(val))
365 SELECT CASE (type_of_var)
370 IF (.NOT.
ASSOCIATED(default_value))
THEN
372 ALLOCATE (l_val_p(0))
375 CALL cp_abort(__location__, &
376 "no value was given and there is no default value"// &
380 cpassert(
ASSOCIATED(default_value%l_val))
381 CALL val_create(val, l_vals=default_value%l_val)
385 NULLIFY (l_last, l_first)
398 ALLOCATE (l_val_p(n_var))
403 IF (
ASSOCIATED(l_val_p))
THEN
410 IF (.NOT.
ASSOCIATED(default_value))
THEN
412 ALLOCATE (i_val_p(0))
415 CALL cp_abort(__location__, &
416 "no value was given and there is no default value"// &
420 check =
ASSOCIATED(default_value%i_val)
422 CALL val_create(val, i_vals=default_value%i_val)
426 NULLIFY (i_last, i_first)
439 ALLOCATE (i_val_p(n_var))
444 IF (
ASSOCIATED(i_val_p))
THEN
451 IF (.NOT.
ASSOCIATED(default_value))
THEN
453 ALLOCATE (r_val_p(0))
456 CALL cp_abort(__location__, &
457 "no value was given and there is no default value"// &
461 cpassert(
ASSOCIATED(default_value%r_val))
462 CALL val_create(val, r_vals=default_value%r_val)
466 NULLIFY (r_last, r_first)
468 CALL get_r_val(r_val, parser, unit, default_units, c_val)
472 CALL get_r_val(r_val, parser, unit, default_units, c_val)
481 ALLOCATE (r_val_p(n_var))
484 CALL get_r_val(r_val_p(i), parser, unit, default_units, c_val)
487 IF (
ASSOCIATED(r_val_p))
THEN
494 IF (
ASSOCIATED(default_value))
THEN
495 cpassert(
ASSOCIATED(default_value%c_val))
496 CALL val_create(val, c_vals=default_value%c_val)
497 ELSE IF (n_var < 1)
THEN
498 ALLOCATE (c_val_p(1))
502 CALL cp_abort(__location__, &
503 "no value was given and there is no default value"// &
508 cpassert(n_var == -1)
509 NULLIFY (c_last, c_first)
522 ALLOCATE (c_val_p(n_var))
527 IF (
ASSOCIATED(c_val_p))
THEN
532 IF (
ASSOCIATED(default_value))
THEN
533 CALL cp_abort(__location__, &
534 "input variables of type lchar_t cannot have a lone keyword attribute,"// &
535 " no value is interpreted as empty string"// &
539 CALL cp_abort(__location__, &
540 "input variables of type lchar_t cannot be repeated,"// &
541 " one always represent a whole line, till the end"// &
545 ALLOCATE (c_val_p(1))
548 NULLIFY (c_last, c_first)
550 IF (c_val(1:1) == parser%quote_character)
THEN
552 c_val(1:) = c_val(2:)
553 i = index(c_val, parser%quote_character)
568 i = index(c_val, parser%quote_character)
574 CALL cp_abort(__location__, &
575 "Quotation mark found which is not the first non-blank character. "// &
576 "Possibly the first quotation mark is missing?"// &
589 cpassert(
ASSOCIATED(c_val_p))
592 cpassert(
ASSOCIATED(enum))
595 IF (.NOT.
ASSOCIATED(default_value))
THEN
597 ALLOCATE (i_val_p(0))
600 CALL cp_abort(__location__, &
601 "no value was given and there is no default value"// &
605 cpassert(
ASSOCIATED(default_value%i_val))
606 CALL val_create(val, i_vals=default_value%i_val, &
607 enum=default_value%enum)
611 NULLIFY (i_last, i_first)
624 ALLOCATE (i_val_p(n_var))
630 IF (
ASSOCIATED(i_val_p))
THEN
631 CALL val_create(val, i_vals_ptr=i_val_p, enum=enum)
635 CALL cp_abort(__location__, &
636 "type "//
cp_to_string(type_of_var)//
"unknown to the parser")
641 CALL cp_abort(__location__, &
642 "found unexpected extra argument "//trim(info)//
" at "//location)
645 CALL timestop(handle)
647 END SUBROUTINE val_create_parsing
658 SUBROUTINE get_r_val(r_val, parser, unit, default_units, c_val)
659 REAL(kind=
dp),
INTENT(OUT) :: r_val
663 CHARACTER(len=default_string_length), &
664 INTENT(INOUT) :: c_val
669 IF (
ASSOCIATED(unit))
THEN
672 IF (c_val(1:1) /=
"[" .OR. c_val(len_trim(c_val):len_trim(c_val)) /=
"]")
THEN
673 CALL cp_abort(__location__, &
674 "Invalid unit specifier or function found when parsing a number: "// &
680 IF (c_val /=
"")
THEN
688 CALL cp_abort(__location__, &
689 "Incompatible units. Defined as ("// &
690 trim(
cp_unit_desc(unit))//
") specified in input as ("// &
691 trim(
cp_unit_desc(my_unit))//
"). These units are incompatible!")
695 IF (
ASSOCIATED(unit))
THEN
697 IF (.NOT. (
ASSOCIATED(my_unit, unit)))
THEN
703 END SUBROUTINE get_r_val
various routines to log and control the output. The idea is that decisions about where to log should ...
integer function, public cp_logger_get_default_io_unit(logger)
returns the unit nr for the ionode (-1 on all other processors) skips as well checks if the procs cal...
Utility routines to read data from files. Kept as close as possible to the old parser because.
subroutine, public parser_skip_space(parser)
Skips the whitespaces.
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
Utility routines to read data from files. Kept as close as possible to the old parser because.
character(len=cp_unit_desc_length) function, public cp_unit_desc(unit, defaults, accept_undefined)
returns the "name" of the given unit
real(kind=dp) function, public cp_unit_to_cp2k1(value, unit, defaults, power)
transform a value to the internal cp2k units
subroutine, public cp_unit_create(unit, string)
creates a unit parsing a string
logical function, public cp_unit_compatible(ref_unit, unit)
returs true if the two units are compatible
elemental subroutine, public cp_unit_release(unit)
releases the given unit
Defines the basic variable types.
integer, parameter, public max_line_length
integer, parameter, public dp
integer, parameter, public default_string_length
Utilities for string manipulations.
character(len=1), parameter, public newline
elemental subroutine, public uppercase(string)
Convert all lower case characters in a string to upper case.
stores the default units to be used