LCOV - code coverage report
Current view: top level - src/input - input_parsing.F (source / functions) Hit Total Coverage
Test: CP2K Regtests (git:b1c14e6) Lines: 252 331 76.1 %
Date: 2022-07-02 11:36:49 Functions: 3 3 100.0 %

          Line data    Source code
       1             : !--------------------------------------------------------------------------------------------------!
       2             : !   CP2K: A general program to perform molecular dynamics simulations                              !
       3             : !   Copyright 2000-2022 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      203904 :    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), POINTER                      :: parser
      69             :       TYPE(cp_unit_set_type), POINTER                    :: 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      203904 :       CALL timeset(routineN, handle)
      86             : 
      87      203904 :       NULLIFY (previous_list, previous_last)
      88             : 
      89      203904 :       root_sect = .TRUE.
      90      203904 :       IF (PRESENT(root_section)) root_sect = root_section
      91             : 
      92      203904 :       CPASSERT(ASSOCIATED(section_vals))
      93      203904 :       CPASSERT(ASSOCIATED(parser))
      94      203904 :       output_unit = cp_logger_get_default_io_unit()
      95             : 
      96      203904 :       CPASSERT(section_vals%ref_count > 0)
      97      203904 :       CPASSERT(parser%ref_count > 0)
      98      203904 :       IF (root_sect .AND. parser%icol1 > parser%icol2) &
      99             :          CALL cp_abort(__LOCATION__, &
     100             :                        "Error 1: this routine must be called just after having parsed the start of the section " &
     101           0 :                        //TRIM(parser_location(parser)))
     102      203904 :       section => section_vals%section
     103      203904 :       IF (root_sect) THEN
     104      195496 :          token = TRIM(ADJUSTL(parser%input_line(parser%icol1:parser%icol2))) ! Ignore leading or trailing blanks
     105      195496 :          CALL uppercase(token)
     106      195496 :          IF (token /= parser%section_character//section%name) &
     107             :             CALL cp_abort(__LOCATION__, &
     108             :                           "Error 2: this routine must be called just after having parsed the start of the section " &
     109           0 :                           //TRIM(parser_location(parser)))
     110             :       END IF
     111      203904 :       IF (.NOT. section%repeats .AND. SIZE(section_vals%values, 2) /= 0) &
     112             :          CALL cp_abort(__LOCATION__, "Section "//TRIM(section%name)// &
     113           0 :                        " should not repeat "//TRIM(parser_location(parser)))
     114      203904 :       CALL section_vals_add_values(section_vals)
     115      203904 :       irs = SIZE(section_vals%values, 2)
     116             : 
     117      203904 :       IF (ASSOCIATED(section%keywords(-1)%keyword)) THEN ! reads section params
     118       42281 :          keyword => section%keywords(-1)%keyword
     119       42281 :          NULLIFY (el)
     120       42281 :          IF (keyword%type_of_var == lchar_t) CALL parser_skip_space(parser)
     121             :          CALL val_create_parsing(el, type_of_var=keyword%type_of_var, &
     122             :                                  n_var=keyword%n_var, default_value=keyword%lone_keyword_value, &
     123             :                                  enum=keyword%enum, unit=keyword%unit, &
     124             :                                  default_units=default_units, &
     125       42281 :                                  parser=parser)
     126       42281 :          NULLIFY (new_val)
     127       42281 :          CALL cp_sll_val_create(new_val, el)
     128       42281 :          section_vals%values(-1, irs)%list => new_val
     129       42281 :          NULLIFY (el)
     130             :       END IF
     131             :       DO WHILE (.TRUE.)
     132             :          CALL parser_get_object(parser, token, newline=.TRUE., &
     133      996960 :                                 lower_to_upper=.TRUE., at_end=at_end)
     134      996960 :          token = TRIM(ADJUSTL(token)) ! Ignore leading or trailing blanks
     135      996960 :          IF (at_end) THEN
     136        8408 :             IF (root_sect) &
     137             :                CALL cp_abort(__LOCATION__, &
     138             :                              "unexpected end of file while parsing section "// &
     139           0 :                              TRIM(section%name)//" "//TRIM(parser_location(parser)))
     140             :             EXIT
     141             :          END IF
     142      988552 :          IF (token(1:1) == parser%section_character) THEN
     143      390909 :             IF (token == "&END") THEN
     144             :                ! end of section
     145      195496 :                compatible_end = .TRUE.
     146      195496 :                IF (parser_test_next_token(parser) /= "EOL") THEN
     147             :                   CALL parser_get_object(parser, token, newline=.FALSE., &
     148      159027 :                                          lower_to_upper=.TRUE.)
     149      354523 :                   IF (token /= "SECTION" .AND. token /= section%name) THEN
     150           0 :                      compatible_end = .FALSE.
     151             :                   END IF
     152             :                END IF
     153      195496 :                IF (parser_test_next_token(parser) /= "EOL") THEN
     154             :                   CALL parser_get_object(parser, token, newline=.FALSE., &
     155          50 :                                          lower_to_upper=.TRUE.)
     156      195546 :                   IF (token /= section%name) THEN
     157           0 :                      PRINT *, TRIM(token), "/=", TRIM(section%name)
     158             :                      compatible_end = .FALSE.
     159             :                   END IF
     160             :                END IF
     161      195496 :                IF (.NOT. compatible_end) THEN
     162             :                   CALL cp_abort(__LOCATION__, &
     163             :                                 "non-compatible end of section "//TRIM(section%name)//" "// &
     164           0 :                                 TRIM(parser_location(parser)))
     165             :                END IF
     166             :                !              RETURN
     167             :                EXIT
     168             :             END IF
     169      195413 :             is = section_get_subsection_index(section, token(2:))
     170      195413 :             IF (is > 0) THEN
     171             :                CALL section_vals_parse(section_vals%subs_vals(is, irs)%section_vals, &
     172      195413 :                                        default_units=default_units, parser=parser)
     173             :             ELSE
     174             :                ! unknown subsection
     175           0 :                IF (output_unit > 0) THEN
     176           0 :                   WRITE (output_unit, *)
     177           0 :                   WRITE (output_unit, '(T2,A)') "Possible matches for unknown subsection "
     178           0 :                   WRITE (output_unit, *)
     179           0 :                   WRITE (output_unit, '(T2,A)') TRIM(token(2:))
     180           0 :                   WRITE (output_unit, *)
     181             :                   CALL section_typo_match(typo_match_section, TRIM(section%name), TRIM(token(2:)), "", &
     182           0 :                                           typo_matching_rank, typo_matching_line, bonus=0)
     183           0 :                   DO imatch = 1, SIZE(typo_matching_rank)
     184           0 :                      WRITE (output_unit, '(T2,A,1X,I0)') TRIM(typo_matching_line(imatch))//" score: ", typo_matching_rank(imatch)
     185             :                   END DO
     186             :                END IF
     187             :                CALL cp_abort(__LOCATION__, &
     188             :                              "unknown subsection "//TRIM(token(2:))//" of section " &
     189           0 :                              //TRIM(section%name))
     190           0 :                nSub = 1
     191           0 :                DO WHILE (nSub > 0)
     192             :                   CALL parser_get_object(parser, token, newline=.TRUE., &
     193           0 :                                          lower_to_upper=.TRUE.)
     194           0 :                   IF (token(1:1) == parser%section_character) THEN
     195           0 :                      IF (token == "&END") THEN
     196           0 :                         nSub = nSub - 1
     197             :                      ELSE
     198           0 :                         nSub = nSub + 1
     199             :                      END IF
     200             :                   END IF
     201             :                END DO
     202             :             END IF
     203             :          ELSE ! token is a keyword
     204      597643 :             IF (token == "DESCRIBE") THEN
     205           2 :                IF (output_unit > 0) WRITE (output_unit, "(/,' ****** DESCRIPTION ******',/)")
     206           2 :                desc_level = 3
     207           2 :                IF (parser_test_next_token(parser) == "INT") THEN
     208           2 :                   CALL parser_get_object(parser, desc_level)
     209             :                END IF
     210           2 :                whole_section = .TRUE.
     211           2 :                DO WHILE (parser_test_next_token(parser) == "STR")
     212           0 :                   whole_section = .FALSE.
     213             :                   CALL parser_get_object(parser, token, newline=.FALSE., &
     214           0 :                                          lower_to_upper=.TRUE.)
     215           0 :                   keyword => section_get_keyword(section, token)
     216           0 :                   IF (.NOT. ASSOCIATED(keyword)) THEN
     217             :                      CALL cp_warn(__LOCATION__, &
     218             :                                   "unknown keyword to describe "//TRIM(token)// &
     219           0 :                                   " in section "//TRIM(section%name))
     220             :                   ELSE
     221           0 :                      CALL keyword_describe(keyword, output_unit, desc_level)
     222             :                   END IF
     223             :                END DO
     224           2 :                IF (whole_section) THEN
     225           2 :                   CALL section_describe(section, output_unit, desc_level, hide_root=.NOT. root_sect)
     226             :                END IF
     227           2 :                IF (output_unit > 0) WRITE (output_unit, "(/,' ****** =========== ******',/)")
     228             : 
     229             :             ELSE ! token is a "normal" keyword
     230      597641 :                ik = section_get_keyword_index(section, token)
     231      597641 :                IF (ik < 1) THEN ! don't accept pseudo keyword names
     232      280174 :                   parser%icol = parser%icol1 - 1 ! re-read also the actual token
     233      280174 :                   ik = 0
     234      280174 :                   IF (.NOT. ASSOCIATED(section%keywords(0)%keyword)) THEN
     235           0 :                      IF (output_unit > 0) THEN
     236           0 :                         WRITE (output_unit, *)
     237           0 :                         WRITE (output_unit, '(T2,A)') "Possible matches for unknown keyword "
     238           0 :                         WRITE (output_unit, *)
     239           0 :                         WRITE (output_unit, '(T2,A)') TRIM(token)
     240           0 :                         WRITE (output_unit, *)
     241             :                         CALL section_typo_match(typo_match_section, TRIM(section%name), TRIM(token), "", &
     242           0 :                                                 typo_matching_rank, typo_matching_line, bonus=0)
     243           0 :                         DO imatch = 1, SIZE(typo_matching_rank)
     244             :                            WRITE (output_unit, '(T2,A,1X,I0)') &
     245           0 :                               TRIM(typo_matching_line(imatch))//" score: ", typo_matching_rank(imatch)
     246             :                         END DO
     247             :                      END IF
     248             :                      CALL cp_abort(__LOCATION__, &
     249             :                                    "found an unknown keyword "//TRIM(token)// &
     250           0 :                                    " in section "//TRIM(section%name))
     251             :                   END IF
     252             :                END IF
     253      597641 :                keyword => section%keywords(ik)%keyword
     254      597641 :                IF (ASSOCIATED(keyword)) THEN
     255      597641 :                   IF (keyword%removed) THEN
     256           0 :                      IF (ALLOCATED(keyword%deprecation_notice)) THEN
     257             :                         CALL cp_abort(__LOCATION__, &
     258             :                                       "The specified keyword '"//TRIM(token)//"' is not available anymore: "// &
     259           0 :                                       keyword%deprecation_notice)
     260             :                      ELSE
     261             :                         CALL cp_abort(__LOCATION__, &
     262             :                                       "The specified keyword '"//TRIM(token)// &
     263           0 :                                       "' is not available anymore, please consult the manual.")
     264             :                      END IF
     265             :                   END IF
     266             : 
     267      597641 :                   IF (ALLOCATED(keyword%deprecation_notice)) &
     268             :                      CALL cp_warn(__LOCATION__, &
     269             :                                   "The specified keyword '"//TRIM(token)// &
     270             :                                   "' is deprecated and may be removed in a future version: "// &
     271          22 :                                   keyword%deprecation_notice//".")
     272             : 
     273      597641 :                   NULLIFY (el)
     274      597641 :                   IF (ik /= 0 .AND. keyword%type_of_var == lchar_t) &
     275       19337 :                      CALL parser_skip_space(parser)
     276             :                   CALL val_create_parsing(el, type_of_var=keyword%type_of_var, &
     277             :                                           n_var=keyword%n_var, default_value=keyword%lone_keyword_value, &
     278             :                                           enum=keyword%enum, unit=keyword%unit, &
     279      597641 :                                           default_units=default_units, parser=parser)
     280      597641 :                   IF (ASSOCIATED(el)) THEN
     281      597641 :                      NULLIFY (new_val)
     282      597641 :                      CALL cp_sll_val_create(new_val, el)
     283      597641 :                      last_val => section_vals%values(ik, irs)%list
     284      597641 :                      IF (.NOT. ASSOCIATED(last_val)) THEN
     285      323192 :                         section_vals%values(ik, irs)%list => new_val
     286             :                      ELSE
     287      274449 :                         IF (.NOT. keyword%repeats) &
     288             :                            CALL cp_abort(__LOCATION__, &
     289             :                                          "Keyword "//TRIM(token)// &
     290           0 :                                          " in section "//TRIM(section%name)//" should not repeat.")
     291      274449 :                         IF (ASSOCIATED(last_val, previous_list)) THEN
     292      265124 :                            last_val => previous_last
     293             :                         ELSE
     294      274449 :                            previous_list => last_val
     295             :                         END IF
     296      274449 :                         DO WHILE (ASSOCIATED(last_val%rest))
     297      274449 :                            last_val => last_val%rest
     298             :                         END DO
     299      274449 :                         last_val%rest => new_val
     300      274449 :                         previous_last => new_val
     301             :                      END IF
     302             :                   END IF
     303             :                END IF
     304             :             END IF
     305             :          END IF
     306             :       END DO
     307      203904 :       CALL timestop(handle)
     308      203904 :    END SUBROUTINE section_vals_parse
     309             : 
     310             : ! **************************************************************************************************
     311             : !> \brief creates a val_type object by parsing the values
     312             : !> \param val the value that will be created
     313             : !> \param type_of_var type of the value to be created
     314             : !> \param n_var number of values to be parsed (-1: undefined)
     315             : !> \param enum ...
     316             : !> \param parser the parser from where the values should be read
     317             : !> \param unit ...
     318             : !> \param default_units ...
     319             : !> \param default_value a default value if nothing is found (can be null)
     320             : !> \author fawzi
     321             : !> \note
     322             : !>      - no_t does not create a value
     323             : ! **************************************************************************************************
     324      639922 :    SUBROUTINE val_create_parsing(val, type_of_var, n_var, enum, &
     325             :                                  parser, unit, default_units, default_value)
     326             :       TYPE(val_type), POINTER                            :: val
     327             :       INTEGER, INTENT(in)                                :: type_of_var, n_var
     328             :       TYPE(enumeration_type), POINTER                    :: enum
     329             :       TYPE(cp_parser_type), POINTER                      :: parser
     330             :       TYPE(cp_unit_type), POINTER                        :: unit
     331             :       TYPE(cp_unit_set_type), POINTER                    :: default_units
     332             :       TYPE(val_type), OPTIONAL, POINTER                  :: default_value
     333             : 
     334             :       CHARACTER(len=*), PARAMETER :: routineN = 'val_create_parsing'
     335             : 
     336             :       CHARACTER(len=default_string_length)               :: c_val, info, location
     337             :       CHARACTER(len=default_string_length), &
     338      639922 :          DIMENSION(:), POINTER                           :: c_val_p
     339             :       INTEGER                                            :: handle, i, i_val
     340      639922 :       INTEGER, DIMENSION(:), POINTER                     :: i_val_p
     341             :       LOGICAL                                            :: check, eol, l_val, quoted
     342      639922 :       LOGICAL, DIMENSION(:), POINTER                     :: l_val_p
     343             :       REAL(kind=dp)                                      :: r_val
     344      639922 :       REAL(kind=dp), DIMENSION(:), POINTER               :: r_val_p
     345             :       TYPE(cp_sll_char_type), POINTER                    :: c_first, c_last, c_new
     346             :       TYPE(cp_sll_int_type), POINTER                     :: i_first, i_last, i_new
     347             :       TYPE(cp_sll_logical_type), POINTER                 :: l_first, l_last, l_new
     348             :       TYPE(cp_sll_real_type), POINTER                    :: r_first, r_last, r_new
     349             : 
     350      639922 :       CALL timeset(routineN, handle)
     351             : 
     352      639922 :       CPASSERT(.NOT. ASSOCIATED(val))
     353      669407 :       SELECT CASE (type_of_var)
     354             :       CASE (no_t)
     355             :       CASE (logical_t)
     356       29485 :          NULLIFY (l_val_p)
     357       58970 :          IF (parser_test_next_token(parser) == "EOL") THEN
     358       13799 :             IF (.NOT. ASSOCIATED(default_value)) THEN
     359           0 :                IF (n_var < 1) THEN
     360           0 :                   ALLOCATE (l_val_p(0))
     361           0 :                   CALL val_create(val, l_vals_ptr=l_val_p)
     362             :                ELSE
     363             :                   CALL cp_abort(__LOCATION__, &
     364             :                                 "no value was given and there is no default value"// &
     365           0 :                                 TRIM(parser_location(parser)))
     366             :                END IF
     367             :             ELSE
     368       13799 :                CPASSERT(ASSOCIATED(default_value%l_val))
     369       13799 :                CALL val_create(val, l_vals=default_value%l_val)
     370             :             END IF
     371             :          ELSE
     372       15686 :             IF (n_var < 1) THEN
     373           0 :                NULLIFY (l_last, l_first)
     374           0 :                CALL parser_get_object(parser, l_val)
     375           0 :                CALL cp_create(l_first, l_val)
     376           0 :                l_last => l_first
     377           0 :                DO WHILE (parser_test_next_token(parser) /= "EOL")
     378           0 :                   CALL parser_get_object(parser, l_val)
     379           0 :                   CALL cp_create(l_new, l_val)
     380           0 :                   l_last%rest => l_new
     381           0 :                   l_last => l_new
     382             :                END DO
     383           0 :                l_val_p => cp_to_array(l_first)
     384           0 :                CALL cp_dealloc(l_first)
     385             :             ELSE
     386       47058 :                ALLOCATE (l_val_p(n_var))
     387       31372 :                DO i = 1, n_var
     388       31372 :                   CALL parser_get_object(parser, l_val_p(i))
     389             :                END DO
     390             :             END IF
     391       45171 :             IF (ASSOCIATED(l_val_p)) THEN
     392       15686 :                CALL val_create(val, l_vals_ptr=l_val_p)
     393             :             END IF
     394             :          END IF
     395             :       CASE (integer_t)
     396       46380 :          NULLIFY (i_val_p)
     397       92760 :          IF (parser_test_next_token(parser) == "EOL") THEN
     398          14 :             IF (.NOT. ASSOCIATED(default_value)) THEN
     399           0 :                IF (n_var < 1) THEN
     400           0 :                   ALLOCATE (i_val_p(0))
     401           0 :                   CALL val_create(val, i_vals_ptr=i_val_p)
     402             :                ELSE
     403             :                   CALL cp_abort(__LOCATION__, &
     404             :                                 "no value was given and there is no default value"// &
     405           0 :                                 TRIM(parser_location(parser)))
     406             :                END IF
     407             :             ELSE
     408          14 :                check = ASSOCIATED(default_value%i_val)
     409          14 :                CPASSERT(check)
     410          14 :                CALL val_create(val, i_vals=default_value%i_val)
     411             :             END IF
     412             :          ELSE
     413       46366 :             IF (n_var < 1) THEN
     414        7501 :                NULLIFY (i_last, i_first)
     415        7501 :                CALL parser_get_object(parser, i_val)
     416        7501 :                CALL cp_create(i_first, i_val)
     417        7501 :                i_last => i_first
     418       29449 :                DO WHILE (parser_test_next_token(parser) /= "EOL")
     419       21948 :                   CALL parser_get_object(parser, i_val)
     420       21948 :                   CALL cp_create(i_new, i_val)
     421       21948 :                   i_last%rest => i_new
     422       21948 :                   i_last => i_new
     423             :                END DO
     424        7501 :                i_val_p => cp_to_array(i_first)
     425        7501 :                CALL cp_dealloc(i_first)
     426             :             ELSE
     427      116595 :                ALLOCATE (i_val_p(n_var))
     428       82306 :                DO i = 1, n_var
     429       82306 :                   CALL parser_get_object(parser, i_val_p(i))
     430             :                END DO
     431             :             END IF
     432       92746 :             IF (ASSOCIATED(i_val_p)) THEN
     433       46366 :                CALL val_create(val, i_vals_ptr=i_val_p)
     434             :             END IF
     435             :          END IF
     436             :       CASE (real_t)
     437      150593 :          NULLIFY (r_val_p)
     438      301186 :          IF (parser_test_next_token(parser) == "EOL") THEN
     439           2 :             IF (.NOT. ASSOCIATED(default_value)) THEN
     440           2 :                IF (n_var < 1) THEN
     441           2 :                   ALLOCATE (r_val_p(0))
     442           2 :                   CALL val_create(val, r_vals_ptr=r_val_p)
     443             :                ELSE
     444             :                   CALL cp_abort(__LOCATION__, &
     445             :                                 "no value was given and there is no default value"// &
     446           0 :                                 TRIM(parser_location(parser)))
     447             :                END IF
     448             :             ELSE
     449           0 :                CPASSERT(ASSOCIATED(default_value%r_val))
     450           0 :                CALL val_create(val, r_vals=default_value%r_val)
     451             :             END IF
     452             :          ELSE
     453      150591 :             IF (n_var < 1) THEN
     454       16771 :                NULLIFY (r_last, r_first)
     455       16771 :                c_val = ""
     456       16771 :                CALL get_r_val(r_val, parser, unit, default_units, c_val)
     457       16771 :                CALL cp_create(r_first, r_val)
     458       16771 :                r_last => r_first
     459     6335207 :                DO WHILE (parser_test_next_token(parser) /= "EOL")
     460     6318436 :                   CALL get_r_val(r_val, parser, unit, default_units, c_val)
     461     6318436 :                   CALL cp_create(r_new, r_val)
     462     6318436 :                   r_last%rest => r_new
     463     6318436 :                   r_last => r_new
     464             :                END DO
     465       16771 :                NULLIFY (r_last)
     466       16771 :                r_val_p => cp_to_array(r_first)
     467       16771 :                CALL cp_dealloc(r_first)
     468             :             ELSE
     469      401460 :                ALLOCATE (r_val_p(n_var))
     470      133820 :                c_val = ""
     471      350148 :                DO i = 1, n_var
     472      350148 :                   CALL get_r_val(r_val_p(i), parser, unit, default_units, c_val)
     473             :                END DO
     474             :             END IF
     475      301184 :             IF (ASSOCIATED(r_val_p)) THEN
     476      150591 :                CALL val_create(val, r_vals_ptr=r_val_p)
     477             :             END IF
     478             :          END IF
     479             :       CASE (char_t)
     480       66253 :          NULLIFY (c_val_p)
     481      132506 :          IF (parser_test_next_token(parser) == "EOL") THEN
     482         206 :             IF (n_var < 1) THEN
     483           2 :                ALLOCATE (c_val_p(1))
     484           2 :                c_val_p(1) = ' '
     485           2 :                CALL val_create(val, c_vals_ptr=c_val_p)
     486             :             ELSE
     487         204 :                IF (.NOT. ASSOCIATED(default_value)) THEN
     488             :                   CALL cp_abort(__LOCATION__, &
     489             :                                 "no value was given and there is no default value"// &
     490           0 :                                 TRIM(parser_location(parser)))
     491             :                ELSE
     492         204 :                   CPASSERT(ASSOCIATED(default_value%c_val))
     493         204 :                   CALL val_create(val, c_vals=default_value%c_val)
     494             :                END IF
     495             :             END IF
     496             :          ELSE
     497       66047 :             IF (n_var < 1) THEN
     498       24074 :                CPASSERT(n_var == -1)
     499       24074 :                NULLIFY (c_last, c_first)
     500       24074 :                CALL parser_get_object(parser, c_val)
     501       24074 :                CALL cp_create(c_first, c_val)
     502       24074 :                c_last => c_first
     503       30674 :                DO WHILE (parser_test_next_token(parser) /= "EOL")
     504        6600 :                   CALL parser_get_object(parser, c_val)
     505        6600 :                   CALL cp_create(c_new, c_val)
     506        6600 :                   c_last%rest => c_new
     507        6600 :                   c_last => c_new
     508             :                END DO
     509       24074 :                c_val_p => cp_to_array(c_first)
     510       24074 :                CALL cp_dealloc(c_first)
     511             :             ELSE
     512      125919 :                ALLOCATE (c_val_p(n_var))
     513       99748 :                DO i = 1, n_var
     514       99748 :                   CALL parser_get_object(parser, c_val_p(i))
     515             :                END DO
     516             :             END IF
     517      132300 :             IF (ASSOCIATED(c_val_p)) THEN
     518       66047 :                CALL val_create(val, c_vals_ptr=c_val_p)
     519             :             END IF
     520             :          END IF
     521             :       CASE (lchar_t)
     522      257515 :          IF (ASSOCIATED(default_value)) &
     523             :             CALL cp_abort(__LOCATION__, &
     524             :                           "input variables of type lchar_t cannot have a lone keyword attribute,"// &
     525             :                           " no value is interpreted as empty string"// &
     526           0 :                           TRIM(parser_location(parser)))
     527      257515 :          IF (n_var /= 1) &
     528             :             CALL cp_abort(__LOCATION__, &
     529             :                           "input variables of type lchar_t cannot be repeated,"// &
     530             :                           " one always represent a whole line, till the end"// &
     531           0 :                           TRIM(parser_location(parser)))
     532      257515 :          IF (parser_test_next_token(parser) == "EOL") THEN
     533          74 :             ALLOCATE (c_val_p(1))
     534          74 :             c_val_p(1) = ' '
     535             :          ELSE
     536      257441 :             NULLIFY (c_last, c_first)
     537      257441 :             CALL parser_get_object(parser, c_val, string_length=LEN(c_val))
     538      257441 :             IF (c_val(1:1) == parser%quote_character) THEN
     539           8 :                quoted = .TRUE.
     540           8 :                c_val(1:) = c_val(2:) ! Drop first quotation mark
     541           8 :                i = INDEX(c_val, parser%quote_character) ! Check for second quotation mark
     542           8 :                IF (i > 0) THEN
     543           0 :                   c_val(i:) = "" ! Discard stuff after second quotation mark
     544             :                   eol = .TRUE. ! Enforce end of line
     545             :                ELSE
     546             :                   eol = .FALSE.
     547             :                END IF
     548             :             ELSE
     549             :                quoted = .FALSE.
     550             :                eol = .FALSE.
     551             :             END IF
     552      257441 :             CALL cp_create(c_first, c_val)
     553      257441 :             c_last => c_first
     554      288131 :             DO WHILE ((.NOT. eol) .AND. (parser_test_next_token(parser) /= "EOL"))
     555       30690 :                CALL parser_get_object(parser, c_val, string_length=LEN(c_val))
     556       30690 :                i = INDEX(c_val, parser%quote_character) ! Check for quotation mark
     557       30690 :                IF (i > 0) THEN
     558           8 :                   IF (quoted) THEN
     559           8 :                      c_val(i:) = "" ! Discard stuff after second quotation mark
     560             :                      eol = .TRUE. ! Enforce end of line
     561             :                   ELSE
     562             :                      CALL cp_abort(__LOCATION__, &
     563             :                                    "Quotation mark found which is not the first non-blank character. "// &
     564             :                                    "Possibly the first quotation mark is missing?"// &
     565           0 :                                    TRIM(parser_location(parser)))
     566             :                   END IF
     567             :                ELSE
     568             :                   eol = .FALSE.
     569             :                END IF
     570       30690 :                CALL cp_create(c_new, c_val)
     571       30690 :                c_last%rest => c_new
     572       30690 :                c_last => c_new
     573             :             END DO
     574      257441 :             c_val_p => cp_to_array(c_first)
     575      514956 :             CALL cp_dealloc(c_first)
     576             :          END IF
     577      257515 :          CPASSERT(ASSOCIATED(c_val_p))
     578      257515 :          CALL val_create(val, lc_vals_ptr=c_val_p)
     579             :       CASE (enum_t)
     580       89696 :          CPASSERT(ASSOCIATED(enum))
     581       89696 :          NULLIFY (i_val_p)
     582      179392 :          IF (parser_test_next_token(parser) == "EOL") THEN
     583        9786 :             IF (.NOT. ASSOCIATED(default_value)) THEN
     584           0 :                IF (n_var < 1) THEN
     585           0 :                   ALLOCATE (i_val_p(0))
     586           0 :                   CALL val_create(val, i_vals_ptr=i_val_p)
     587             :                ELSE
     588             :                   CALL cp_abort(__LOCATION__, &
     589             :                                 "no value was given and there is no default value"// &
     590           0 :                                 TRIM(parser_location(parser)))
     591             :                END IF
     592             :             ELSE
     593        9786 :                CPASSERT(ASSOCIATED(default_value%i_val))
     594             :                CALL val_create(val, i_vals=default_value%i_val, &
     595        9786 :                                enum=default_value%enum)
     596             :             END IF
     597             :          ELSE
     598       79910 :             IF (n_var < 1) THEN
     599          58 :                NULLIFY (i_last, i_first)
     600          58 :                CALL parser_get_object(parser, c_val)
     601          58 :                CALL cp_create(i_first, enum_c2i(enum, c_val))
     602          58 :                i_last => i_first
     603          64 :                DO WHILE (parser_test_next_token(parser) /= "EOL")
     604           6 :                   CALL parser_get_object(parser, c_val)
     605           6 :                   CALL cp_create(i_new, enum_c2i(enum, c_val))
     606           6 :                   i_last%rest => i_new
     607           6 :                   i_last => i_new
     608             :                END DO
     609          58 :                i_val_p => cp_to_array(i_first)
     610          58 :                CALL cp_dealloc(i_first)
     611             :             ELSE
     612      239556 :                ALLOCATE (i_val_p(n_var))
     613      159704 :                DO i = 1, n_var
     614       79852 :                   CALL parser_get_object(parser, c_val)
     615      159704 :                   i_val_p(i) = enum_c2i(enum, c_val)
     616             :                END DO
     617             :             END IF
     618      169606 :             IF (ASSOCIATED(i_val_p)) THEN
     619       79910 :                CALL val_create(val, i_vals_ptr=i_val_p, enum=enum)
     620             :             END IF
     621             :          END IF
     622             :       CASE default
     623             :          CALL cp_abort(__LOCATION__, &
     624      639922 :                        "type "//cp_to_string(type_of_var)//"unknown to the parser")
     625             :       END SELECT
     626      639922 :       IF (parser_test_next_token(parser) .NE. "EOL") THEN
     627           0 :          location = TRIM(parser_location(parser))
     628           0 :          CALL parser_get_object(parser, info)
     629             :          CALL cp_abort(__LOCATION__, &
     630      639922 :                        "found unexpected extra argument "//TRIM(info)//" at "//location)
     631             :       END IF
     632             : 
     633      639922 :       CALL timestop(handle)
     634             : 
     635      639922 :    END SUBROUTINE val_create_parsing
     636             : 
     637             : ! **************************************************************************************************
     638             : !> \brief Reads and convert a real number from the input file
     639             : !> \param r_val ...
     640             : !> \param parser the parser from where the values should be read
     641             : !> \param unit ...
     642             : !> \param default_units ...
     643             : !> \param c_val ...
     644             : !> \author Teodoro Laino - 11.2007 [tlaino] - University of Zurich
     645             : ! **************************************************************************************************
     646     6551535 :    SUBROUTINE get_r_val(r_val, parser, unit, default_units, c_val)
     647             :       REAL(kind=dp), INTENT(OUT)                         :: r_val
     648             :       TYPE(cp_parser_type), POINTER                      :: parser
     649             :       TYPE(cp_unit_type), POINTER                        :: unit
     650             :       TYPE(cp_unit_set_type), POINTER                    :: default_units
     651             :       CHARACTER(len=default_string_length), &
     652             :          INTENT(INOUT)                                   :: c_val
     653             : 
     654             :       TYPE(cp_unit_type), POINTER                        :: my_unit
     655             : 
     656     6551535 :       NULLIFY (my_unit)
     657     6551535 :       IF (ASSOCIATED(unit)) THEN
     658       97443 :          IF ('STR' == parser_test_next_token(parser)) THEN
     659       11390 :             CALL parser_get_object(parser, c_val)
     660       11390 :             IF (c_val(1:1) /= "[" .OR. c_val(LEN_TRIM(c_val):LEN_TRIM(c_val)) /= "]") THEN
     661             :                CALL cp_abort(__LOCATION__, &
     662             :                              "Invalid unit specifier found when parsing a number: "// &
     663           0 :                              c_val)
     664             :             END IF
     665       11390 :             CALL cp_unit_create(my_unit, c_val(2:LEN_TRIM(c_val) - 1))
     666             :          ELSE
     667      183496 :             IF (c_val /= "") THEN
     668        2704 :                CALL cp_unit_create(my_unit, c_val(2:LEN_TRIM(c_val) - 1))
     669             :             ELSE
     670       83349 :                my_unit => unit
     671             :             END IF
     672             :          END IF
     673       97443 :          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     6551535 :       CALL parser_get_object(parser, r_val)
     680     6551535 :       IF (ASSOCIATED(unit)) THEN
     681       97443 :          r_val = cp_unit_to_cp2k1(r_val, my_unit, default_units)
     682       97443 :          IF (.NOT. (ASSOCIATED(my_unit, unit))) CALL cp_unit_release(my_unit)
     683             :       END IF
     684             : 
     685     6551535 :    END SUBROUTINE get_r_val
     686             : 
     687             : END MODULE input_parsing

Generated by: LCOV version 1.15