LCOV - code coverage report
Current view: top level - src/input - input_keyword_types.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:71c3ab0) Lines: 46.0 % 383 176
Test Date: 2026-07-25 06:35:44 Functions: 50.0 % 10 5

            Line data    Source code
       1              : !--------------------------------------------------------------------------------------------------!
       2              : !   CP2K: A general program to perform molecular dynamics simulations                              !
       3              : !   Copyright 2000-2026 CP2K developers group <https://cp2k.org>                                   !
       4              : !                                                                                                  !
       5              : !   SPDX-License-Identifier: GPL-2.0-or-later                                                      !
       6              : !--------------------------------------------------------------------------------------------------!
       7              : 
       8              : ! **************************************************************************************************
       9              : !> \brief represents keywords in an input
      10              : !> \par History
      11              : !>      06.2004 created, based on Joost cp_keywords proposal [fawzi]
      12              : !> \author fawzi
      13              : ! **************************************************************************************************
      14              : MODULE input_keyword_types
      15              :    USE cp_units,                        ONLY: cp_unit_create,&
      16              :                                               cp_unit_desc,&
      17              :                                               cp_unit_desc_length,&
      18              :                                               cp_unit_release,&
      19              :                                               cp_unit_type
      20              :    USE input_enumeration_types,         ONLY: enum_create,&
      21              :                                               enum_release,&
      22              :                                               enum_retain,&
      23              :                                               enumeration_type
      24              :    USE input_val_types,                 ONLY: &
      25              :         char_t, enum_t, integer_t, lchar_t, logical_t, no_t, real_t, val_create, val_release, &
      26              :         val_retain, val_type, val_write, val_write_internal
      27              :    USE kinds,                           ONLY: default_string_length,&
      28              :                                               dp
      29              :    USE print_messages,                  ONLY: print_message
      30              :    USE reference_manager,               ONLY: get_citation_key
      31              :    USE string_utilities,                ONLY: a2s,&
      32              :                                               compress,&
      33              :                                               substitute_special_xml_tokens,&
      34              :                                               typo_match,&
      35              :                                               uppercase
      36              : #include "../base/base_uses.f90"
      37              : 
      38              :    IMPLICIT NONE
      39              :    PRIVATE
      40              : 
      41              :    LOGICAL, PRIVATE, PARAMETER :: debug_this_module = .TRUE.
      42              :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'input_keyword_types'
      43              : 
      44              :    INTEGER, PARAMETER, PUBLIC :: usage_string_length = default_string_length*2
      45              : 
      46              :    PUBLIC :: keyword_p_type, keyword_type, keyword_create, keyword_retain, &
      47              :              keyword_release, keyword_get, keyword_describe, &
      48              :              write_keyword_xml, keyword_typo_match
      49              : 
      50              : ! **************************************************************************************************
      51              : !> \brief represent a pointer to a keyword (to make arrays of pointers)
      52              : !> \param keyword the pointer to the keyword
      53              : !> \author fawzi
      54              : ! **************************************************************************************************
      55              :    TYPE keyword_p_type
      56              :       TYPE(keyword_type), POINTER :: keyword => NULL()
      57              :    END TYPE keyword_p_type
      58              : 
      59              : ! **************************************************************************************************
      60              : !> \brief represent a keyword in the input
      61              : !> \param names the names of the current keyword (at least one should be
      62              : !>        present) for example "MAXSCF"
      63              : !> \param location is where in the source code (file and line) the keyword is created
      64              : !> \param usage how to use it "MAXSCF 10"
      65              : !> \param description what does it do: "MAXSCF : determines the maximum
      66              : !>        number of steps in an SCF run"
      67              : !> \param deprecation_notice show this warning that the keyword is deprecated
      68              : !> \param citations references to literature associated with this keyword
      69              : !> \param type_of_var the type of keyword (controls how it is parsed)
      70              : !>        it can be one of: no_parse_t,logical_t, integer_t, real_t,
      71              : !>        char_t
      72              : !> \param n_var number of values that should be parsed (-1=unknown)
      73              : !> \param repeats if the keyword can be present more than once in the
      74              : !>        section
      75              : !> \param removed to trigger a CPABORT when encountered while parsing the input
      76              : !> \param enum enumeration that defines the mapping between integers and
      77              : !>        strings
      78              : !> \param unit the default unit this keyword is read in (to automatically
      79              : !>        convert to the internal cp2k units during parsing)
      80              : !> \param default_value the default value for the keyword
      81              : !> \param lone_keyword_value value to be used in presence of the keyword
      82              : !>        without any parameter
      83              : !> \note
      84              : !>      I have expressely avoided a format string for the type of keywords:
      85              : !>      they should easily map to basic types of fortran, if you need more
      86              : !>      information use a subsection. [fawzi]
      87              : !> \author Joost & fawzi
      88              : ! **************************************************************************************************
      89              :    TYPE keyword_type
      90              :       INTEGER :: ref_count = 0
      91              :       CHARACTER(LEN=default_string_length), DIMENSION(:), POINTER :: names => NULL()
      92              :       CHARACTER(LEN=usage_string_length) :: location = ""
      93              :       CHARACTER(LEN=usage_string_length) :: usage = ""
      94              :       CHARACTER, DIMENSION(:), POINTER :: description => null()
      95              :       CHARACTER(LEN=:), ALLOCATABLE :: deprecation_notice
      96              :       INTEGER, POINTER, DIMENSION(:) :: citations => NULL()
      97              :       INTEGER :: type_of_var = 0, n_var = 0
      98              :       LOGICAL :: repeats = .FALSE., removed = .FALSE.
      99              :       TYPE(enumeration_type), POINTER :: enum => NULL()
     100              :       TYPE(cp_unit_type), POINTER :: unit => NULL()
     101              :       TYPE(val_type), POINTER :: default_value => NULL()
     102              :       TYPE(val_type), POINTER :: lone_keyword_value => NULL()
     103              :    END TYPE keyword_type
     104              : 
     105              : CONTAINS
     106              : 
     107              : ! **************************************************************************************************
     108              : !> \brief creates a keyword object
     109              : !> \param keyword the keyword object to be created
     110              : !> \param location from where in the source code keyword_create() is called
     111              : !> \param name the name of the keyword
     112              : !> \param description ...
     113              : !> \param usage ...
     114              : !> \param type_of_var ...
     115              : !> \param n_var ...
     116              : !> \param repeats ...
     117              : !> \param variants ...
     118              : !> \param default_val ...
     119              : !> \param default_l_val ...
     120              : !> \param default_r_val ...
     121              : !> \param default_lc_val ...
     122              : !> \param default_c_val ...
     123              : !> \param default_i_val ...
     124              : !> \param default_l_vals ...
     125              : !> \param default_r_vals ...
     126              : !> \param default_c_vals ...
     127              : !> \param default_i_vals ...
     128              : !> \param lone_keyword_val ...
     129              : !> \param lone_keyword_l_val ...
     130              : !> \param lone_keyword_r_val ...
     131              : !> \param lone_keyword_c_val ...
     132              : !> \param lone_keyword_i_val ...
     133              : !> \param lone_keyword_l_vals ...
     134              : !> \param lone_keyword_r_vals ...
     135              : !> \param lone_keyword_c_vals ...
     136              : !> \param lone_keyword_i_vals ...
     137              : !> \param enum_c_vals ...
     138              : !> \param enum_i_vals ...
     139              : !> \param enum ...
     140              : !> \param enum_strict ...
     141              : !> \param enum_desc ...
     142              : !> \param unit_str ...
     143              : !> \param citations ...
     144              : !> \param deprecation_notice ...
     145              : !> \param removed ...
     146              : !> \author fawzi
     147              : ! **************************************************************************************************
     148    836117882 :    SUBROUTINE keyword_create(keyword, location, name, description, usage, type_of_var, &
     149     13271875 :                              n_var, repeats, variants, default_val, &
     150              :                              default_l_val, default_r_val, default_lc_val, default_c_val, default_i_val, &
     151    836117882 :                              default_l_vals, default_r_vals, default_c_vals, default_i_vals, &
     152              :                              lone_keyword_val, lone_keyword_l_val, lone_keyword_r_val, lone_keyword_c_val, &
     153   1672235764 :                              lone_keyword_i_val, lone_keyword_l_vals, lone_keyword_r_vals, &
     154   2508353646 :                              lone_keyword_c_vals, lone_keyword_i_vals, enum_c_vals, enum_i_vals, &
     155   1672235764 :                              enum, enum_strict, enum_desc, unit_str, citations, deprecation_notice, removed)
     156              :       TYPE(keyword_type), POINTER                        :: keyword
     157              :       CHARACTER(len=*), INTENT(in)                       :: location, name, description
     158              :       CHARACTER(len=*), INTENT(in), OPTIONAL             :: usage
     159              :       INTEGER, INTENT(in), OPTIONAL                      :: type_of_var, n_var
     160              :       LOGICAL, INTENT(in), OPTIONAL                      :: repeats
     161              :       CHARACTER(len=*), DIMENSION(:), INTENT(in), &
     162              :          OPTIONAL                                        :: variants
     163              :       TYPE(val_type), OPTIONAL, POINTER                  :: default_val
     164              :       LOGICAL, INTENT(in), OPTIONAL                      :: default_l_val
     165              :       REAL(KIND=DP), INTENT(in), OPTIONAL                :: default_r_val
     166              :       CHARACTER(len=*), INTENT(in), OPTIONAL             :: default_lc_val, default_c_val
     167              :       INTEGER, INTENT(in), OPTIONAL                      :: default_i_val
     168              :       LOGICAL, DIMENSION(:), INTENT(in), OPTIONAL        :: default_l_vals
     169              :       REAL(KIND=DP), DIMENSION(:), INTENT(in), OPTIONAL  :: default_r_vals
     170              :       CHARACTER(len=*), DIMENSION(:), INTENT(in), &
     171              :          OPTIONAL                                        :: default_c_vals
     172              :       INTEGER, DIMENSION(:), INTENT(in), OPTIONAL        :: default_i_vals
     173              :       TYPE(val_type), OPTIONAL, POINTER                  :: lone_keyword_val
     174              :       LOGICAL, INTENT(in), OPTIONAL                      :: lone_keyword_l_val
     175              :       REAL(KIND=DP), INTENT(in), OPTIONAL                :: lone_keyword_r_val
     176              :       CHARACTER(len=*), INTENT(in), OPTIONAL             :: lone_keyword_c_val
     177              :       INTEGER, INTENT(in), OPTIONAL                      :: lone_keyword_i_val
     178              :       LOGICAL, DIMENSION(:), INTENT(in), OPTIONAL        :: lone_keyword_l_vals
     179              :       REAL(KIND=DP), DIMENSION(:), INTENT(in), OPTIONAL  :: lone_keyword_r_vals
     180              :       CHARACTER(len=*), DIMENSION(:), INTENT(in), &
     181              :          OPTIONAL                                        :: lone_keyword_c_vals
     182              :       INTEGER, DIMENSION(:), INTENT(in), OPTIONAL        :: lone_keyword_i_vals
     183              :       CHARACTER(len=*), DIMENSION(:), INTENT(in), &
     184              :          OPTIONAL                                        :: enum_c_vals
     185              :       INTEGER, DIMENSION(:), INTENT(in), OPTIONAL        :: enum_i_vals
     186              :       TYPE(enumeration_type), OPTIONAL, POINTER          :: enum
     187              :       LOGICAL, INTENT(in), OPTIONAL                      :: enum_strict
     188              :       CHARACTER(len=*), DIMENSION(:), INTENT(in), &
     189              :          OPTIONAL                                        :: enum_desc
     190              :       CHARACTER(len=*), INTENT(in), OPTIONAL             :: unit_str
     191              :       INTEGER, DIMENSION(:), INTENT(in), OPTIONAL        :: citations
     192              :       CHARACTER(len=*), INTENT(in), OPTIONAL             :: deprecation_notice
     193              :       LOGICAL, INTENT(in), OPTIONAL                      :: removed
     194              : 
     195              :       CHARACTER(LEN=default_string_length)               :: tmp_string
     196              :       INTEGER                                            :: i, n
     197              :       LOGICAL                                            :: check
     198              : 
     199    836117882 :       CPASSERT(.NOT. ASSOCIATED(keyword))
     200    836117882 :       ALLOCATE (keyword)
     201    836117882 :       keyword%ref_count = 1
     202    836117882 :       NULLIFY (keyword%unit)
     203    836117882 :       keyword%location = location
     204    836117882 :       keyword%removed = .FALSE.
     205              : 
     206    836117882 :       CPASSERT(LEN_TRIM(name) > 0)
     207              : 
     208    836117882 :       IF (PRESENT(variants)) THEN
     209     39815625 :          ALLOCATE (keyword%names(SIZE(variants) + 1))
     210     13271875 :          keyword%names(1) = name
     211     30960292 :          DO i = 1, SIZE(variants)
     212     17688417 :             CPASSERT(LEN_TRIM(variants(i)) > 0)
     213     30960292 :             keyword%names(i + 1) = variants(i)
     214              :          END DO
     215              :       ELSE
     216    822846007 :          ALLOCATE (keyword%names(1))
     217    822846007 :          keyword%names(1) = name
     218              :       END IF
     219   1689924181 :       DO i = 1, SIZE(keyword%names)
     220   1689924181 :          CALL uppercase(keyword%names(i))
     221              :       END DO
     222              : 
     223    836117882 :       IF (PRESENT(usage)) THEN
     224    279618290 :          CPASSERT(LEN_TRIM(usage) <= LEN(keyword%usage))
     225    279618290 :          keyword%usage = usage
     226              :          ! Check that the usage string starts with one of the keyword names.
     227    279618290 :          IF (keyword%names(1) /= "_SECTION_PARAMETERS_" .AND. keyword%names(1) /= "_DEFAULT_KEYWORD_") THEN
     228    267966968 :             tmp_string = usage
     229    267966968 :             CALL uppercase(tmp_string)
     230    267966968 :             check = .FALSE.
     231    548794808 :             DO i = 1, SIZE(keyword%names)
     232    549951024 :                check = check .OR. (INDEX(tmp_string, TRIM(keyword%names(i))) == 1)
     233              :             END DO
     234    267966968 :             IF (.NOT. check) THEN
     235            0 :                CPABORT("Usage string must start with one of the keyword name.")
     236              :             END IF
     237              :          END IF
     238              :       ELSE
     239    556499592 :          keyword%usage = ""
     240              :       END IF
     241              : 
     242    836117882 :       n = LEN_TRIM(description)
     243   2508206778 :       ALLOCATE (keyword%description(n))
     244  40943321249 :       DO i = 1, n
     245  40943321249 :          keyword%description(i) = description(i:i)
     246              :       END DO
     247              : 
     248    836117882 :       IF (PRESENT(citations)) THEN
     249      3769803 :          ALLOCATE (keyword%citations(SIZE(citations, 1)))
     250      3590898 :          keyword%citations = citations
     251              :       ELSE
     252    834861281 :          NULLIFY (keyword%citations)
     253              :       END IF
     254              : 
     255    836117882 :       keyword%repeats = .FALSE.
     256    836117882 :       IF (PRESENT(repeats)) keyword%repeats = repeats
     257              : 
     258    836117882 :       NULLIFY (keyword%enum)
     259    836117882 :       IF (PRESENT(enum)) THEN
     260            0 :          keyword%enum => enum
     261            0 :          IF (ASSOCIATED(enum)) CALL enum_retain(enum)
     262              :       END IF
     263    836117882 :       IF (PRESENT(enum_i_vals)) THEN
     264     29292191 :          CPASSERT(PRESENT(enum_c_vals))
     265     29292191 :          CPASSERT(.NOT. ASSOCIATED(keyword%enum))
     266              :          CALL enum_create(keyword%enum, c_vals=enum_c_vals, i_vals=enum_i_vals, &
     267     39403199 :                           desc=enum_desc, strict=enum_strict)
     268              :       ELSE
     269    806825691 :          CPASSERT(.NOT. PRESENT(enum_c_vals))
     270              :       END IF
     271              : 
     272    836117882 :       NULLIFY (keyword%default_value, keyword%lone_keyword_value)
     273    836117882 :       IF (PRESENT(default_val)) THEN
     274              :          IF (PRESENT(default_l_val) .OR. PRESENT(default_l_vals) .OR. &
     275              :              PRESENT(default_i_val) .OR. PRESENT(default_i_vals) .OR. &
     276              :              PRESENT(default_r_val) .OR. PRESENT(default_r_vals) .OR. &
     277            0 :              PRESENT(default_c_val) .OR. PRESENT(default_c_vals)) THEN
     278            0 :             CPABORT("you should pass either default_val or a default value, not both")
     279              :          END IF
     280            0 :          keyword%default_value => default_val
     281            0 :          IF (ASSOCIATED(default_val%enum)) THEN
     282            0 :             IF (ASSOCIATED(keyword%enum)) THEN
     283            0 :                CPASSERT(ASSOCIATED(keyword%enum, default_val%enum))
     284              :             ELSE
     285            0 :                keyword%enum => default_val%enum
     286            0 :                CALL enum_retain(keyword%enum)
     287              :             END IF
     288              :          ELSE
     289            0 :             CPASSERT(.NOT. ASSOCIATED(keyword%enum))
     290              :          END IF
     291            0 :          CALL val_retain(default_val)
     292              :       END IF
     293    836117882 :       IF (.NOT. ASSOCIATED(keyword%default_value)) THEN
     294              :          CALL val_create(keyword%default_value, l_val=default_l_val, &
     295              :                          l_vals=default_l_vals, i_val=default_i_val, i_vals=default_i_vals, &
     296              :                          r_val=default_r_val, r_vals=default_r_vals, c_val=default_c_val, &
     297   5836338969 :                          c_vals=default_c_vals, lc_val=default_lc_val, enum=keyword%enum)
     298              :       END IF
     299              : 
     300    836117882 :       keyword%type_of_var = keyword%default_value%type_of_var
     301    836117882 :       IF (keyword%default_value%type_of_var == no_t) THEN
     302     18062001 :          CALL val_release(keyword%default_value)
     303              :       END IF
     304              : 
     305    836117882 :       IF (keyword%type_of_var == no_t) THEN
     306     18062001 :          IF (PRESENT(type_of_var)) THEN
     307     18062001 :             keyword%type_of_var = type_of_var
     308              :          ELSE
     309              :             CALL cp_abort(__LOCATION__, &
     310              :                           "keyword "//TRIM(keyword%names(1))// &
     311            0 :                           " assumed undefined type by default")
     312              :          END IF
     313    818055881 :       ELSE IF (PRESENT(type_of_var)) THEN
     314     16796202 :          IF (keyword%type_of_var /= type_of_var) THEN
     315              :             CALL cp_abort(__LOCATION__, &
     316              :                           "keyword "//TRIM(keyword%names(1))// &
     317            0 :                           " has a type different from the type of the default_value")
     318              :          END IF
     319     16796202 :          keyword%type_of_var = type_of_var
     320              :       END IF
     321              : 
     322    836117882 :       IF (keyword%type_of_var == no_t) THEN
     323            0 :          CALL val_create(keyword%default_value)
     324              :       END IF
     325              : 
     326    836117882 :       IF (PRESENT(lone_keyword_val)) THEN
     327              :          IF (PRESENT(lone_keyword_l_val) .OR. PRESENT(lone_keyword_l_vals) .OR. &
     328              :              PRESENT(lone_keyword_i_val) .OR. PRESENT(lone_keyword_i_vals) .OR. &
     329              :              PRESENT(lone_keyword_r_val) .OR. PRESENT(lone_keyword_r_vals) .OR. &
     330            0 :              PRESENT(lone_keyword_c_val) .OR. PRESENT(lone_keyword_c_vals)) THEN
     331              :             CALL cp_abort(__LOCATION__, &
     332            0 :                           "you should pass either lone_keyword_val or a lone_keyword value, not both")
     333              :          END IF
     334            0 :          keyword%lone_keyword_value => lone_keyword_val
     335            0 :          CALL val_retain(lone_keyword_val)
     336            0 :          IF (ASSOCIATED(lone_keyword_val%enum)) THEN
     337            0 :             IF (ASSOCIATED(keyword%enum)) THEN
     338            0 :                IF (.NOT. ASSOCIATED(keyword%enum, lone_keyword_val%enum)) THEN
     339            0 :                   CPABORT("keyword%enum/=lone_keyword_val%enum")
     340              :                END IF
     341              :             ELSE
     342            0 :                IF (ASSOCIATED(keyword%lone_keyword_value)) THEN
     343            0 :                   CPABORT(".NOT. ASSOCIATED(keyword%lone_keyword_value)")
     344              :                END IF
     345            0 :                keyword%enum => lone_keyword_val%enum
     346            0 :                CALL enum_retain(keyword%enum)
     347              :             END IF
     348              :          ELSE
     349            0 :             CPASSERT(.NOT. ASSOCIATED(keyword%enum))
     350              :          END IF
     351              :       END IF
     352    836117882 :       IF (.NOT. ASSOCIATED(keyword%lone_keyword_value)) THEN
     353              :          CALL val_create(keyword%lone_keyword_value, l_val=lone_keyword_l_val, &
     354              :                          l_vals=lone_keyword_l_vals, i_val=lone_keyword_i_val, i_vals=lone_keyword_i_vals, &
     355              :                          r_val=lone_keyword_r_val, r_vals=lone_keyword_r_vals, c_val=lone_keyword_c_val, &
     356   5016528950 :                          c_vals=lone_keyword_c_vals, enum=keyword%enum)
     357              :       END IF
     358    836117882 :       IF (ASSOCIATED(keyword%lone_keyword_value)) THEN
     359    836117882 :          IF (keyword%lone_keyword_value%type_of_var == no_t) THEN
     360    721078545 :             CALL val_release(keyword%lone_keyword_value)
     361              :          ELSE
     362    115039337 :             IF (keyword%lone_keyword_value%type_of_var /= keyword%type_of_var) THEN
     363            0 :                CPABORT("lone_keyword_value type incompatible with keyword type")
     364              :             END IF
     365              :             ! lc_val cannot have lone_keyword_value!
     366    115039337 :             IF (keyword%type_of_var == enum_t) THEN
     367      7995374 :                IF (keyword%enum%strict) THEN
     368      7995374 :                   check = .FALSE.
     369     63919100 :                   DO i = 1, SIZE(keyword%enum%i_vals)
     370     96463758 :                      check = check .OR. (keyword%default_value%i_val(1) == keyword%enum%i_vals(i))
     371              :                   END DO
     372      7995374 :                   IF (.NOT. check) THEN
     373            0 :                      CPABORT("default value not in enumeration : "//keyword%names(1))
     374              :                   END IF
     375              :                END IF
     376              :             END IF
     377              :          END IF
     378              :       END IF
     379              : 
     380    836117882 :       keyword%n_var = 1
     381    836117882 :       IF (ASSOCIATED(keyword%default_value)) THEN
     382    926837231 :          SELECT CASE (keyword%default_value%type_of_var)
     383              :          CASE (logical_t)
     384    108781350 :             keyword%n_var = SIZE(keyword%default_value%l_val)
     385              :          CASE (integer_t)
     386    181534954 :             keyword%n_var = SIZE(keyword%default_value%i_val)
     387              :          CASE (enum_t)
     388     29195864 :             IF (keyword%enum%strict) THEN
     389     29195864 :                check = .FALSE.
     390    161805830 :                DO i = 1, SIZE(keyword%enum%i_vals)
     391    204795523 :                   check = check .OR. (keyword%default_value%i_val(1) == keyword%enum%i_vals(i))
     392              :                END DO
     393     29195864 :                IF (.NOT. check) THEN
     394            0 :                   CPABORT("default value not in enumeration : "//keyword%names(1))
     395              :                END IF
     396              :             END IF
     397     29195864 :             keyword%n_var = SIZE(keyword%default_value%i_val)
     398              :          CASE (real_t)
     399    486147767 :             keyword%n_var = SIZE(keyword%default_value%r_val)
     400              :          CASE (char_t)
     401      3563066 :             keyword%n_var = SIZE(keyword%default_value%c_val)
     402              :          CASE (lchar_t)
     403      8832880 :             keyword%n_var = 1
     404              :          CASE (no_t)
     405            0 :             keyword%n_var = 0
     406              :          CASE default
     407    818055881 :             CPABORT("Unknown type_of_var for keyword_create")
     408              :          END SELECT
     409              :       END IF
     410    836117882 :       IF (PRESENT(n_var)) keyword%n_var = n_var
     411    836117882 :       IF (keyword%type_of_var == lchar_t .AND. keyword%n_var /= 1) THEN
     412            0 :          CPABORT("arrays of lchar_t not supported : "//keyword%names(1))
     413              :       END IF
     414              : 
     415    836117882 :       IF (PRESENT(unit_str)) THEN
     416    379318325 :          ALLOCATE (keyword%unit)
     417     15172733 :          CALL cp_unit_create(keyword%unit, unit_str)
     418              :       END IF
     419              : 
     420    836117882 :       IF (PRESENT(deprecation_notice)) THEN
     421        83920 :          keyword%deprecation_notice = TRIM(deprecation_notice)
     422              :       END IF
     423              : 
     424    836117882 :       IF (PRESENT(removed)) THEN
     425        52430 :          keyword%removed = removed
     426              :       END IF
     427    836117882 :    END SUBROUTINE keyword_create
     428              : 
     429              : ! **************************************************************************************************
     430              : !> \brief retains the given keyword (see doc/ReferenceCounting.html)
     431              : !> \param keyword the keyword to retain
     432              : !> \author fawzi
     433              : ! **************************************************************************************************
     434    836117882 :    SUBROUTINE keyword_retain(keyword)
     435              :       TYPE(keyword_type), POINTER                        :: keyword
     436              : 
     437    836117882 :       CPASSERT(ASSOCIATED(keyword))
     438    836117882 :       CPASSERT(keyword%ref_count > 0)
     439    836117882 :       keyword%ref_count = keyword%ref_count + 1
     440    836117882 :    END SUBROUTINE keyword_retain
     441              : 
     442              : ! **************************************************************************************************
     443              : !> \brief releases the given keyword (see doc/ReferenceCounting.html)
     444              : !> \param keyword the keyword to release
     445              : !> \author fawzi
     446              : ! **************************************************************************************************
     447   2128898556 :    SUBROUTINE keyword_release(keyword)
     448              :       TYPE(keyword_type), POINTER                        :: keyword
     449              : 
     450   2128898556 :       IF (ASSOCIATED(keyword)) THEN
     451   1672235764 :          CPASSERT(keyword%ref_count > 0)
     452   1672235764 :          keyword%ref_count = keyword%ref_count - 1
     453   1672235764 :          IF (keyword%ref_count == 0) THEN
     454    836117882 :             DEALLOCATE (keyword%names)
     455    836117882 :             DEALLOCATE (keyword%description)
     456    836117882 :             CALL val_release(keyword%default_value)
     457    836117882 :             CALL val_release(keyword%lone_keyword_value)
     458    836117882 :             CALL enum_release(keyword%enum)
     459    836117882 :             IF (ASSOCIATED(keyword%unit)) THEN
     460     15172733 :                CALL cp_unit_release(keyword%unit)
     461     15172733 :                DEALLOCATE (keyword%unit)
     462              :             END IF
     463    836117882 :             IF (ASSOCIATED(keyword%citations)) THEN
     464      1256601 :                DEALLOCATE (keyword%citations)
     465              :             END IF
     466    836117882 :             DEALLOCATE (keyword)
     467              :          END IF
     468              :       END IF
     469   2128898556 :       NULLIFY (keyword)
     470   2128898556 :    END SUBROUTINE keyword_release
     471              : 
     472              : ! **************************************************************************************************
     473              : !> \brief ...
     474              : !> \param keyword ...
     475              : !> \param names ...
     476              : !> \param usage ...
     477              : !> \param description ...
     478              : !> \param type_of_var ...
     479              : !> \param n_var ...
     480              : !> \param default_value ...
     481              : !> \param lone_keyword_value ...
     482              : !> \param repeats ...
     483              : !> \param enum ...
     484              : !> \param citations ...
     485              : !> \author fawzi
     486              : ! **************************************************************************************************
     487        55718 :    SUBROUTINE keyword_get(keyword, names, usage, description, type_of_var, n_var, &
     488              :                           default_value, lone_keyword_value, repeats, enum, citations)
     489              :       TYPE(keyword_type), POINTER                        :: keyword
     490              :       CHARACTER(len=default_string_length), &
     491              :          DIMENSION(:), OPTIONAL, POINTER                 :: names
     492              :       CHARACTER(len=*), INTENT(out), OPTIONAL            :: usage, description
     493              :       INTEGER, INTENT(out), OPTIONAL                     :: type_of_var, n_var
     494              :       TYPE(val_type), OPTIONAL, POINTER                  :: default_value, lone_keyword_value
     495              :       LOGICAL, INTENT(out), OPTIONAL                     :: repeats
     496              :       TYPE(enumeration_type), OPTIONAL, POINTER          :: enum
     497              :       INTEGER, DIMENSION(:), OPTIONAL, POINTER           :: citations
     498              : 
     499            0 :       CPASSERT(ASSOCIATED(keyword))
     500        55718 :       CPASSERT(keyword%ref_count > 0)
     501        55718 :       IF (PRESENT(names)) names => keyword%names
     502        55718 :       IF (PRESENT(usage)) usage = keyword%usage
     503        55718 :       IF (PRESENT(description)) description = a2s(keyword%description)
     504        55718 :       IF (PRESENT(type_of_var)) type_of_var = keyword%type_of_var
     505        55718 :       IF (PRESENT(n_var)) n_var = keyword%n_var
     506        55718 :       IF (PRESENT(repeats)) repeats = keyword%repeats
     507        55718 :       IF (PRESENT(default_value)) default_value => keyword%default_value
     508        55718 :       IF (PRESENT(lone_keyword_value)) lone_keyword_value => keyword%lone_keyword_value
     509        55718 :       IF (PRESENT(enum)) enum => keyword%enum
     510        55718 :       IF (PRESENT(citations)) citations => keyword%citations
     511        55718 :    END SUBROUTINE keyword_get
     512              : 
     513              : ! **************************************************************************************************
     514              : !> \brief writes out a description of the keyword
     515              : !> \param keyword the keyword to describe
     516              : !> \param unit_nr the unit to write to
     517              : !> \param level the description level (0 no description, 1 name
     518              : !>        2: +usage, 3: +variants+description+default_value+repeats
     519              : !>        4: +type_of_var)
     520              : !> \author fawzi
     521              : ! **************************************************************************************************
     522           19 :    SUBROUTINE keyword_describe(keyword, unit_nr, level)
     523              :       TYPE(keyword_type), POINTER                        :: keyword
     524              :       INTEGER, INTENT(in)                                :: unit_nr, level
     525              : 
     526              :       CHARACTER(len=cp_unit_desc_length)                 :: c_string
     527              :       INTEGER                                            :: i, l
     528              : 
     529           19 :       CPASSERT(ASSOCIATED(keyword))
     530           19 :       CPASSERT(keyword%ref_count > 0)
     531           19 :       IF (level > 0 .AND. (unit_nr > 0)) THEN
     532           19 :          WRITE (unit_nr, "(a,a,a)") "                           ---", &
     533           38 :             TRIM(keyword%names(1)), "---"
     534           19 :          IF (level > 1) THEN
     535           19 :             WRITE (unit_nr, "(a,a)") "usage         : ", TRIM(keyword%usage)
     536              :          END IF
     537           19 :          IF (level > 2) THEN
     538           19 :             WRITE (unit_nr, "(a)") "description   : "
     539           19 :             CALL print_message(TRIM(a2s(keyword%description)), unit_nr, 0, 0, 0)
     540           19 :             IF (level > 3) THEN
     541            0 :                SELECT CASE (keyword%type_of_var)
     542              :                CASE (logical_t)
     543            0 :                   IF (keyword%n_var == -1) THEN
     544            0 :                      WRITE (unit_nr, "('  A list of logicals is expected')")
     545            0 :                   ELSE IF (keyword%n_var == 1) THEN
     546            0 :                      WRITE (unit_nr, "('  A logical is expected')")
     547              :                   ELSE
     548            0 :                      WRITE (unit_nr, "(i6,'  logicals are expected')") keyword%n_var
     549              :                   END IF
     550            0 :                   WRITE (unit_nr, "('  (T,TRUE,YES,ON) and (F,FALSE,NO,OFF) are synonyms')")
     551              :                CASE (integer_t)
     552            0 :                   IF (keyword%n_var == -1) THEN
     553            0 :                      WRITE (unit_nr, "('  A list of integers is expected')")
     554            0 :                   ELSE IF (keyword%n_var == 1) THEN
     555            0 :                      WRITE (unit_nr, "('  An integer is expected')")
     556              :                   ELSE
     557            0 :                      WRITE (unit_nr, "(i6,' integers are expected')") keyword%n_var
     558              :                   END IF
     559              :                CASE (real_t)
     560            0 :                   IF (keyword%n_var == -1) THEN
     561            0 :                      WRITE (unit_nr, "('  A list of reals is expected')")
     562            0 :                   ELSE IF (keyword%n_var == 1) THEN
     563            0 :                      WRITE (unit_nr, "('  A real is expected')")
     564              :                   ELSE
     565            0 :                      WRITE (unit_nr, "(i6,' reals are expected')") keyword%n_var
     566              :                   END IF
     567            0 :                   IF (ASSOCIATED(keyword%unit)) THEN
     568            0 :                      c_string = cp_unit_desc(keyword%unit, accept_undefined=.TRUE.)
     569              :                      WRITE (unit_nr, "('the default unit of measure is ',a)") &
     570            0 :                         TRIM(c_string)
     571              :                   END IF
     572              :                CASE (char_t)
     573            0 :                   IF (keyword%n_var == -1) THEN
     574            0 :                      WRITE (unit_nr, "('  A list of words is expected')")
     575            0 :                   ELSE IF (keyword%n_var == 1) THEN
     576            0 :                      WRITE (unit_nr, "('  A word is expected')")
     577              :                   ELSE
     578            0 :                      WRITE (unit_nr, "(i6,' words are expected')") keyword%n_var
     579              :                   END IF
     580              :                CASE (lchar_t)
     581            0 :                   WRITE (unit_nr, "('  A string is expected')")
     582              :                CASE (enum_t)
     583            0 :                   IF (keyword%n_var == -1) THEN
     584            0 :                      WRITE (unit_nr, "('  A list of keywords is expected')")
     585            0 :                   ELSE IF (keyword%n_var == 1) THEN
     586            0 :                      WRITE (unit_nr, "('  A keyword is expected')")
     587              :                   ELSE
     588            0 :                      WRITE (unit_nr, "(i6,' keywords are expected')") keyword%n_var
     589              :                   END IF
     590              :                CASE (no_t)
     591            0 :                   WRITE (unit_nr, "('  Non-standard type.')")
     592              :                CASE default
     593            0 :                   CPABORT("Unknown type_of_var for keyword_describe")
     594              :                END SELECT
     595              :             END IF
     596           19 :             IF (keyword%type_of_var == enum_t) THEN
     597            2 :                IF (level > 3) THEN
     598            0 :                   WRITE (unit_nr, "('  valid keywords:')")
     599            0 :                   DO i = 1, SIZE(keyword%enum%c_vals)
     600            0 :                      c_string = keyword%enum%c_vals(i)
     601            0 :                      IF (LEN_TRIM(a2s(keyword%enum%desc(i)%chars)) > 0) THEN
     602              :                         WRITE (unit_nr, "('  - ',a,' : ',a,'.')") &
     603            0 :                            TRIM(c_string), TRIM(a2s(keyword%enum%desc(i)%chars))
     604              :                      ELSE
     605            0 :                         WRITE (unit_nr, "('  - ',a)") TRIM(c_string)
     606              :                      END IF
     607              :                   END DO
     608              :                ELSE
     609            2 :                   WRITE (unit_nr, "('  valid keywords:')", advance='NO')
     610            2 :                   l = 17
     611           18 :                   DO i = 1, SIZE(keyword%enum%c_vals)
     612           16 :                      c_string = keyword%enum%c_vals(i)
     613           16 :                      IF (l + LEN_TRIM(c_string) > 72 .AND. l > 14) THEN
     614            0 :                         WRITE (unit_nr, "(/,'    ')", advance='NO')
     615            0 :                         l = 4
     616              :                      END IF
     617           16 :                      WRITE (unit_nr, "(' ',a)", advance='NO') TRIM(c_string)
     618           18 :                      l = LEN_TRIM(c_string) + 3
     619              :                   END DO
     620            2 :                   WRITE (unit_nr, "()")
     621              :                END IF
     622            2 :                IF (.NOT. keyword%enum%strict) THEN
     623            0 :                   WRITE (unit_nr, "('     other integer values are also accepted.')")
     624              :                END IF
     625              :             END IF
     626           19 :             IF (ASSOCIATED(keyword%default_value) .AND. keyword%type_of_var /= no_t) THEN
     627           17 :                WRITE (unit_nr, "('default_value : ')", advance="NO")
     628           17 :                CALL val_write(keyword%default_value, unit_nr=unit_nr)
     629              :             END IF
     630           19 :             IF (ASSOCIATED(keyword%lone_keyword_value) .AND. keyword%type_of_var /= no_t) THEN
     631            3 :                WRITE (unit_nr, "('lone_keyword  : ')", advance="NO")
     632            3 :                CALL val_write(keyword%lone_keyword_value, unit_nr=unit_nr)
     633              :             END IF
     634           19 :             IF (keyword%repeats) THEN
     635            0 :                WRITE (unit_nr, "(' and it can be repeated more than once')", advance="NO")
     636              :             END IF
     637           19 :             WRITE (unit_nr, "()")
     638           19 :             IF (SIZE(keyword%names) > 1) THEN
     639            1 :                WRITE (unit_nr, "(a)", advance="NO") "variants    : "
     640            3 :                DO i = 2, SIZE(keyword%names)
     641            3 :                   WRITE (unit_nr, "(a,' ')", advance="NO") keyword%names(i)
     642              :                END DO
     643            1 :                WRITE (unit_nr, "()")
     644              :             END IF
     645              :          END IF
     646              :       END IF
     647           19 :    END SUBROUTINE keyword_describe
     648              : 
     649              : ! **************************************************************************************************
     650              : !> \brief Prints a description of a keyword in XML format
     651              : !> \param keyword The keyword to describe
     652              : !> \param level ...
     653              : !> \param unit_number Number of the output unit
     654              : !> \author Matthias Krack
     655              : ! **************************************************************************************************
     656            0 :    SUBROUTINE write_keyword_xml(keyword, level, unit_number)
     657              : 
     658              :       TYPE(keyword_type), POINTER                        :: keyword
     659              :       INTEGER, INTENT(IN)                                :: level, unit_number
     660              : 
     661              :       CHARACTER(LEN=1000)                                :: string
     662              :       CHARACTER(LEN=3)                                   :: removed, repeats
     663              :       CHARACTER(LEN=8)                                   :: short_string
     664              :       INTEGER                                            :: i, l0, l1, l2, l3, l4
     665              : 
     666            0 :       CPASSERT(ASSOCIATED(keyword))
     667            0 :       CPASSERT(keyword%ref_count > 0)
     668              : 
     669              :       ! Indentation for current level, next level, etc.
     670              : 
     671            0 :       l0 = level
     672            0 :       l1 = level + 1
     673            0 :       l2 = level + 2
     674            0 :       l3 = level + 3
     675            0 :       l4 = level + 4
     676              : 
     677            0 :       IF (keyword%repeats) THEN
     678            0 :          repeats = "yes"
     679              :       ELSE
     680            0 :          repeats = "no "
     681              :       END IF
     682              : 
     683            0 :       IF (keyword%removed) THEN
     684            0 :          removed = "yes"
     685              :       ELSE
     686            0 :          removed = "no "
     687              :       END IF
     688              : 
     689              :       ! Write (special) keyword element
     690              : 
     691            0 :       IF (keyword%names(1) == "_SECTION_PARAMETERS_") THEN
     692            0 :          WRITE (UNIT=unit_number, FMT="(A)") &
     693              :             REPEAT(" ", l0)//"<SECTION_PARAMETERS repeats="""//TRIM(repeats)// &
     694            0 :             """ removed="""//TRIM(removed)//""">", &
     695            0 :             REPEAT(" ", l1)//"<NAME type=""default"">SECTION_PARAMETERS</NAME>"
     696            0 :       ELSE IF (keyword%names(1) == "_DEFAULT_KEYWORD_") THEN
     697            0 :          WRITE (UNIT=unit_number, FMT="(A)") &
     698            0 :             REPEAT(" ", l0)//"<DEFAULT_KEYWORD repeats="""//TRIM(repeats)//""">", &
     699            0 :             REPEAT(" ", l1)//"<NAME type=""default"">DEFAULT_KEYWORD</NAME>"
     700              :       ELSE
     701            0 :          WRITE (UNIT=unit_number, FMT="(A)") &
     702              :             REPEAT(" ", l0)//"<KEYWORD repeats="""//TRIM(repeats)// &
     703            0 :             """ removed="""//TRIM(removed)//""">", &
     704              :             REPEAT(" ", l1)//"<NAME type=""default"">"// &
     705            0 :             TRIM(keyword%names(1))//"</NAME>"
     706              :       END IF
     707              : 
     708            0 :       DO i = 2, SIZE(keyword%names)
     709            0 :          WRITE (UNIT=unit_number, FMT="(A)") &
     710              :             REPEAT(" ", l1)//"<NAME type=""alias"">"// &
     711            0 :             TRIM(keyword%names(i))//"</NAME>"
     712              :       END DO
     713              : 
     714            0 :       SELECT CASE (keyword%type_of_var)
     715              :       CASE (logical_t)
     716            0 :          WRITE (UNIT=unit_number, FMT="(A)") &
     717            0 :             REPEAT(" ", l1)//"<DATA_TYPE kind=""logical"">"
     718              :       CASE (integer_t)
     719            0 :          WRITE (UNIT=unit_number, FMT="(A)") &
     720            0 :             REPEAT(" ", l1)//"<DATA_TYPE kind=""integer"">"
     721              :       CASE (real_t)
     722            0 :          WRITE (UNIT=unit_number, FMT="(A)") &
     723            0 :             REPEAT(" ", l1)//"<DATA_TYPE kind=""real"">"
     724              :       CASE (char_t)
     725            0 :          WRITE (UNIT=unit_number, FMT="(A)") &
     726            0 :             REPEAT(" ", l1)//"<DATA_TYPE kind=""word"">"
     727              :       CASE (lchar_t)
     728            0 :          WRITE (UNIT=unit_number, FMT="(A)") &
     729            0 :             REPEAT(" ", l1)//"<DATA_TYPE kind=""string"">"
     730              :       CASE (enum_t)
     731            0 :          WRITE (UNIT=unit_number, FMT="(A)") &
     732            0 :             REPEAT(" ", l1)//"<DATA_TYPE kind=""keyword"">"
     733            0 :          IF (keyword%enum%strict) THEN
     734            0 :             WRITE (UNIT=unit_number, FMT="(A)") &
     735            0 :                REPEAT(" ", l2)//"<ENUMERATION strict=""yes"">"
     736              :          ELSE
     737            0 :             WRITE (UNIT=unit_number, FMT="(A)") &
     738            0 :                REPEAT(" ", l2)//"<ENUMERATION strict=""no"">"
     739              :          END IF
     740            0 :          DO i = 1, SIZE(keyword%enum%c_vals)
     741            0 :             WRITE (UNIT=unit_number, FMT="(A)") &
     742            0 :                REPEAT(" ", l3)//"<ITEM>", &
     743              :                REPEAT(" ", l4)//"<NAME>"// &
     744            0 :                TRIM(ADJUSTL(substitute_special_xml_tokens(keyword%enum%c_vals(i))))//"</NAME>", &
     745              :                REPEAT(" ", l4)//"<DESCRIPTION>"// &
     746              :                TRIM(ADJUSTL(substitute_special_xml_tokens(a2s(keyword%enum%desc(i)%chars)))) &
     747            0 :                //"</DESCRIPTION>", REPEAT(" ", l3)//"</ITEM>"
     748              :          END DO
     749            0 :          WRITE (UNIT=unit_number, FMT="(A)") REPEAT(" ", l2)//"</ENUMERATION>"
     750              :       CASE (no_t)
     751            0 :          WRITE (UNIT=unit_number, FMT="(A)") &
     752            0 :             REPEAT(" ", l1)//"<DATA_TYPE kind=""non-standard type"">"
     753              :       CASE DEFAULT
     754            0 :          CPABORT("Unknown type_of_var for write_keyword_xml")
     755              :       END SELECT
     756              : 
     757            0 :       short_string = ""
     758            0 :       WRITE (UNIT=short_string, FMT="(I8)") keyword%n_var
     759            0 :       WRITE (UNIT=unit_number, FMT="(A)") &
     760            0 :          REPEAT(" ", l2)//"<N_VAR>"//TRIM(ADJUSTL(short_string))//"</N_VAR>", &
     761            0 :          REPEAT(" ", l1)//"</DATA_TYPE>"
     762              : 
     763              :       WRITE (UNIT=unit_number, FMT="(A)") REPEAT(" ", l1)//"<USAGE>"// &
     764              :          TRIM(substitute_special_xml_tokens(keyword%usage)) &
     765            0 :          //"</USAGE>"
     766              : 
     767              :       WRITE (UNIT=unit_number, FMT="(A)") REPEAT(" ", l1)//"<DESCRIPTION>"// &
     768              :          TRIM(substitute_special_xml_tokens(a2s(keyword%description))) &
     769            0 :          //"</DESCRIPTION>"
     770              : 
     771            0 :       IF (ALLOCATED(keyword%deprecation_notice)) THEN
     772              :          WRITE (UNIT=unit_number, FMT="(A)") REPEAT(" ", l1)//"<DEPRECATION_NOTICE>"// &
     773              :             TRIM(substitute_special_xml_tokens(keyword%deprecation_notice)) &
     774            0 :             //"</DEPRECATION_NOTICE>"
     775              :       END IF
     776              : 
     777            0 :       IF (ASSOCIATED(keyword%default_value) .AND. &
     778              :           (keyword%type_of_var /= no_t)) THEN
     779            0 :          IF (ASSOCIATED(keyword%unit)) THEN
     780              :             CALL val_write_internal(val=keyword%default_value, &
     781              :                                     string=string, &
     782            0 :                                     unit=keyword%unit)
     783              :          ELSE
     784              :             CALL val_write_internal(val=keyword%default_value, &
     785            0 :                                     string=string)
     786              :          END IF
     787            0 :          CALL compress(string)
     788              :          WRITE (UNIT=unit_number, FMT="(A)") &
     789              :             REPEAT(" ", l1)//"<DEFAULT_VALUE>"// &
     790            0 :             TRIM(ADJUSTL(substitute_special_xml_tokens(string)))//"</DEFAULT_VALUE>"
     791              :       END IF
     792              : 
     793            0 :       IF (ASSOCIATED(keyword%unit)) THEN
     794            0 :          string = cp_unit_desc(keyword%unit, accept_undefined=.TRUE.)
     795              :          WRITE (UNIT=unit_number, FMT="(A)") &
     796              :             REPEAT(" ", l1)//"<DEFAULT_UNIT>"// &
     797            0 :             TRIM(ADJUSTL(string))//"</DEFAULT_UNIT>"
     798              :       END IF
     799              : 
     800            0 :       IF (ASSOCIATED(keyword%lone_keyword_value) .AND. &
     801              :           (keyword%type_of_var /= no_t)) THEN
     802              :          CALL val_write_internal(val=keyword%lone_keyword_value, &
     803            0 :                                  string=string)
     804              :          WRITE (UNIT=unit_number, FMT="(A)") &
     805              :             REPEAT(" ", l1)//"<LONE_KEYWORD_VALUE>"// &
     806            0 :             TRIM(ADJUSTL(substitute_special_xml_tokens(string)))//"</LONE_KEYWORD_VALUE>"
     807              :       END IF
     808              : 
     809            0 :       IF (ASSOCIATED(keyword%citations)) THEN
     810            0 :          DO i = 1, SIZE(keyword%citations, 1)
     811            0 :             short_string = ""
     812            0 :             WRITE (UNIT=short_string, FMT="(I8)") keyword%citations(i)
     813              :             WRITE (UNIT=unit_number, FMT="(A)") &
     814            0 :                REPEAT(" ", l1)//"<REFERENCE>", &
     815            0 :                REPEAT(" ", l2)//"<NAME>"//TRIM(get_citation_key(keyword%citations(i)))//"</NAME>", &
     816            0 :                REPEAT(" ", l2)//"<NUMBER>"//TRIM(ADJUSTL(short_string))//"</NUMBER>", &
     817            0 :                REPEAT(" ", l1)//"</REFERENCE>"
     818              :          END DO
     819              :       END IF
     820              : 
     821              :       WRITE (UNIT=unit_number, FMT="(A)") &
     822            0 :          REPEAT(" ", l1)//"<LOCATION>"//TRIM(keyword%location)//"</LOCATION>"
     823              : 
     824              :       ! Close (special) keyword section
     825              : 
     826            0 :       IF (keyword%names(1) == "_SECTION_PARAMETERS_") THEN
     827            0 :          WRITE (UNIT=unit_number, FMT="(A)") &
     828            0 :             REPEAT(" ", l0)//"</SECTION_PARAMETERS>"
     829            0 :       ELSE IF (keyword%names(1) == "_DEFAULT_KEYWORD_") THEN
     830            0 :          WRITE (UNIT=unit_number, FMT="(A)") &
     831            0 :             REPEAT(" ", l0)//"</DEFAULT_KEYWORD>"
     832              :       ELSE
     833            0 :          WRITE (UNIT=unit_number, FMT="(A)") &
     834            0 :             REPEAT(" ", l0)//"</KEYWORD>"
     835              :       END IF
     836              : 
     837            0 :    END SUBROUTINE write_keyword_xml
     838              : 
     839              : ! **************************************************************************************************
     840              : !> \brief ...
     841              : !> \param keyword ...
     842              : !> \param unknown_string ...
     843              : !> \param location_string ...
     844              : !> \param matching_rank ...
     845              : !> \param matching_string ...
     846              : !> \param bonus ...
     847              : ! **************************************************************************************************
     848            0 :    SUBROUTINE keyword_typo_match(keyword, unknown_string, location_string, matching_rank, matching_string, bonus)
     849              : 
     850              :       TYPE(keyword_type), POINTER                        :: keyword
     851              :       CHARACTER(LEN=*)                                   :: unknown_string, location_string
     852              :       INTEGER, DIMENSION(:), INTENT(INOUT)               :: matching_rank
     853              :       CHARACTER(LEN=*), DIMENSION(:), INTENT(INOUT)      :: matching_string
     854              :       INTEGER, INTENT(IN)                                :: bonus
     855              : 
     856            0 :       CHARACTER(LEN=LEN(matching_string(1)))             :: line
     857              :       INTEGER                                            :: i, imatch, imax, irank, j, k
     858              : 
     859            0 :       CPASSERT(ASSOCIATED(keyword))
     860            0 :       CPASSERT(keyword%ref_count > 0)
     861              : 
     862            0 :       DO i = 1, SIZE(keyword%names)
     863            0 :          imatch = typo_match(TRIM(keyword%names(i)), TRIM(unknown_string))
     864            0 :          IF (imatch > 0) THEN
     865            0 :             imatch = imatch + bonus
     866            0 :             WRITE (line, '(T2,A)') " keyword "//TRIM(keyword%names(i))//" in section "//TRIM(location_string)
     867            0 :             imax = SIZE(matching_rank, 1)
     868            0 :             irank = imax + 1
     869            0 :             DO k = imax, 1, -1
     870            0 :                IF (imatch > matching_rank(k)) irank = k
     871              :             END DO
     872            0 :             IF (irank <= imax) THEN
     873            0 :                matching_rank(irank + 1:imax) = matching_rank(irank:imax - 1)
     874            0 :                matching_string(irank + 1:imax) = matching_string(irank:imax - 1)
     875            0 :                matching_rank(irank) = imatch
     876            0 :                matching_string(irank) = line
     877              :             END IF
     878              :          END IF
     879              : 
     880            0 :          IF (keyword%type_of_var == enum_t) THEN
     881            0 :             DO j = 1, SIZE(keyword%enum%c_vals)
     882            0 :                imatch = typo_match(TRIM(keyword%enum%c_vals(j)), TRIM(unknown_string))
     883            0 :                IF (imatch > 0) THEN
     884            0 :                   imatch = imatch + bonus
     885              :                   WRITE (line, '(T2,A)') " enum "//TRIM(keyword%enum%c_vals(j))// &
     886              :                      " in section "//TRIM(location_string)// &
     887            0 :                      " for keyword "//TRIM(keyword%names(i))
     888            0 :                   imax = SIZE(matching_rank, 1)
     889            0 :                   irank = imax + 1
     890            0 :                   DO k = imax, 1, -1
     891            0 :                      IF (imatch > matching_rank(k)) irank = k
     892              :                   END DO
     893            0 :                   IF (irank <= imax) THEN
     894            0 :                      matching_rank(irank + 1:imax) = matching_rank(irank:imax - 1)
     895            0 :                      matching_string(irank + 1:imax) = matching_string(irank:imax - 1)
     896            0 :                      matching_rank(irank) = imatch
     897            0 :                      matching_string(irank) = line
     898              :                   END IF
     899              :                END IF
     900              :             END DO
     901              :          END IF
     902              :       END DO
     903              : 
     904            0 :    END SUBROUTINE keyword_typo_match
     905              : 
     906            0 : END MODULE input_keyword_types
        

Generated by: LCOV version 2.0-1