(git:b195825)
input_parsing.F
Go to the documentation of this file.
1 !--------------------------------------------------------------------------------------------------!
2 ! CP2K: A general program to perform molecular dynamics simulations !
3 ! Copyright 2000-2024 CP2K developers group <https://cp2k.org> !
4 ! !
5 ! SPDX-License-Identifier: GPL-2.0-or-later !
6 !--------------------------------------------------------------------------------------------------!
7 
8 ! **************************************************************************************************
9 !> \brief routines that parse the input
10 !> \par History
11 !> 06.2004 created
12 !> \author fawzi
13 ! **************************************************************************************************
15  USE cp_linked_list_input, ONLY: &
16  cp_create, cp_dealloc, cp_sll_char_type, cp_sll_int_type, cp_sll_logical_type, &
17  cp_sll_real_type, cp_sll_val_create, cp_sll_val_type, cp_to_array
19  cp_to_string
20  USE cp_parser_methods, ONLY: parser_get_object,&
24  USE cp_parser_types, ONLY: cp_parser_type
25  USE cp_units, ONLY: cp_unit_compatible,&
27  cp_unit_desc,&
29  cp_unit_set_type,&
31  cp_unit_type
33  enumeration_type
35  keyword_type
36  USE input_section_types, ONLY: &
40  USE input_val_types, ONLY: &
42  USE kinds, ONLY: default_string_length,&
43  dp,&
45  USE string_utilities, ONLY: uppercase
46 #include "../base/base_uses.f90"
47 
48  IMPLICIT NONE
49  PRIVATE
50 
51  LOGICAL, PRIVATE, PARAMETER :: debug_this_module = .true.
52  CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'input_parsing'
53 
54  PUBLIC :: section_vals_parse
55 !***
56 CONTAINS
57 
58 ! **************************************************************************************************
59 !> \brief ...
60 !> \param section_vals ...
61 !> \param parser ...
62 !> \param default_units ...
63 !> \param root_section if the root section should be parsed (defaults to true)
64 !> \author fawzi
65 ! **************************************************************************************************
66  RECURSIVE SUBROUTINE section_vals_parse(section_vals, parser, default_units, root_section)
67  TYPE(section_vals_type), POINTER :: section_vals
68  TYPE(cp_parser_type), INTENT(INOUT) :: parser
69  TYPE(cp_unit_set_type), INTENT(IN) :: default_units
70  LOGICAL, INTENT(in), OPTIONAL :: root_section
71 
72  CHARACTER(len=*), PARAMETER :: routinen = 'section_vals_parse'
73 
74  CHARACTER(len=max_line_length) :: token
75  INTEGER :: desc_level, handle, ik, imatch, irs, is, &
76  nsub, output_unit
77  LOGICAL :: at_end, compatible_end, root_sect, &
78  whole_section
79  TYPE(cp_sll_val_type), POINTER :: last_val, new_val, previous_last, &
80  previous_list
81  TYPE(keyword_type), POINTER :: keyword
82  TYPE(section_type), POINTER :: section
83  TYPE(val_type), POINTER :: el
84 
85  CALL timeset(routinen, handle)
86 
87  NULLIFY (previous_list, previous_last)
88 
89  root_sect = .true.
90  IF (PRESENT(root_section)) root_sect = root_section
91 
92  cpassert(ASSOCIATED(section_vals))
93  output_unit = cp_logger_get_default_io_unit()
94 
95  cpassert(section_vals%ref_count > 0)
96  IF (root_sect .AND. parser%icol1 > parser%icol2) &
97  CALL cp_abort(__location__, &
98  "Error 1: this routine must be called just after having parsed the start of the section " &
99  //trim(parser_location(parser)))
100  section => section_vals%section
101  IF (root_sect) THEN
102  token = trim(adjustl(parser%input_line(parser%icol1:parser%icol2))) ! Ignore leading or trailing blanks
103  CALL uppercase(token)
104  IF (token /= parser%section_character//section%name) &
105  CALL cp_abort(__location__, &
106  "Error 2: this routine must be called just after having parsed the start of the section " &
107  //trim(parser_location(parser)))
108  END IF
109  IF (.NOT. section%repeats .AND. SIZE(section_vals%values, 2) /= 0) &
110  CALL cp_abort(__location__, "Section "//trim(section%name)// &
111  " should not repeat "//trim(parser_location(parser)))
112  CALL section_vals_add_values(section_vals)
113  irs = SIZE(section_vals%values, 2)
114 
115  IF (ASSOCIATED(section%keywords(-1)%keyword)) THEN ! reads section params
116  keyword => section%keywords(-1)%keyword
117  NULLIFY (el)
118  IF (keyword%type_of_var == lchar_t) CALL parser_skip_space(parser)
119  CALL val_create_parsing(el, type_of_var=keyword%type_of_var, &
120  n_var=keyword%n_var, default_value=keyword%lone_keyword_value, &
121  enum=keyword%enum, unit=keyword%unit, &
122  default_units=default_units, &
123  parser=parser)
124  NULLIFY (new_val)
125  CALL cp_sll_val_create(new_val, el)
126  section_vals%values(-1, irs)%list => new_val
127  NULLIFY (el)
128  END IF
129  DO WHILE (.true.)
130  CALL parser_get_object(parser, token, newline=.true., &
131  lower_to_upper=.true., at_end=at_end)
132  token = trim(adjustl(token)) ! Ignore leading or trailing blanks
133  IF (at_end) THEN
134  IF (root_sect) &
135  CALL cp_abort(__location__, &
136  "unexpected end of file while parsing section "// &
137  trim(section%name)//" "//trim(parser_location(parser)))
138  EXIT
139  END IF
140  IF (token(1:1) == parser%section_character) THEN
141  IF (token == "&END") THEN
142  ! end of section
143  compatible_end = .true.
144  IF (parser_test_next_token(parser) /= "EOL") THEN
145  CALL parser_get_object(parser, token, newline=.false., &
146  lower_to_upper=.true.)
147  IF (token /= "SECTION" .AND. token /= section%name) THEN
148  compatible_end = .false.
149  END IF
150  END IF
151  IF (parser_test_next_token(parser) /= "EOL") THEN
152  CALL parser_get_object(parser, token, newline=.false., &
153  lower_to_upper=.true.)
154  IF (token /= section%name) THEN
155  print *, trim(token), "/=", trim(section%name)
156  compatible_end = .false.
157  END IF
158  END IF
159  IF (.NOT. compatible_end) THEN
160  CALL cp_abort(__location__, &
161  "non-compatible end of section "//trim(section%name)//" "// &
162  trim(parser_location(parser)))
163  END IF
164  ! RETURN
165  EXIT
166  END IF
167  is = section_get_subsection_index(section, token(2:))
168  IF (is > 0) THEN
169  CALL section_vals_parse(section_vals%subs_vals(is, irs)%section_vals, &
170  default_units=default_units, parser=parser)
171  ELSE
172  ! unknown subsection
173  IF (output_unit > 0) THEN
174  WRITE (output_unit, *)
175  WRITE (output_unit, '(T2,A)') "Possible matches for unknown subsection "
176  WRITE (output_unit, *)
177  WRITE (output_unit, '(T2,A)') trim(token(2:))
178  WRITE (output_unit, *)
179  CALL section_typo_match(typo_match_section, trim(section%name), trim(token(2:)), "", &
181  DO imatch = 1, SIZE(typo_matching_rank)
182  WRITE (output_unit, '(T2,A,1X,I0)') trim(typo_matching_line(imatch))//" score: ", typo_matching_rank(imatch)
183  END DO
184  END IF
185  CALL cp_abort(__location__, &
186  "unknown subsection "//trim(token(2:))//" of section " &
187  //trim(section%name))
188  nsub = 1
189  DO WHILE (nsub > 0)
190  CALL parser_get_object(parser, token, newline=.true., &
191  lower_to_upper=.true.)
192  IF (token(1:1) == parser%section_character) THEN
193  IF (token == "&END") THEN
194  nsub = nsub - 1
195  ELSE
196  nsub = nsub + 1
197  END IF
198  END IF
199  END DO
200  END IF
201  ELSE ! token is a keyword
202  IF (token == "DESCRIBE") THEN
203  IF (output_unit > 0) WRITE (output_unit, "(/,' ****** DESCRIPTION ******',/)")
204  desc_level = 3
205  IF (parser_test_next_token(parser) == "INT") THEN
206  CALL parser_get_object(parser, desc_level)
207  END IF
208  whole_section = .true.
209  DO WHILE (parser_test_next_token(parser) == "STR")
210  whole_section = .false.
211  CALL parser_get_object(parser, token, newline=.false., &
212  lower_to_upper=.true.)
213  keyword => section_get_keyword(section, token)
214  IF (.NOT. ASSOCIATED(keyword)) THEN
215  CALL cp_warn(__location__, &
216  "unknown keyword to describe "//trim(token)// &
217  " in section "//trim(section%name))
218  ELSE
219  CALL keyword_describe(keyword, output_unit, desc_level)
220  END IF
221  END DO
222  IF (whole_section) THEN
223  CALL section_describe(section, output_unit, desc_level, hide_root=.NOT. root_sect)
224  END IF
225  IF (output_unit > 0) WRITE (output_unit, "(/,' ****** =========== ******',/)")
226 
227  ELSE ! token is a "normal" keyword
228  ik = section_get_keyword_index(section, token)
229  IF (ik < 1) THEN ! don't accept pseudo keyword names
230  parser%icol = parser%icol1 - 1 ! re-read also the actual token
231  ik = 0
232  IF (.NOT. ASSOCIATED(section%keywords(0)%keyword)) THEN
233  IF (output_unit > 0) THEN
234  WRITE (output_unit, *)
235  WRITE (output_unit, '(T2,A)') "Possible matches for unknown keyword "
236  WRITE (output_unit, *)
237  WRITE (output_unit, '(T2,A)') trim(token)
238  WRITE (output_unit, *)
239  CALL section_typo_match(typo_match_section, trim(section%name), trim(token), "", &
241  DO imatch = 1, SIZE(typo_matching_rank)
242  WRITE (output_unit, '(T2,A,1X,I0)') &
243  trim(typo_matching_line(imatch))//" score: ", typo_matching_rank(imatch)
244  END DO
245  END IF
246  CALL cp_abort(__location__, &
247  "found an unknown keyword "//trim(token)// &
248  " in section "//trim(section%name))
249  END IF
250  END IF
251  keyword => section%keywords(ik)%keyword
252  IF (ASSOCIATED(keyword)) THEN
253  IF (keyword%removed) THEN
254  IF (ALLOCATED(keyword%deprecation_notice)) THEN
255  CALL cp_abort(__location__, &
256  "The specified keyword '"//trim(token)//"' is not available anymore: "// &
257  keyword%deprecation_notice)
258  ELSE
259  CALL cp_abort(__location__, &
260  "The specified keyword '"//trim(token)// &
261  "' is not available anymore, please consult the manual.")
262  END IF
263  END IF
264 
265  IF (ALLOCATED(keyword%deprecation_notice)) &
266  CALL cp_warn(__location__, &
267  "The specified keyword '"//trim(token)// &
268  "' is deprecated and may be removed in a future version: "// &
269  keyword%deprecation_notice//".")
270 
271  NULLIFY (el)
272  IF (ik /= 0 .AND. keyword%type_of_var == lchar_t) &
273  CALL parser_skip_space(parser)
274  CALL val_create_parsing(el, type_of_var=keyword%type_of_var, &
275  n_var=keyword%n_var, default_value=keyword%lone_keyword_value, &
276  enum=keyword%enum, unit=keyword%unit, &
277  default_units=default_units, parser=parser)
278  IF (ASSOCIATED(el)) THEN
279  NULLIFY (new_val)
280  CALL cp_sll_val_create(new_val, el)
281  last_val => section_vals%values(ik, irs)%list
282  IF (.NOT. ASSOCIATED(last_val)) THEN
283  section_vals%values(ik, irs)%list => new_val
284  ELSE
285  IF (.NOT. keyword%repeats) &
286  CALL cp_abort(__location__, &
287  "Keyword "//trim(token)// &
288  " in section "//trim(section%name)//" should not repeat.")
289  IF (ASSOCIATED(last_val, previous_list)) THEN
290  last_val => previous_last
291  ELSE
292  previous_list => last_val
293  END IF
294  DO WHILE (ASSOCIATED(last_val%rest))
295  last_val => last_val%rest
296  END DO
297  last_val%rest => new_val
298  previous_last => new_val
299  END IF
300  END IF
301  END IF
302  END IF
303  END IF
304  END DO
305  CALL timestop(handle)
306  END SUBROUTINE section_vals_parse
307 
308 ! **************************************************************************************************
309 !> \brief creates a val_type object by parsing the values
310 !> \param val the value that will be created
311 !> \param type_of_var type of the value to be created
312 !> \param n_var number of values to be parsed (-1: undefined)
313 !> \param enum ...
314 !> \param parser the parser from where the values should be read
315 !> \param unit ...
316 !> \param default_units ...
317 !> \param default_value a default value if nothing is found (can be null)
318 !> \author fawzi
319 !> \note
320 !> - no_t does not create a value
321 ! **************************************************************************************************
322  SUBROUTINE val_create_parsing(val, type_of_var, n_var, enum, &
323  parser, unit, default_units, default_value)
324  TYPE(val_type), POINTER :: val
325  INTEGER, INTENT(in) :: type_of_var, n_var
326  TYPE(enumeration_type), POINTER :: enum
327  TYPE(cp_parser_type), INTENT(INOUT) :: parser
328  TYPE(cp_unit_type), POINTER :: unit
329  TYPE(cp_unit_set_type), INTENT(IN) :: default_units
330  TYPE(val_type), OPTIONAL, POINTER :: default_value
331 
332  CHARACTER(len=*), PARAMETER :: routinen = 'val_create_parsing'
333 
334  CHARACTER(len=default_string_length) :: c_val, info, location
335  CHARACTER(len=default_string_length), &
336  DIMENSION(:), POINTER :: c_val_p
337  INTEGER :: handle, i, i_val
338  INTEGER, DIMENSION(:), POINTER :: i_val_p
339  LOGICAL :: check, eol, l_val, quoted
340  LOGICAL, DIMENSION(:), POINTER :: l_val_p
341  REAL(kind=dp) :: r_val
342  REAL(kind=dp), DIMENSION(:), POINTER :: r_val_p
343  TYPE(cp_sll_char_type), POINTER :: c_first, c_last, c_new
344  TYPE(cp_sll_int_type), POINTER :: i_first, i_last, i_new
345  TYPE(cp_sll_logical_type), POINTER :: l_first, l_last, l_new
346  TYPE(cp_sll_real_type), POINTER :: r_first, r_last, r_new
347 
348  CALL timeset(routinen, handle)
349 
350  cpassert(.NOT. ASSOCIATED(val))
351  SELECT CASE (type_of_var)
352  CASE (no_t)
353  CASE (logical_t)
354  NULLIFY (l_val_p)
355  IF (parser_test_next_token(parser) == "EOL") THEN
356  IF (.NOT. ASSOCIATED(default_value)) THEN
357  IF (n_var < 1) THEN
358  ALLOCATE (l_val_p(0))
359  CALL val_create(val, l_vals_ptr=l_val_p)
360  ELSE
361  CALL cp_abort(__location__, &
362  "no value was given and there is no default value"// &
363  trim(parser_location(parser)))
364  END IF
365  ELSE
366  cpassert(ASSOCIATED(default_value%l_val))
367  CALL val_create(val, l_vals=default_value%l_val)
368  END IF
369  ELSE
370  IF (n_var < 1) THEN
371  NULLIFY (l_last, l_first)
372  CALL parser_get_object(parser, l_val)
373  CALL cp_create(l_first, l_val)
374  l_last => l_first
375  DO WHILE (parser_test_next_token(parser) /= "EOL")
376  CALL parser_get_object(parser, l_val)
377  CALL cp_create(l_new, l_val)
378  l_last%rest => l_new
379  l_last => l_new
380  END DO
381  l_val_p => cp_to_array(l_first)
382  CALL cp_dealloc(l_first)
383  ELSE
384  ALLOCATE (l_val_p(n_var))
385  DO i = 1, n_var
386  CALL parser_get_object(parser, l_val_p(i))
387  END DO
388  END IF
389  IF (ASSOCIATED(l_val_p)) THEN
390  CALL val_create(val, l_vals_ptr=l_val_p)
391  END IF
392  END IF
393  CASE (integer_t)
394  NULLIFY (i_val_p)
395  IF (parser_test_next_token(parser) == "EOL") THEN
396  IF (.NOT. ASSOCIATED(default_value)) THEN
397  IF (n_var < 1) THEN
398  ALLOCATE (i_val_p(0))
399  CALL val_create(val, i_vals_ptr=i_val_p)
400  ELSE
401  CALL cp_abort(__location__, &
402  "no value was given and there is no default value"// &
403  trim(parser_location(parser)))
404  END IF
405  ELSE
406  check = ASSOCIATED(default_value%i_val)
407  cpassert(check)
408  CALL val_create(val, i_vals=default_value%i_val)
409  END IF
410  ELSE
411  IF (n_var < 1) THEN
412  NULLIFY (i_last, i_first)
413  CALL parser_get_object(parser, i_val)
414  CALL cp_create(i_first, i_val)
415  i_last => i_first
416  DO WHILE (parser_test_next_token(parser) /= "EOL")
417  CALL parser_get_object(parser, i_val)
418  CALL cp_create(i_new, i_val)
419  i_last%rest => i_new
420  i_last => i_new
421  END DO
422  i_val_p => cp_to_array(i_first)
423  CALL cp_dealloc(i_first)
424  ELSE
425  ALLOCATE (i_val_p(n_var))
426  DO i = 1, n_var
427  CALL parser_get_object(parser, i_val_p(i))
428  END DO
429  END IF
430  IF (ASSOCIATED(i_val_p)) THEN
431  CALL val_create(val, i_vals_ptr=i_val_p)
432  END IF
433  END IF
434  CASE (real_t)
435  NULLIFY (r_val_p)
436  IF (parser_test_next_token(parser) == "EOL") THEN
437  IF (.NOT. ASSOCIATED(default_value)) THEN
438  IF (n_var < 1) THEN
439  ALLOCATE (r_val_p(0))
440  CALL val_create(val, r_vals_ptr=r_val_p)
441  ELSE
442  CALL cp_abort(__location__, &
443  "no value was given and there is no default value"// &
444  trim(parser_location(parser)))
445  END IF
446  ELSE
447  cpassert(ASSOCIATED(default_value%r_val))
448  CALL val_create(val, r_vals=default_value%r_val)
449  END IF
450  ELSE
451  IF (n_var < 1) THEN
452  NULLIFY (r_last, r_first)
453  c_val = ""
454  CALL get_r_val(r_val, parser, unit, default_units, c_val)
455  CALL cp_create(r_first, r_val)
456  r_last => r_first
457  DO WHILE (parser_test_next_token(parser) /= "EOL")
458  CALL get_r_val(r_val, parser, unit, default_units, c_val)
459  CALL cp_create(r_new, r_val)
460  r_last%rest => r_new
461  r_last => r_new
462  END DO
463  NULLIFY (r_last)
464  r_val_p => cp_to_array(r_first)
465  CALL cp_dealloc(r_first)
466  ELSE
467  ALLOCATE (r_val_p(n_var))
468  c_val = ""
469  DO i = 1, n_var
470  CALL get_r_val(r_val_p(i), parser, unit, default_units, c_val)
471  END DO
472  END IF
473  IF (ASSOCIATED(r_val_p)) THEN
474  CALL val_create(val, r_vals_ptr=r_val_p)
475  END IF
476  END IF
477  CASE (char_t)
478  NULLIFY (c_val_p)
479  IF (parser_test_next_token(parser) == "EOL") THEN
480  IF (n_var < 1) THEN
481  ALLOCATE (c_val_p(1))
482  c_val_p(1) = ' '
483  CALL val_create(val, c_vals_ptr=c_val_p)
484  ELSE
485  IF (.NOT. ASSOCIATED(default_value)) THEN
486  CALL cp_abort(__location__, &
487  "no value was given and there is no default value"// &
488  trim(parser_location(parser)))
489  ELSE
490  cpassert(ASSOCIATED(default_value%c_val))
491  CALL val_create(val, c_vals=default_value%c_val)
492  END IF
493  END IF
494  ELSE
495  IF (n_var < 1) THEN
496  cpassert(n_var == -1)
497  NULLIFY (c_last, c_first)
498  CALL parser_get_object(parser, c_val)
499  CALL cp_create(c_first, c_val)
500  c_last => c_first
501  DO WHILE (parser_test_next_token(parser) /= "EOL")
502  CALL parser_get_object(parser, c_val)
503  CALL cp_create(c_new, c_val)
504  c_last%rest => c_new
505  c_last => c_new
506  END DO
507  c_val_p => cp_to_array(c_first)
508  CALL cp_dealloc(c_first)
509  ELSE
510  ALLOCATE (c_val_p(n_var))
511  DO i = 1, n_var
512  CALL parser_get_object(parser, c_val_p(i))
513  END DO
514  END IF
515  IF (ASSOCIATED(c_val_p)) THEN
516  CALL val_create(val, c_vals_ptr=c_val_p)
517  END IF
518  END IF
519  CASE (lchar_t)
520  IF (ASSOCIATED(default_value)) &
521  CALL cp_abort(__location__, &
522  "input variables of type lchar_t cannot have a lone keyword attribute,"// &
523  " no value is interpreted as empty string"// &
524  trim(parser_location(parser)))
525  IF (n_var /= 1) &
526  CALL cp_abort(__location__, &
527  "input variables of type lchar_t cannot be repeated,"// &
528  " one always represent a whole line, till the end"// &
529  trim(parser_location(parser)))
530  IF (parser_test_next_token(parser) == "EOL") THEN
531  ALLOCATE (c_val_p(1))
532  c_val_p(1) = ' '
533  ELSE
534  NULLIFY (c_last, c_first)
535  CALL parser_get_object(parser, c_val, string_length=len(c_val))
536  IF (c_val(1:1) == parser%quote_character) THEN
537  quoted = .true.
538  c_val(1:) = c_val(2:) ! Drop first quotation mark
539  i = index(c_val, parser%quote_character) ! Check for second quotation mark
540  IF (i > 0) THEN
541  c_val(i:) = "" ! Discard stuff after second quotation mark
542  eol = .true. ! Enforce end of line
543  ELSE
544  eol = .false.
545  END IF
546  ELSE
547  quoted = .false.
548  eol = .false.
549  END IF
550  CALL cp_create(c_first, c_val)
551  c_last => c_first
552  DO WHILE ((.NOT. eol) .AND. (parser_test_next_token(parser) /= "EOL"))
553  CALL parser_get_object(parser, c_val, string_length=len(c_val))
554  i = index(c_val, parser%quote_character) ! Check for quotation mark
555  IF (i > 0) THEN
556  IF (quoted) THEN
557  c_val(i:) = "" ! Discard stuff after second quotation mark
558  eol = .true. ! Enforce end of line
559  ELSE
560  CALL cp_abort(__location__, &
561  "Quotation mark found which is not the first non-blank character. "// &
562  "Possibly the first quotation mark is missing?"// &
563  trim(parser_location(parser)))
564  END IF
565  ELSE
566  eol = .false.
567  END IF
568  CALL cp_create(c_new, c_val)
569  c_last%rest => c_new
570  c_last => c_new
571  END DO
572  c_val_p => cp_to_array(c_first)
573  CALL cp_dealloc(c_first)
574  END IF
575  cpassert(ASSOCIATED(c_val_p))
576  CALL val_create(val, lc_vals_ptr=c_val_p)
577  CASE (enum_t)
578  cpassert(ASSOCIATED(enum))
579  NULLIFY (i_val_p)
580  IF (parser_test_next_token(parser) == "EOL") THEN
581  IF (.NOT. ASSOCIATED(default_value)) THEN
582  IF (n_var < 1) THEN
583  ALLOCATE (i_val_p(0))
584  CALL val_create(val, i_vals_ptr=i_val_p)
585  ELSE
586  CALL cp_abort(__location__, &
587  "no value was given and there is no default value"// &
588  trim(parser_location(parser)))
589  END IF
590  ELSE
591  cpassert(ASSOCIATED(default_value%i_val))
592  CALL val_create(val, i_vals=default_value%i_val, &
593  enum=default_value%enum)
594  END IF
595  ELSE
596  IF (n_var < 1) THEN
597  NULLIFY (i_last, i_first)
598  CALL parser_get_object(parser, c_val)
599  CALL cp_create(i_first, enum_c2i(enum, c_val))
600  i_last => i_first
601  DO WHILE (parser_test_next_token(parser) /= "EOL")
602  CALL parser_get_object(parser, c_val)
603  CALL cp_create(i_new, enum_c2i(enum, c_val))
604  i_last%rest => i_new
605  i_last => i_new
606  END DO
607  i_val_p => cp_to_array(i_first)
608  CALL cp_dealloc(i_first)
609  ELSE
610  ALLOCATE (i_val_p(n_var))
611  DO i = 1, n_var
612  CALL parser_get_object(parser, c_val)
613  i_val_p(i) = enum_c2i(enum, c_val)
614  END DO
615  END IF
616  IF (ASSOCIATED(i_val_p)) THEN
617  CALL val_create(val, i_vals_ptr=i_val_p, enum=enum)
618  END IF
619  END IF
620  CASE default
621  CALL cp_abort(__location__, &
622  "type "//cp_to_string(type_of_var)//"unknown to the parser")
623  END SELECT
624  IF (parser_test_next_token(parser) .NE. "EOL") THEN
625  location = trim(parser_location(parser))
626  CALL parser_get_object(parser, info)
627  CALL cp_abort(__location__, &
628  "found unexpected extra argument "//trim(info)//" at "//location)
629  END IF
630 
631  CALL timestop(handle)
632 
633  END SUBROUTINE val_create_parsing
634 
635 ! **************************************************************************************************
636 !> \brief Reads and convert a real number from the input file
637 !> \param r_val ...
638 !> \param parser the parser from where the values should be read
639 !> \param unit ...
640 !> \param default_units ...
641 !> \param c_val ...
642 !> \author Teodoro Laino - 11.2007 [tlaino] - University of Zurich
643 ! **************************************************************************************************
644  SUBROUTINE get_r_val(r_val, parser, unit, default_units, c_val)
645  REAL(kind=dp), INTENT(OUT) :: r_val
646  TYPE(cp_parser_type), INTENT(INOUT) :: parser
647  TYPE(cp_unit_type), POINTER :: unit
648  TYPE(cp_unit_set_type), INTENT(IN) :: default_units
649  CHARACTER(len=default_string_length), &
650  INTENT(INOUT) :: c_val
651 
652  TYPE(cp_unit_type), POINTER :: my_unit
653 
654  NULLIFY (my_unit)
655  IF (ASSOCIATED(unit)) THEN
656  IF ('STR' == parser_test_next_token(parser)) THEN
657  CALL parser_get_object(parser, c_val)
658  IF (c_val(1:1) /= "[" .OR. c_val(len_trim(c_val):len_trim(c_val)) /= "]") THEN
659  CALL cp_abort(__location__, &
660  "Invalid unit specifier or function found when parsing a number: "// &
661  c_val)
662  END IF
663  ALLOCATE (my_unit)
664  CALL cp_unit_create(my_unit, c_val(2:len_trim(c_val) - 1))
665  ELSE
666  IF (c_val /= "") THEN
667  ALLOCATE (my_unit)
668  CALL cp_unit_create(my_unit, c_val(2:len_trim(c_val) - 1))
669  ELSE
670  my_unit => unit
671  END IF
672  END IF
673  IF (.NOT. cp_unit_compatible(unit, my_unit)) &
674  CALL cp_abort(__location__, &
675  "Incompatible units. Defined as ("// &
676  trim(cp_unit_desc(unit))//") specified in input as ("// &
677  trim(cp_unit_desc(my_unit))//"). These units are incompatible!")
678  END IF
679  CALL parser_get_object(parser, r_val)
680  IF (ASSOCIATED(unit)) THEN
681  r_val = cp_unit_to_cp2k1(r_val, my_unit, default_units)
682  IF (.NOT. (ASSOCIATED(my_unit, unit))) THEN
683  CALL cp_unit_release(my_unit)
684  DEALLOCATE (my_unit)
685  END IF
686  END IF
687 
688  END SUBROUTINE get_r_val
689 
690 END MODULE input_parsing
subroutine, public cp_sll_val_create(sll, first_el, rest)
allocates and initializes a single linked list
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.
unit conversion facility
Definition: cp_units.F:30
character(len=cp_unit_desc_length) function, public cp_unit_desc(unit, defaults, accept_undefined)
returns the "name" of the given unit
Definition: cp_units.F:1036
real(kind=dp) function, public cp_unit_to_cp2k1(value, unit, defaults, power)
transform a value to the internal cp2k units
Definition: cp_units.F:1085
subroutine, public cp_unit_create(unit, string)
creates a unit parsing a string
Definition: cp_units.F:163
logical function, public cp_unit_compatible(ref_unit, unit)
returs true if the two units are compatible
Definition: cp_units.F:1205
elemental subroutine, public cp_unit_release(unit)
releases the given unit
Definition: cp_units.F:545
represents an enumeration, i.e. a mapping between integers and strings
integer function, public enum_c2i(enum, c)
maps a string to an integer
represents keywords in an input
subroutine, public keyword_describe(keyword, unit_nr, level)
writes out a description of the keyword
routines that parse the input
Definition: input_parsing.F:14
recursive subroutine, public section_vals_parse(section_vals, parser, default_units, root_section)
...
Definition: input_parsing.F:67
objects that represent the structure of input sections and the data contained in an input section
recursive subroutine, public section_typo_match(section, section_name, unknown_string, location_string, matching_rank, matching_string, bonus)
...
type(section_type), pointer, save, public typo_match_section
integer function, public section_get_keyword_index(section, keyword_name)
returns the index of the requested keyword (or -2 if not found)
integer, dimension(n_typo_matches), public typo_matching_rank
recursive type(keyword_type) function, pointer, public section_get_keyword(section, keyword_name)
returns the requested keyword
recursive subroutine, public section_describe(section, unit_nr, level, hide_root, recurse)
prints a description of the given section
integer function, public section_get_subsection_index(section, subsection_name)
returns the index of requested subsection (-1 if not found)
character(len=default_string_length *5), dimension(n_typo_matches), public typo_matching_line
subroutine, public section_vals_add_values(section_vals)
adds the place to store the values of a repetition of the section
a wrapper for basic fortran types.
integer, parameter, public real_t
integer, parameter, public lchar_t
integer, parameter, public logical_t
subroutine, public val_create(val, l_val, l_vals, l_vals_ptr, i_val, i_vals, i_vals_ptr, r_val, r_vals, r_vals_ptr, c_val, c_vals, c_vals_ptr, lc_val, lc_vals, lc_vals_ptr, enum)
creates a keyword value
integer, parameter, public char_t
integer, parameter, public integer_t
integer, parameter, public no_t
integer, parameter, public enum_t
Defines the basic variable types.
Definition: kinds.F:23
integer, parameter, public max_line_length
Definition: kinds.F:59
integer, parameter, public dp
Definition: kinds.F:34
integer, parameter, public default_string_length
Definition: kinds.F:57
Utilities for string manipulations.
elemental subroutine, public uppercase(string)
Convert all lower case characters in a string to upper case.