LCOV - code coverage report
Current view: top level - src/input - input_parsing.F (source / functions) Hit Total Coverage
Test: CP2K Regtests (git:5d0137b) Lines: 253 333 76.0 %
Date: 2024-03-01 06:31:42 Functions: 3 3 100.0 %

          Line data    Source code
       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             : ! **************************************************************************************************
      14             : MODULE input_parsing
      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
      18             :    USE cp_log_handling,                 ONLY: cp_logger_get_default_io_unit,&
      19             :                                               cp_to_string
      20             :    USE cp_parser_methods,               ONLY: parser_get_object,&
      21             :                                               parser_location,&
      22             :                                               parser_skip_space,&
      23             :                                               parser_test_next_token
      24             :    USE cp_parser_types,                 ONLY: cp_parser_type
      25             :    USE cp_units,                        ONLY: cp_unit_compatible,&
      26             :                                               cp_unit_create,&
      27             :                                               cp_unit_desc,&
      28             :                                               cp_unit_release,&
      29             :                                               cp_unit_set_type,&
      30             :                                               cp_unit_to_cp2k1,&
      31             :                                               cp_unit_type
      32             :    USE input_enumeration_types,         ONLY: enum_c2i,&
      33             :                                               enumeration_type
      34             :    USE input_keyword_types,             ONLY: keyword_describe,&
      35             :                                               keyword_type
      36             :    USE input_section_types,             ONLY: &
      37             :         section_describe, section_get_keyword, section_get_keyword_index, &
      38             :         section_get_subsection_index, section_type, section_typo_match, section_vals_add_values, &
      39             :         section_vals_type, typo_match_section, typo_matching_line, typo_matching_rank
      40             :    USE input_val_types,                 ONLY: &
      41             :         char_t, enum_t, integer_t, lchar_t, logical_t, no_t, real_t, val_create, val_type
      42             :    USE kinds,                           ONLY: default_string_length,&
      43             :                                               dp,&
      44             :                                               max_line_length
      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      222810 :    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      222810 :       CALL timeset(routineN, handle)
      86             : 
      87      222810 :       NULLIFY (previous_list, previous_last)
      88             : 
      89      222810 :       root_sect = .TRUE.
      90      222810 :       IF (PRESENT(root_section)) root_sect = root_section
      91             : 
      92      222810 :       CPASSERT(ASSOCIATED(section_vals))
      93      222810 :       output_unit = cp_logger_get_default_io_unit()
      94             : 
      95      222810 :       CPASSERT(section_vals%ref_count > 0)
      96      222810 :       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           0 :                        //TRIM(parser_location(parser)))
     100      222810 :       section => section_vals%section
     101      222810 :       IF (root_sect) THEN
     102      213622 :          token = TRIM(ADJUSTL(parser%input_line(parser%icol1:parser%icol2))) ! Ignore leading or trailing blanks
     103      213622 :          CALL uppercase(token)
     104      213622 :          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           0 :                           //TRIM(parser_location(parser)))
     108             :       END IF
     109      222810 :       IF (.NOT. section%repeats .AND. SIZE(section_vals%values, 2) /= 0) &
     110             :          CALL cp_abort(__LOCATION__, "Section "//TRIM(section%name)// &
     111           0 :                        " should not repeat "//TRIM(parser_location(parser)))
     112      222810 :       CALL section_vals_add_values(section_vals)
     113      222810 :       irs = SIZE(section_vals%values, 2)
     114             : 
     115      222810 :       IF (ASSOCIATED(section%keywords(-1)%keyword)) THEN ! reads section params
     116       47839 :          keyword => section%keywords(-1)%keyword
     117       47839 :          NULLIFY (el)
     118       47839 :          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       47839 :                                  parser=parser)
     124       47839 :          NULLIFY (new_val)
     125       47839 :          CALL cp_sll_val_create(new_val, el)
     126       47839 :          section_vals%values(-1, irs)%list => new_val
     127       47839 :          NULLIFY (el)
     128             :       END IF
     129             :       DO WHILE (.TRUE.)
     130             :          CALL parser_get_object(parser, token, newline=.TRUE., &
     131     1063347 :                                 lower_to_upper=.TRUE., at_end=at_end)
     132     1063347 :          token = TRIM(ADJUSTL(token)) ! Ignore leading or trailing blanks
     133     1063347 :          IF (at_end) THEN
     134        9188 :             IF (root_sect) &
     135             :                CALL cp_abort(__LOCATION__, &
     136             :                              "unexpected end of file while parsing section "// &
     137           0 :                              TRIM(section%name)//" "//TRIM(parser_location(parser)))
     138             :             EXIT
     139             :          END IF
     140     1054159 :          IF (token(1:1) == parser%section_character) THEN
     141      427159 :             IF (token == "&END") THEN
     142             :                ! end of section
     143      213622 :                compatible_end = .TRUE.
     144      213622 :                IF (parser_test_next_token(parser) /= "EOL") THEN
     145             :                   CALL parser_get_object(parser, token, newline=.FALSE., &
     146      212136 :                                          lower_to_upper=.TRUE.)
     147      425758 :                   IF (token /= "SECTION" .AND. token /= section%name) THEN
     148           0 :                      compatible_end = .FALSE.
     149             :                   END IF
     150             :                END IF
     151      213622 :                IF (parser_test_next_token(parser) /= "EOL") THEN
     152             :                   CALL parser_get_object(parser, token, newline=.FALSE., &
     153           0 :                                          lower_to_upper=.TRUE.)
     154      213622 :                   IF (token /= section%name) THEN
     155           0 :                      PRINT *, TRIM(token), "/=", TRIM(section%name)
     156             :                      compatible_end = .FALSE.
     157             :                   END IF
     158             :                END IF
     159      213622 :                IF (.NOT. compatible_end) THEN
     160             :                   CALL cp_abort(__LOCATION__, &
     161             :                                 "non-compatible end of section "//TRIM(section%name)//" "// &
     162           0 :                                 TRIM(parser_location(parser)))
     163             :                END IF
     164             :                !              RETURN
     165             :                EXIT
     166             :             END IF
     167      213537 :             is = section_get_subsection_index(section, token(2:))
     168      213537 :             IF (is > 0) THEN
     169             :                CALL section_vals_parse(section_vals%subs_vals(is, irs)%section_vals, &
     170      213537 :                                        default_units=default_units, parser=parser)
     171             :             ELSE
     172             :                ! unknown subsection
     173           0 :                IF (output_unit > 0) THEN
     174           0 :                   WRITE (output_unit, *)
     175           0 :                   WRITE (output_unit, '(T2,A)') "Possible matches for unknown subsection "
     176           0 :                   WRITE (output_unit, *)
     177           0 :                   WRITE (output_unit, '(T2,A)') TRIM(token(2:))
     178           0 :                   WRITE (output_unit, *)
     179             :                   CALL section_typo_match(typo_match_section, TRIM(section%name), TRIM(token(2:)), "", &
     180           0 :                                           typo_matching_rank, typo_matching_line, bonus=0)
     181           0 :                   DO imatch = 1, SIZE(typo_matching_rank)
     182           0 :                      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           0 :                              //TRIM(section%name))
     188           0 :                nSub = 1
     189           0 :                DO WHILE (nSub > 0)
     190             :                   CALL parser_get_object(parser, token, newline=.TRUE., &
     191           0 :                                          lower_to_upper=.TRUE.)
     192           0 :                   IF (token(1:1) == parser%section_character) THEN
     193           0 :                      IF (token == "&END") THEN
     194           0 :                         nSub = nSub - 1
     195             :                      ELSE
     196           0 :                         nSub = nSub + 1
     197             :                      END IF
     198             :                   END IF
     199             :                END DO
     200             :             END IF
     201             :          ELSE ! token is a keyword
     202      627000 :             IF (token == "DESCRIBE") THEN
     203           2 :                IF (output_unit > 0) WRITE (output_unit, "(/,' ****** DESCRIPTION ******',/)")
     204           2 :                desc_level = 3
     205           2 :                IF (parser_test_next_token(parser) == "INT") THEN
     206           2 :                   CALL parser_get_object(parser, desc_level)
     207             :                END IF
     208           2 :                whole_section = .TRUE.
     209           2 :                DO WHILE (parser_test_next_token(parser) == "STR")
     210           0 :                   whole_section = .FALSE.
     211             :                   CALL parser_get_object(parser, token, newline=.FALSE., &
     212           0 :                                          lower_to_upper=.TRUE.)
     213           0 :                   keyword => section_get_keyword(section, token)
     214           0 :                   IF (.NOT. ASSOCIATED(keyword)) THEN
     215             :                      CALL cp_warn(__LOCATION__, &
     216             :                                   "unknown keyword to describe "//TRIM(token)// &
     217           0 :                                   " in section "//TRIM(section%name))
     218             :                   ELSE
     219           0 :                      CALL keyword_describe(keyword, output_unit, desc_level)
     220             :                   END IF
     221             :                END DO
     222           2 :                IF (whole_section) THEN
     223           2 :                   CALL section_describe(section, output_unit, desc_level, hide_root=.NOT. root_sect)
     224             :                END IF
     225           2 :                IF (output_unit > 0) WRITE (output_unit, "(/,' ****** =========== ******',/)")
     226             : 
     227             :             ELSE ! token is a "normal" keyword
     228      626998 :                ik = section_get_keyword_index(section, token)
     229      626998 :                IF (ik < 1) THEN ! don't accept pseudo keyword names
     230      282602 :                   parser%icol = parser%icol1 - 1 ! re-read also the actual token
     231      282602 :                   ik = 0
     232      282602 :                   IF (.NOT. ASSOCIATED(section%keywords(0)%keyword)) THEN
     233           0 :                      IF (output_unit > 0) THEN
     234           0 :                         WRITE (output_unit, *)
     235           0 :                         WRITE (output_unit, '(T2,A)') "Possible matches for unknown keyword "
     236           0 :                         WRITE (output_unit, *)
     237           0 :                         WRITE (output_unit, '(T2,A)') TRIM(token)
     238           0 :                         WRITE (output_unit, *)
     239             :                         CALL section_typo_match(typo_match_section, TRIM(section%name), TRIM(token), "", &
     240           0 :                                                 typo_matching_rank, typo_matching_line, bonus=0)
     241           0 :                         DO imatch = 1, SIZE(typo_matching_rank)
     242             :                            WRITE (output_unit, '(T2,A,1X,I0)') &
     243           0 :                               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           0 :                                    " in section "//TRIM(section%name))
     249             :                   END IF
     250             :                END IF
     251      626998 :                keyword => section%keywords(ik)%keyword
     252      626998 :                IF (ASSOCIATED(keyword)) THEN
     253      626998 :                   IF (keyword%removed) THEN
     254           0 :                      IF (ALLOCATED(keyword%deprecation_notice)) THEN
     255             :                         CALL cp_abort(__LOCATION__, &
     256             :                                       "The specified keyword '"//TRIM(token)//"' is not available anymore: "// &
     257           0 :                                       keyword%deprecation_notice)
     258             :                      ELSE
     259             :                         CALL cp_abort(__LOCATION__, &
     260             :                                       "The specified keyword '"//TRIM(token)// &
     261           0 :                                       "' is not available anymore, please consult the manual.")
     262             :                      END IF
     263             :                   END IF
     264             : 
     265      626998 :                   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          56 :                                   keyword%deprecation_notice//".")
     270             : 
     271      626998 :                   NULLIFY (el)
     272      626998 :                   IF (ik /= 0 .AND. keyword%type_of_var == lchar_t) &
     273       21053 :                      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      626998 :                                           default_units=default_units, parser=parser)
     278      626998 :                   IF (ASSOCIATED(el)) THEN
     279      626998 :                      NULLIFY (new_val)
     280      626998 :                      CALL cp_sll_val_create(new_val, el)
     281      626998 :                      last_val => section_vals%values(ik, irs)%list
     282      626998 :                      IF (.NOT. ASSOCIATED(last_val)) THEN
     283      350157 :                         section_vals%values(ik, irs)%list => new_val
     284             :                      ELSE
     285      276841 :                         IF (.NOT. keyword%repeats) &
     286             :                            CALL cp_abort(__LOCATION__, &
     287             :                                          "Keyword "//TRIM(token)// &
     288           0 :                                          " in section "//TRIM(section%name)//" should not repeat.")
     289      276841 :                         IF (ASSOCIATED(last_val, previous_list)) THEN
     290      266134 :                            last_val => previous_last
     291             :                         ELSE
     292      276841 :                            previous_list => last_val
     293             :                         END IF
     294      276841 :                         DO WHILE (ASSOCIATED(last_val%rest))
     295      276841 :                            last_val => last_val%rest
     296             :                         END DO
     297      276841 :                         last_val%rest => new_val
     298      276841 :                         previous_last => new_val
     299             :                      END IF
     300             :                   END IF
     301             :                END IF
     302             :             END IF
     303             :          END IF
     304             :       END DO
     305      222810 :       CALL timestop(handle)
     306      222810 :    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      674837 :    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      674837 :          DIMENSION(:), POINTER                           :: c_val_p
     337             :       INTEGER                                            :: handle, i, i_val
     338      674837 :       INTEGER, DIMENSION(:), POINTER                     :: i_val_p
     339             :       LOGICAL                                            :: check, eol, l_val, quoted
     340      674837 :       LOGICAL, DIMENSION(:), POINTER                     :: l_val_p
     341             :       REAL(kind=dp)                                      :: r_val
     342      674837 :       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      674837 :       CALL timeset(routineN, handle)
     349             : 
     350      674837 :       CPASSERT(.NOT. ASSOCIATED(val))
     351      709357 :       SELECT CASE (type_of_var)
     352             :       CASE (no_t)
     353             :       CASE (logical_t)
     354       34520 :          NULLIFY (l_val_p)
     355       69040 :          IF (parser_test_next_token(parser) == "EOL") THEN
     356       17220 :             IF (.NOT. ASSOCIATED(default_value)) THEN
     357           0 :                IF (n_var < 1) THEN
     358           0 :                   ALLOCATE (l_val_p(0))
     359           0 :                   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           0 :                                 TRIM(parser_location(parser)))
     364             :                END IF
     365             :             ELSE
     366       17220 :                CPASSERT(ASSOCIATED(default_value%l_val))
     367       17220 :                CALL val_create(val, l_vals=default_value%l_val)
     368             :             END IF
     369             :          ELSE
     370       17300 :             IF (n_var < 1) THEN
     371           0 :                NULLIFY (l_last, l_first)
     372           0 :                CALL parser_get_object(parser, l_val)
     373           0 :                CALL cp_create(l_first, l_val)
     374           0 :                l_last => l_first
     375           0 :                DO WHILE (parser_test_next_token(parser) /= "EOL")
     376           0 :                   CALL parser_get_object(parser, l_val)
     377           0 :                   CALL cp_create(l_new, l_val)
     378           0 :                   l_last%rest => l_new
     379           0 :                   l_last => l_new
     380             :                END DO
     381           0 :                l_val_p => cp_to_array(l_first)
     382           0 :                CALL cp_dealloc(l_first)
     383             :             ELSE
     384       51900 :                ALLOCATE (l_val_p(n_var))
     385       34600 :                DO i = 1, n_var
     386       34600 :                   CALL parser_get_object(parser, l_val_p(i))
     387             :                END DO
     388             :             END IF
     389       51820 :             IF (ASSOCIATED(l_val_p)) THEN
     390       17300 :                CALL val_create(val, l_vals_ptr=l_val_p)
     391             :             END IF
     392             :          END IF
     393             :       CASE (integer_t)
     394       49450 :          NULLIFY (i_val_p)
     395       98900 :          IF (parser_test_next_token(parser) == "EOL") THEN
     396          14 :             IF (.NOT. ASSOCIATED(default_value)) THEN
     397           0 :                IF (n_var < 1) THEN
     398           0 :                   ALLOCATE (i_val_p(0))
     399           0 :                   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           0 :                                 TRIM(parser_location(parser)))
     404             :                END IF
     405             :             ELSE
     406          14 :                check = ASSOCIATED(default_value%i_val)
     407          14 :                CPASSERT(check)
     408          14 :                CALL val_create(val, i_vals=default_value%i_val)
     409             :             END IF
     410             :          ELSE
     411       49436 :             IF (n_var < 1) THEN
     412        7627 :                NULLIFY (i_last, i_first)
     413        7627 :                CALL parser_get_object(parser, i_val)
     414        7627 :                CALL cp_create(i_first, i_val)
     415        7627 :                i_last => i_first
     416       29571 :                DO WHILE (parser_test_next_token(parser) /= "EOL")
     417       21944 :                   CALL parser_get_object(parser, i_val)
     418       21944 :                   CALL cp_create(i_new, i_val)
     419       21944 :                   i_last%rest => i_new
     420       21944 :                   i_last => i_new
     421             :                END DO
     422        7627 :                i_val_p => cp_to_array(i_first)
     423        7627 :                CALL cp_dealloc(i_first)
     424             :             ELSE
     425      125427 :                ALLOCATE (i_val_p(n_var))
     426       88568 :                DO i = 1, n_var
     427       88568 :                   CALL parser_get_object(parser, i_val_p(i))
     428             :                END DO
     429             :             END IF
     430       98886 :             IF (ASSOCIATED(i_val_p)) THEN
     431       49436 :                CALL val_create(val, i_vals_ptr=i_val_p)
     432             :             END IF
     433             :          END IF
     434             :       CASE (real_t)
     435      156571 :          NULLIFY (r_val_p)
     436      313142 :          IF (parser_test_next_token(parser) == "EOL") THEN
     437           2 :             IF (.NOT. ASSOCIATED(default_value)) THEN
     438           2 :                IF (n_var < 1) THEN
     439           2 :                   ALLOCATE (r_val_p(0))
     440           2 :                   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           0 :                                 TRIM(parser_location(parser)))
     445             :                END IF
     446             :             ELSE
     447           0 :                CPASSERT(ASSOCIATED(default_value%r_val))
     448           0 :                CALL val_create(val, r_vals=default_value%r_val)
     449             :             END IF
     450             :          ELSE
     451      156569 :             IF (n_var < 1) THEN
     452       16815 :                NULLIFY (r_last, r_first)
     453       16815 :                c_val = ""
     454       16815 :                CALL get_r_val(r_val, parser, unit, default_units, c_val)
     455       16815 :                CALL cp_create(r_first, r_val)
     456       16815 :                r_last => r_first
     457      333781 :                DO WHILE (parser_test_next_token(parser) /= "EOL")
     458      316966 :                   CALL get_r_val(r_val, parser, unit, default_units, c_val)
     459      316966 :                   CALL cp_create(r_new, r_val)
     460      316966 :                   r_last%rest => r_new
     461      316966 :                   r_last => r_new
     462             :                END DO
     463       16815 :                NULLIFY (r_last)
     464       16815 :                r_val_p => cp_to_array(r_first)
     465       16815 :                CALL cp_dealloc(r_first)
     466             :             ELSE
     467      419262 :                ALLOCATE (r_val_p(n_var))
     468      139754 :                c_val = ""
     469      363938 :                DO i = 1, n_var
     470      363938 :                   CALL get_r_val(r_val_p(i), parser, unit, default_units, c_val)
     471             :                END DO
     472             :             END IF
     473      313140 :             IF (ASSOCIATED(r_val_p)) THEN
     474      156569 :                CALL val_create(val, r_vals_ptr=r_val_p)
     475             :             END IF
     476             :          END IF
     477             :       CASE (char_t)
     478       73113 :          NULLIFY (c_val_p)
     479      146226 :          IF (parser_test_next_token(parser) == "EOL") THEN
     480         206 :             IF (n_var < 1) THEN
     481           2 :                ALLOCATE (c_val_p(1))
     482           2 :                c_val_p(1) = ' '
     483           2 :                CALL val_create(val, c_vals_ptr=c_val_p)
     484             :             ELSE
     485         204 :                IF (.NOT. ASSOCIATED(default_value)) THEN
     486             :                   CALL cp_abort(__LOCATION__, &
     487             :                                 "no value was given and there is no default value"// &
     488           0 :                                 TRIM(parser_location(parser)))
     489             :                ELSE
     490         204 :                   CPASSERT(ASSOCIATED(default_value%c_val))
     491         204 :                   CALL val_create(val, c_vals=default_value%c_val)
     492             :                END IF
     493             :             END IF
     494             :          ELSE
     495       72907 :             IF (n_var < 1) THEN
     496       28058 :                CPASSERT(n_var == -1)
     497       28058 :                NULLIFY (c_last, c_first)
     498       28058 :                CALL parser_get_object(parser, c_val)
     499       28058 :                CALL cp_create(c_first, c_val)
     500       28058 :                c_last => c_first
     501       35656 :                DO WHILE (parser_test_next_token(parser) /= "EOL")
     502        7598 :                   CALL parser_get_object(parser, c_val)
     503        7598 :                   CALL cp_create(c_new, c_val)
     504        7598 :                   c_last%rest => c_new
     505        7598 :                   c_last => c_new
     506             :                END DO
     507       28058 :                c_val_p => cp_to_array(c_first)
     508       28058 :                CALL cp_dealloc(c_first)
     509             :             ELSE
     510      134547 :                ALLOCATE (c_val_p(n_var))
     511      105674 :                DO i = 1, n_var
     512      105674 :                   CALL parser_get_object(parser, c_val_p(i))
     513             :                END DO
     514             :             END IF
     515      146020 :             IF (ASSOCIATED(c_val_p)) THEN
     516       72907 :                CALL val_create(val, c_vals_ptr=c_val_p)
     517             :             END IF
     518             :          END IF
     519             :       CASE (lchar_t)
     520      261655 :          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           0 :                           TRIM(parser_location(parser)))
     525      261655 :          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           0 :                           TRIM(parser_location(parser)))
     530      261655 :          IF (parser_test_next_token(parser) == "EOL") THEN
     531          74 :             ALLOCATE (c_val_p(1))
     532          74 :             c_val_p(1) = ' '
     533             :          ELSE
     534      261581 :             NULLIFY (c_last, c_first)
     535      261581 :             CALL parser_get_object(parser, c_val, string_length=LEN(c_val))
     536      261581 :             IF (c_val(1:1) == parser%quote_character) THEN
     537          10 :                quoted = .TRUE.
     538          10 :                c_val(1:) = c_val(2:) ! Drop first quotation mark
     539          10 :                i = INDEX(c_val, parser%quote_character) ! Check for second quotation mark
     540          10 :                IF (i > 0) THEN
     541           0 :                   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      261581 :             CALL cp_create(c_first, c_val)
     551      261581 :             c_last => c_first
     552      283739 :             DO WHILE ((.NOT. eol) .AND. (parser_test_next_token(parser) /= "EOL"))
     553       22158 :                CALL parser_get_object(parser, c_val, string_length=LEN(c_val))
     554       22158 :                i = INDEX(c_val, parser%quote_character) ! Check for quotation mark
     555       22158 :                IF (i > 0) THEN
     556          10 :                   IF (quoted) THEN
     557          10 :                      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           0 :                                    TRIM(parser_location(parser)))
     564             :                   END IF
     565             :                ELSE
     566             :                   eol = .FALSE.
     567             :                END IF
     568       22158 :                CALL cp_create(c_new, c_val)
     569       22158 :                c_last%rest => c_new
     570       22158 :                c_last => c_new
     571             :             END DO
     572      261581 :             c_val_p => cp_to_array(c_first)
     573      523236 :             CALL cp_dealloc(c_first)
     574             :          END IF
     575      261655 :          CPASSERT(ASSOCIATED(c_val_p))
     576      261655 :          CALL val_create(val, lc_vals_ptr=c_val_p)
     577             :       CASE (enum_t)
     578       99528 :          CPASSERT(ASSOCIATED(enum))
     579       99528 :          NULLIFY (i_val_p)
     580      199056 :          IF (parser_test_next_token(parser) == "EOL") THEN
     581       10598 :             IF (.NOT. ASSOCIATED(default_value)) THEN
     582           0 :                IF (n_var < 1) THEN
     583           0 :                   ALLOCATE (i_val_p(0))
     584           0 :                   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           0 :                                 TRIM(parser_location(parser)))
     589             :                END IF
     590             :             ELSE
     591       10598 :                CPASSERT(ASSOCIATED(default_value%i_val))
     592             :                CALL val_create(val, i_vals=default_value%i_val, &
     593       10598 :                                enum=default_value%enum)
     594             :             END IF
     595             :          ELSE
     596       88930 :             IF (n_var < 1) THEN
     597          58 :                NULLIFY (i_last, i_first)
     598          58 :                CALL parser_get_object(parser, c_val)
     599          58 :                CALL cp_create(i_first, enum_c2i(enum, c_val))
     600          58 :                i_last => i_first
     601          64 :                DO WHILE (parser_test_next_token(parser) /= "EOL")
     602           6 :                   CALL parser_get_object(parser, c_val)
     603           6 :                   CALL cp_create(i_new, enum_c2i(enum, c_val))
     604           6 :                   i_last%rest => i_new
     605           6 :                   i_last => i_new
     606             :                END DO
     607          58 :                i_val_p => cp_to_array(i_first)
     608          58 :                CALL cp_dealloc(i_first)
     609             :             ELSE
     610      266616 :                ALLOCATE (i_val_p(n_var))
     611      177744 :                DO i = 1, n_var
     612       88872 :                   CALL parser_get_object(parser, c_val)
     613      177744 :                   i_val_p(i) = enum_c2i(enum, c_val)
     614             :                END DO
     615             :             END IF
     616      188458 :             IF (ASSOCIATED(i_val_p)) THEN
     617       88930 :                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      674837 :                        "type "//cp_to_string(type_of_var)//"unknown to the parser")
     623             :       END SELECT
     624      674837 :       IF (parser_test_next_token(parser) .NE. "EOL") THEN
     625           0 :          location = TRIM(parser_location(parser))
     626           0 :          CALL parser_get_object(parser, info)
     627             :          CALL cp_abort(__LOCATION__, &
     628      674837 :                        "found unexpected extra argument "//TRIM(info)//" at "//location)
     629             :       END IF
     630             : 
     631      674837 :       CALL timestop(handle)
     632             : 
     633      674837 :    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      557965 :    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      557965 :       NULLIFY (my_unit)
     655      557965 :       IF (ASSOCIATED(unit)) THEN
     656      102433 :          IF ('STR' == parser_test_next_token(parser)) THEN
     657       12220 :             CALL parser_get_object(parser, c_val)
     658       12220 :             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           0 :                              c_val)
     662             :             END IF
     663      305500 :             ALLOCATE (my_unit)
     664       12220 :             CALL cp_unit_create(my_unit, c_val(2:LEN_TRIM(c_val) - 1))
     665             :          ELSE
     666      192646 :             IF (c_val /= "") THEN
     667       80900 :                ALLOCATE (my_unit)
     668        3236 :                CALL cp_unit_create(my_unit, c_val(2:LEN_TRIM(c_val) - 1))
     669             :             ELSE
     670       86977 :                my_unit => unit
     671             :             END IF
     672             :          END IF
     673      102433 :          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           0 :                           TRIM(cp_unit_desc(my_unit))//"). These units are incompatible!")
     678             :       END IF
     679      557965 :       CALL parser_get_object(parser, r_val)
     680      557965 :       IF (ASSOCIATED(unit)) THEN
     681      102433 :          r_val = cp_unit_to_cp2k1(r_val, my_unit, default_units)
     682      102433 :          IF (.NOT. (ASSOCIATED(my_unit, unit))) THEN
     683       15456 :             CALL cp_unit_release(my_unit)
     684       15456 :             DEALLOCATE (my_unit)
     685             :          END IF
     686             :       END IF
     687             : 
     688      557965 :    END SUBROUTINE get_r_val
     689             : 
     690             : END MODULE input_parsing

Generated by: LCOV version 1.15