LCOV - code coverage report
Current view: top level - src/input - cp_parser_types.F (source / functions) Hit Total Coverage
Test: CP2K Regtests (git:f515968) Lines: 90 100 90.0 %
Date: 2022-07-03 19:52:34 Functions: 3 5 60.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 Utility routines to read data from files.
      10             : !>      Kept as close as possible to the old parser because
      11             : !>        1. string handling is a weak point of fortran compilers, and it is
      12             : !>           easy to write correct things that do not work
      13             : !>        2. conversion of old code
      14             : !> \par History
      15             : !>      22.11.1999 first version of the old parser (called qs_parser)
      16             : !>                 Matthias Krack
      17             : !>      06.2004 removed module variables, cp_parser_type, new module [fawzi]
      18             : !>      08.2008 Added buffering [tlaino]
      19             : !> \author fawzi
      20             : ! **************************************************************************************************
      21             : MODULE cp_parser_types
      22             :    USE cp_files,                        ONLY: close_file,&
      23             :                                               open_file
      24             :    USE cp_para_env,                     ONLY: cp_para_env_create,&
      25             :                                               cp_para_env_release,&
      26             :                                               cp_para_env_retain
      27             :    USE cp_para_types,                   ONLY: cp_para_env_type
      28             :    USE cp_parser_buffer_types,          ONLY: buffer_type,&
      29             :                                               create_buffer_type,&
      30             :                                               release_buffer_type
      31             :    USE cp_parser_ilist_types,           ONLY: create_ilist_type,&
      32             :                                               ilist_type,&
      33             :                                               release_ilist_type
      34             :    USE cp_parser_inpp_types,            ONLY: create_inpp_type,&
      35             :                                               inpp_type,&
      36             :                                               release_inpp_type
      37             :    USE cp_parser_status_types,          ONLY: create_status_type,&
      38             :                                               release_status_type,&
      39             :                                               status_type
      40             :    USE kinds,                           ONLY: default_path_length,&
      41             :                                               default_string_length,&
      42             :                                               max_line_length
      43             :    USE message_passing,                 ONLY: mp_comm_self
      44             :    USE string_utilities,                ONLY: compress
      45             : #include "../base/base_uses.f90"
      46             : 
      47             :    IMPLICIT NONE
      48             : 
      49             :    PRIVATE
      50             : 
      51             :    PUBLIC :: cp_parser_type, parser_release, parser_create, &
      52             :              parser_reset, empty_initial_variables
      53             : 
      54             :    ! this is a zero sized array by choice, and convenience
      55             :    CHARACTER(LEN=default_path_length), DIMENSION(2, 1:0) :: empty_initial_variables
      56             : 
      57             :    ! Private parameters
      58             :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'cp_parser_types'
      59             :    INTEGER, SAVE, PRIVATE               :: last_parser_id = 0
      60             : 
      61             :    ! Global variables
      62             :    CHARACTER(LEN=1), PARAMETER, PUBLIC   :: default_continuation_character = CHAR(92) ! backslash
      63             :    CHARACTER(LEN=4), PARAMETER, PUBLIC   :: default_separators = ",:;="
      64             :    CHARACTER(LEN=3), PARAMETER, PUBLIC   :: default_end_section_label = "END"
      65             :    CHARACTER(LEN=1), PARAMETER, PUBLIC   :: default_comment_character(2) = (/"#", "!"/), &
      66             :                                             default_section_character = "&", &
      67             :                                             default_quote_character = '"'
      68             :    INTEGER, PARAMETER, PUBLIC            :: max_unit_number = 999
      69             : 
      70             : ! **************************************************************************************************
      71             : !> \brief represent a parser
      72             : !> \param icol Number of the current column in the current input line,
      73             : !>  -1 if at the end of the file
      74             : !>  icol1            : First column of the current input string
      75             : !>  icol2            : Last column of the current input string
      76             : !> \param input_line_number Number of the current input line read from the input file
      77             : !> \param input_unit Logical unit number of the input file
      78             : !> \author fawzi
      79             : ! **************************************************************************************************
      80             :    TYPE cp_parser_type
      81             :       INTEGER                                        :: id_nr, ref_count
      82             :       CHARACTER(LEN=default_string_length)           :: end_section, start_section
      83             :       CHARACTER(LEN=10)                              :: separators
      84             :       CHARACTER(LEN=1)                               :: comment_character(2), &
      85             :                                                         continuation_character, &
      86             :                                                         quote_character, &
      87             :                                                         section_character
      88             :       CHARACTER(LEN=default_path_length)             :: input_file_name
      89             :       CHARACTER(LEN=max_line_length)                 :: input_line
      90             :       INTEGER                                        :: icol, icol1, icol2
      91             :       INTEGER                                        :: input_unit, input_line_number
      92             :       LOGICAL                                        :: first_separator, &
      93             :                                                         apply_preprocessing, &
      94             :                                                         parse_white_lines
      95             :       CHARACTER(len=default_path_length), DIMENSION(:, :), POINTER :: initial_variables
      96             :       TYPE(buffer_type), POINTER                     :: buffer
      97             :       TYPE(status_type), POINTER                     :: status
      98             :       TYPE(cp_para_env_type), POINTER                :: para_env
      99             :       TYPE(inpp_type), POINTER                       :: inpp
     100             :       TYPE(ilist_type), POINTER                      :: ilist
     101             :    END TYPE cp_parser_type
     102             : 
     103             : CONTAINS
     104             : 
     105             : ! **************************************************************************************************
     106             : !> \brief retains the given parser
     107             : !> \param parser the parser to retain
     108             : !> \author fawzi
     109             : ! **************************************************************************************************
     110           0 :    SUBROUTINE parser_retain(parser)
     111             :       TYPE(cp_parser_type), POINTER                      :: parser
     112             : 
     113           0 :       CPASSERT(ASSOCIATED(parser))
     114           0 :       CPASSERT(parser%ref_count > 0)
     115           0 :       parser%ref_count = parser%ref_count + 1
     116           0 :    END SUBROUTINE parser_retain
     117             : 
     118             : ! **************************************************************************************************
     119             : !> \brief   releases the parser
     120             : !> \param parser ...
     121             : !> \date    14.02.2001
     122             : !> \author  MK
     123             : !> \version 1.0
     124             : ! **************************************************************************************************
     125       46003 :    SUBROUTINE parser_release(parser)
     126             :       TYPE(cp_parser_type), POINTER                      :: parser
     127             : 
     128       46003 :       IF (ASSOCIATED(parser)) THEN
     129       45977 :          CPASSERT(parser%ref_count > 0)
     130       45977 :          parser%ref_count = parser%ref_count - 1
     131       45977 :          IF (parser%ref_count == 0) THEN
     132       45977 :             IF (parser%input_unit >= 0) THEN
     133       24713 :                CALL close_file(unit_number=parser%input_unit)
     134             :             END IF
     135       45977 :             CALL cp_para_env_release(parser%para_env)
     136       45977 :             CALL release_inpp_type(parser%inpp)
     137       45977 :             CALL release_ilist_type(parser%ilist)
     138       45977 :             CALL release_buffer_type(parser%buffer)
     139       45977 :             CALL release_status_type(parser%status)
     140       45977 :             IF (ASSOCIATED(parser%initial_variables)) THEN
     141          86 :                DEALLOCATE (parser%initial_variables)
     142             :             END IF
     143       45977 :             DEALLOCATE (parser)
     144             :          END IF
     145             :       END IF
     146       46003 :    END SUBROUTINE parser_release
     147             : 
     148             : ! **************************************************************************************************
     149             : !> \brief   Start a parser run. Initial variables allow to @SET stuff before opening the file
     150             : !> \param parser ...
     151             : !> \param file_name ...
     152             : !> \param unit_nr ...
     153             : !> \param para_env ...
     154             : !> \param end_section_label ...
     155             : !> \param separator_chars ...
     156             : !> \param comment_char ...
     157             : !> \param continuation_char ...
     158             : !> \param quote_char ...
     159             : !> \param section_char ...
     160             : !> \param parse_white_lines ...
     161             : !> \param initial_variables ...
     162             : !> \param apply_preprocessing ...
     163             : !> \date    14.02.2001
     164             : !> \author  MK
     165             : !> \version 1.0
     166             : ! **************************************************************************************************
     167       45977 :    SUBROUTINE parser_create(parser, file_name, unit_nr, para_env, end_section_label, &
     168             :                             separator_chars, comment_char, continuation_char, quote_char, &
     169        8194 :                             section_char, parse_white_lines, initial_variables, apply_preprocessing)
     170             :       TYPE(cp_parser_type), POINTER                      :: parser
     171             :       CHARACTER(LEN=*), INTENT(IN), OPTIONAL             :: file_name
     172             :       INTEGER, INTENT(in), OPTIONAL                      :: unit_nr
     173             :       TYPE(cp_para_env_type), OPTIONAL, POINTER          :: para_env
     174             :       CHARACTER(LEN=*), INTENT(IN), OPTIONAL             :: end_section_label, separator_chars
     175             :       CHARACTER(LEN=1), INTENT(IN), OPTIONAL             :: comment_char, continuation_char, &
     176             :                                                             quote_char, section_char
     177             :       LOGICAL, INTENT(IN), OPTIONAL                      :: parse_white_lines
     178             :       CHARACTER(len=*), DIMENSION(:, :), OPTIONAL        :: initial_variables
     179             :       LOGICAL, INTENT(IN), OPTIONAL                      :: apply_preprocessing
     180             : 
     181       45977 :       CPASSERT(.NOT. ASSOCIATED(parser))
     182       45977 :       ALLOCATE (parser)
     183       45977 :       last_parser_id = last_parser_id + 1
     184       45977 :       parser%id_nr = last_parser_id
     185       45977 :       parser%ref_count = 1
     186             : 
     187       45977 :       parser%input_unit = -1
     188       45977 :       parser%input_file_name = ""
     189       45977 :       NULLIFY (parser%initial_variables)
     190             : 
     191             :       ! Load the default values and overwrite them, if requested
     192       45977 :       parser%separators = default_separators
     193       45977 :       IF (PRESENT(separator_chars)) parser%separators = separator_chars
     194      137931 :       parser%comment_character = default_comment_character
     195       45977 :       IF (PRESENT(comment_char)) parser%comment_character = comment_char
     196       45977 :       parser%continuation_character = default_continuation_character
     197       45977 :       IF (PRESENT(continuation_char)) parser%continuation_character = continuation_char
     198       45977 :       parser%quote_character = default_quote_character
     199       45977 :       IF (PRESENT(quote_char)) parser%quote_character = quote_char
     200       45977 :       parser%section_character = default_section_character
     201       45977 :       IF (PRESENT(section_char)) parser%section_character = section_char
     202       45977 :       parser%end_section = parser%section_character//default_end_section_label
     203       45977 :       IF (PRESENT(end_section_label)) THEN
     204           0 :          parser%end_section = parser%section_character//TRIM(end_section_label)
     205             :       END IF
     206       45977 :       parser%parse_white_lines = .FALSE.
     207       45977 :       IF (PRESENT(parse_white_lines)) THEN
     208        1097 :          parser%parse_white_lines = parse_white_lines
     209             :       END IF
     210       45977 :       parser%apply_preprocessing = .TRUE.
     211       45977 :       IF (PRESENT(apply_preprocessing)) THEN
     212          14 :          parser%apply_preprocessing = apply_preprocessing
     213             :       END IF
     214             : 
     215       45977 :       CALL compress(parser%end_section) ! needed?
     216             : 
     217             :       ! para_env
     218       45977 :       IF (PRESENT(para_env)) THEN
     219       45741 :          parser%para_env => para_env
     220       45741 :          CALL cp_para_env_retain(para_env)
     221             :       ELSE
     222         236 :          NULLIFY (parser%para_env)
     223             :          CALL cp_para_env_create(parser%para_env, group=mp_comm_self, source=0, &
     224         236 :                                  mepos=0, num_pe=1, owns_group=.FALSE.)
     225             :       END IF
     226             : 
     227             :       !   *** Get the logical output unit number for error messages ***
     228       45977 :       IF (parser%para_env%ionode) THEN
     229       24713 :          IF (PRESENT(unit_nr)) THEN
     230           0 :             parser%input_unit = unit_nr
     231           0 :             IF (PRESENT(file_name)) parser%input_file_name = file_name
     232             :          ELSE
     233       24713 :             IF (.NOT. PRESENT(file_name)) &
     234           0 :                CPABORT("at least one of filename and unit_nr must be present")
     235             :             CALL open_file(file_name=TRIM(file_name), &
     236       24713 :                            unit_number=parser%input_unit)
     237       24713 :             parser%input_file_name = file_name
     238             :          END IF
     239             :       END IF
     240             : 
     241       45977 :       IF (PRESENT(initial_variables)) THEN
     242        8194 :          IF (SIZE(initial_variables, 2) > 0) THEN
     243         258 :             ALLOCATE (parser%initial_variables(2, SIZE(initial_variables, 2)))
     244         602 :             parser%initial_variables = initial_variables
     245             :          END IF
     246             :       END IF
     247             : 
     248       45977 :       parser%input_line_number = 0
     249       45977 :       parser%icol = 0
     250       45977 :       parser%icol1 = 0
     251       45977 :       parser%icol2 = 0
     252       45977 :       parser%first_separator = .TRUE.
     253       45977 :       NULLIFY (parser%buffer)
     254       45977 :       NULLIFY (parser%status)
     255       45977 :       NULLIFY (parser%inpp)
     256       45977 :       NULLIFY (parser%ilist)
     257       45977 :       CALL create_inpp_type(parser%inpp, parser%initial_variables)
     258       45977 :       CALL create_ilist_type(parser%ilist)
     259       45977 :       CALL create_buffer_type(parser%buffer)
     260       45977 :       CALL create_status_type(parser%status)
     261       45977 :    END SUBROUTINE parser_create
     262             : 
     263             : ! **************************************************************************************************
     264             : !> \brief   Resets the parser: rewinding the unit and re-initializing all
     265             : !>          parser structures
     266             : !> \param parser ...
     267             : !> \date    12.2008
     268             : !> \author  Teodoro Laino [tlaino]
     269             : ! **************************************************************************************************
     270         510 :    SUBROUTINE parser_reset(parser)
     271             :       TYPE(cp_parser_type), POINTER                      :: parser
     272             : 
     273         510 :       CPASSERT(ASSOCIATED(parser))
     274             :       ! Rewind units
     275         510 :       IF (parser%input_unit > 0) REWIND (parser%input_unit)
     276             :       ! Restore initial settings
     277         510 :       parser%input_line_number = 0
     278         510 :       parser%icol = 0
     279         510 :       parser%icol1 = 0
     280         510 :       parser%icol2 = 0
     281         510 :       parser%first_separator = .TRUE.
     282             :       ! Release substructures
     283         510 :       CALL release_inpp_type(parser%inpp)
     284         510 :       CALL release_ilist_type(parser%ilist)
     285         510 :       CALL release_buffer_type(parser%buffer)
     286         510 :       CALL release_status_type(parser%status)
     287             :       ! Reallocate substructures
     288         510 :       CALL create_inpp_type(parser%inpp, parser%initial_variables)
     289         510 :       CALL create_ilist_type(parser%ilist)
     290         510 :       CALL create_buffer_type(parser%buffer)
     291         510 :       CALL create_status_type(parser%status)
     292         510 :    END SUBROUTINE parser_reset
     293             : 
     294           0 : END MODULE cp_parser_types

Generated by: LCOV version 1.15