(git:b195825)
input_section_types.F
Go to the documentation of this file.
1 !--------------------------------------------------------------------------------------------------!
2 ! CP2K: A general program to perform molecular dynamics simulations !
3 ! Copyright 2000-2024 CP2K developers group <https://cp2k.org> !
4 ! !
5 ! SPDX-License-Identifier: GPL-2.0-or-later !
6 !--------------------------------------------------------------------------------------------------!
7 
8 ! **************************************************************************************************
9 !> \brief objects that represent the structure of input sections and the data
10 !> contained in an input section
11 !> \par History
12 !> 06.2004 created [fawzi]
13 !> \author fawzi
14 ! **************************************************************************************************
16 
17  USE cp_linked_list_input, ONLY: &
21  USE cp_log_handling, ONLY: cp_to_string
24  keyword_p_type,&
27  keyword_type,&
30  USE input_val_types, ONLY: lchar_t,&
31  no_t,&
32  val_create,&
34  val_get,&
35  val_release,&
36  val_type,&
37  val_write
38  USE kinds, ONLY: default_path_length,&
40  dp
41  USE print_messages, ONLY: print_message
43  USE string_utilities, ONLY: a2s,&
45  typo_match,&
46  uppercase
47 #include "../base/base_uses.f90"
48 
49  IMPLICIT NONE
50  PRIVATE
51 
52  LOGICAL, PRIVATE, PARAMETER :: debug_this_module = .true.
53  CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'input_section_types'
54 
55  PUBLIC :: section_type
60 
61  PUBLIC :: section_vals_type
67  PUBLIC :: write_section_xml
68 
69  PUBLIC :: section_get_ival, &
74 
75 ! **************************************************************************************************
76 !> \brief represent a pointer to a section (to make arrays of pointers)
77 !> \param section the pointer to the section
78 !> \author fawzi
79 ! **************************************************************************************************
80  TYPE section_p_type
81  TYPE(section_type), POINTER :: section => null()
82  END TYPE section_p_type
83 
84 ! **************************************************************************************************
85 !> \brief represent a section of the input file
86 !> \note
87 !> - frozen: if the section has been frozen (and no keyword/subsections
88 !> can be added)
89 !> - repeats: if the section can be repeated more than once in the same
90 !> context
91 !> - ref_count: reference count (see doc/ReferenceCounting.html)
92 !> - n_keywords: the number of keywords in this section
93 !> - name: name of the section
94 !> - location where in the source code (file and line) the section is created
95 !> - description: description of the section
96 !> - citations: references to literature associated to this section
97 !> - keywords: array with the keywords of this section (might be
98 !> oversized)
99 !> - subsections: sections contained in this section
100 !> \author fawzi
101 ! **************************************************************************************************
102  TYPE section_type
103  LOGICAL :: frozen = .false., repeats = .false.
104  INTEGER :: ref_count = 0, n_keywords = 0, n_subsections = 0
105  CHARACTER(len=default_string_length) :: name = ""
106  CHARACTER(len=default_string_length) :: location = ""
107  CHARACTER, DIMENSION(:), POINTER :: description => null()
108  INTEGER, POINTER, DIMENSION(:) :: citations => null()
109  TYPE(keyword_p_type), DIMENSION(:), POINTER :: keywords => null()
110  TYPE(section_p_type), POINTER, DIMENSION(:) :: subsections => null()
111  END TYPE section_type
112 
113 ! **************************************************************************************************
114 !> \brief repesents a pointer to a parsed section (to make arrays of pointers)
115 !> \param section_vals the pointer to the parsed section
116 !> \author fawzi
117 ! **************************************************************************************************
118  TYPE section_vals_p_type
119  TYPE(section_vals_type), POINTER :: section_vals => null()
120  END TYPE section_vals_p_type
121 
122 ! **************************************************************************************************
123 !> \brief stores the values of a section
124 !> \author fawzi
125 ! **************************************************************************************************
126  TYPE section_vals_type
127  INTEGER :: ref_count = 0
128  INTEGER, POINTER, DIMENSION(:) :: ibackup => null()
129  TYPE(section_type), POINTER :: section => null()
130  TYPE(cp_sll_val_p_type), DIMENSION(:, :), POINTER :: values => null()
131  TYPE(section_vals_p_type), DIMENSION(:, :), POINTER :: subs_vals => null()
132  END TYPE section_vals_type
133 
134  TYPE(section_type), POINTER, SAVE :: typo_match_section => null()
135  INTEGER, PARAMETER :: n_typo_matches = 5
136  INTEGER, DIMENSION(n_typo_matches) :: typo_matching_rank = 0
137  CHARACTER(LEN=default_string_length*5), DIMENSION(n_typo_matches):: typo_matching_line = ""
138 
139 CONTAINS
140 
141 ! **************************************************************************************************
142 !> \brief creates a list of keywords
143 !> \param section the list to be created
144 !> \param location from where in the source code section_create() is called
145 !> \param name ...
146 !> \param description ...
147 !> \param n_keywords hint about the number of keywords, defaults to 10
148 !> \param n_subsections a hint about how many sections will be added to this
149 !> structure, defaults to 0
150 !> \param repeats if this section can repeat (defaults to false)
151 !> \param citations ...
152 !> \author fawzi
153 ! **************************************************************************************************
154  SUBROUTINE section_create(section, location, name, description, n_keywords, &
155  n_subsections, repeats, citations)
156 
157  TYPE(section_type), POINTER :: section
158  CHARACTER(len=*), INTENT(in) :: location, name, description
159  INTEGER, INTENT(in), OPTIONAL :: n_keywords, n_subsections
160  LOGICAL, INTENT(in), OPTIONAL :: repeats
161  INTEGER, DIMENSION(:), INTENT(IN), OPTIONAL :: citations
162 
163  INTEGER :: i, my_n_keywords, my_n_subsections, n
164 
165  cpassert(.NOT. ASSOCIATED(section))
166  my_n_keywords = 10
167  IF (PRESENT(n_keywords)) my_n_keywords = n_keywords
168  my_n_subsections = 0
169  IF (PRESENT(n_subsections)) my_n_subsections = n_subsections
170 
171  ALLOCATE (section)
172  section%ref_count = 1
173 
174  section%n_keywords = 0
175  section%n_subsections = 0
176  section%location = location
177 
178  cpassert(len_trim(name) > 0)
179  section%name = name
180  CALL uppercase(section%name)
181 
182  n = len_trim(description)
183  ALLOCATE (section%description(n))
184  DO i = 1, n
185  section%description(i) = description(i:i)
186  END DO
187 
188  section%frozen = .false.
189  section%repeats = .false.
190  IF (PRESENT(repeats)) section%repeats = repeats
191 
192  NULLIFY (section%citations)
193  IF (PRESENT(citations)) THEN
194  ALLOCATE (section%citations(SIZE(citations)))
195  section%citations = citations
196  END IF
197 
198  ALLOCATE (section%keywords(-1:my_n_keywords))
199  DO i = -1, my_n_keywords
200  NULLIFY (section%keywords(i)%keyword)
201  END DO
202 
203  ALLOCATE (section%subsections(my_n_subsections))
204  DO i = 1, my_n_subsections
205  NULLIFY (section%subsections(i)%section)
206  END DO
207 
208  END SUBROUTINE section_create
209 
210 ! **************************************************************************************************
211 !> \brief retains the given keyword list (see doc/ReferenceCounting.html)
212 !> \param section the list to retain
213 !> \author fawzi
214 ! **************************************************************************************************
215  SUBROUTINE section_retain(section)
216 
217  TYPE(section_type), POINTER :: section
218 
219  cpassert(ASSOCIATED(section))
220  cpassert(section%ref_count > 0)
221  section%ref_count = section%ref_count + 1
222 
223  END SUBROUTINE section_retain
224 
225 ! **************************************************************************************************
226 !> \brief releases the given keyword list (see doc/ReferenceCounting.html)
227 !> \param section the list to release
228 !> \author fawzi
229 ! **************************************************************************************************
230  RECURSIVE SUBROUTINE section_release(section)
231 
232  TYPE(section_type), POINTER :: section
233 
234  INTEGER :: i
235 
236  IF (ASSOCIATED(section)) THEN
237  cpassert(section%ref_count > 0)
238  section%ref_count = section%ref_count - 1
239  IF (section%ref_count == 0) THEN
240  IF (ASSOCIATED(section%citations)) THEN
241  DEALLOCATE (section%citations)
242  END IF
243  IF (ASSOCIATED(section%keywords)) THEN
244  DO i = -1, ubound(section%keywords, 1)
245  CALL keyword_release(section%keywords(i)%keyword)
246  END DO
247  DEALLOCATE (section%keywords)
248  END IF
249  section%n_keywords = 0
250  IF (ASSOCIATED(section%subsections)) THEN
251  DO i = 1, SIZE(section%subsections)
252  CALL section_release(section%subsections(i)%section)
253  END DO
254  DEALLOCATE (section%subsections)
255  END IF
256  DEALLOCATE (section%description)
257  DEALLOCATE (section)
258  END IF
259  NULLIFY (section)
260  END IF
261 
262  END SUBROUTINE section_release
263 
264 ! **************************************************************************************************
265 !> \brief collects additional information on the section for IO + documentation
266 !> \param section ...
267 !> \return ...
268 !> \author fawzi
269 ! **************************************************************************************************
270  FUNCTION get_section_info(section) RESULT(message)
271 
272  TYPE(section_type), INTENT(IN) :: section
273  CHARACTER(LEN=default_path_length) :: message
274 
275  INTEGER :: length
276 
277  message = " "
278  length = len_trim(a2s(section%description))
279  IF (length > 0) THEN
280  IF (section%description(length) /= ".") THEN
281  message = "."
282  END IF
283  END IF
284  IF (section%repeats) THEN
285  message = trim(message)//" This section can be repeated."
286  ELSE
287  message = trim(message)//" This section can not be repeated."
288  END IF
289 
290  END FUNCTION get_section_info
291 
292 ! **************************************************************************************************
293 !> \brief prints a description of the given section
294 !> \param section the section to describe
295 !> \param unit_nr the unit to write to
296 !> \param level the level of output: 0: just section name, 1:keywords,
297 !> then see keyword_describe :-)
298 !> \param hide_root if the name of the first section should be hidden
299 !> (defaults to false).
300 !> \param recurse ...
301 !> \author fawzi
302 ! **************************************************************************************************
303  RECURSIVE SUBROUTINE section_describe(section, unit_nr, level, hide_root, recurse)
304 
305  TYPE(section_type), INTENT(IN), POINTER :: section
306  INTEGER, INTENT(in) :: unit_nr, level
307  LOGICAL, INTENT(in), OPTIONAL :: hide_root
308  INTEGER, INTENT(in), OPTIONAL :: recurse
309 
310  CHARACTER(LEN=default_path_length) :: message
311  INTEGER :: ikeyword, isub, my_recurse
312  LOGICAL :: my_hide_root
313 
314  IF (unit_nr > 0) THEN
315  my_hide_root = .false.
316  IF (PRESENT(hide_root)) my_hide_root = hide_root
317  my_recurse = 0
318  IF (PRESENT(recurse)) my_recurse = recurse
319  IF (ASSOCIATED(section)) THEN
320  cpassert(section%ref_count > 0)
321 
322  IF (.NOT. my_hide_root) &
323  WRITE (unit=unit_nr, fmt="('*** section &',A,' ***')") trim(adjustl(section%name))
324  IF (level > 1) THEN
325  message = get_section_info(section)
326  CALL print_message(trim(a2s(section%description))//trim(message), unit_nr, 0, 0, 0)
327  END IF
328  IF (level > 0) THEN
329  IF (ASSOCIATED(section%keywords(-1)%keyword)) THEN
330  CALL keyword_describe(section%keywords(-1)%keyword, unit_nr, &
331  level)
332  END IF
333  IF (ASSOCIATED(section%keywords(0)%keyword)) THEN
334  CALL keyword_describe(section%keywords(0)%keyword, unit_nr, &
335  level)
336  END IF
337  DO ikeyword = 1, section%n_keywords
338  CALL keyword_describe(section%keywords(ikeyword)%keyword, unit_nr, &
339  level)
340  END DO
341  END IF
342  IF (section%n_subsections > 0 .AND. my_recurse >= 0) THEN
343  IF (.NOT. my_hide_root) &
344  WRITE (unit=unit_nr, fmt="('** subsections **')")
345  DO isub = 1, section%n_subsections
346  IF (my_recurse > 0) THEN
347  CALL section_describe(section%subsections(isub)%section, unit_nr, &
348  level, recurse=my_recurse - 1)
349  ELSE
350  WRITE (unit=unit_nr, fmt="(1X,A)") section%subsections(isub)%section%name
351  END IF
352  END DO
353  END IF
354  IF (.NOT. my_hide_root) &
355  WRITE (unit=unit_nr, fmt="('*** &end section ',A,' ***')") trim(adjustl(section%name))
356  ELSE
357  WRITE (unit_nr, "(a)") '<section *null*>'
358  END IF
359  END IF
360 
361  END SUBROUTINE section_describe
362 
363 ! **************************************************************************************************
364 !> \brief returns the index of requested subsection (-1 if not found)
365 !> \param section the root section
366 !> \param subsection_name the name of the subsection you want to get
367 !> \return ...
368 !> \author fawzi
369 !> \note
370 !> private utility function
371 ! **************************************************************************************************
372  FUNCTION section_get_subsection_index(section, subsection_name) RESULT(res)
373 
374  TYPE(section_type), INTENT(IN) :: section
375  CHARACTER(len=*), INTENT(IN) :: subsection_name
376  INTEGER :: res
377 
378  CHARACTER(len=default_string_length) :: upc_name
379  INTEGER :: isub
380 
381  cpassert(section%ref_count > 0)
382  res = -1
383  upc_name = subsection_name
384  CALL uppercase(upc_name)
385  DO isub = 1, section%n_subsections
386  cpassert(ASSOCIATED(section%subsections(isub)%section))
387  IF (section%subsections(isub)%section%name == upc_name) THEN
388  res = isub
389  EXIT
390  END IF
391  END DO
392 
393  END FUNCTION section_get_subsection_index
394 
395 ! **************************************************************************************************
396 !> \brief returns the requested subsection
397 !> \param section the root section
398 !> \param subsection_name the name of the subsection you want to get
399 !> \return ...
400 !> \author fawzi
401 ! **************************************************************************************************
402  FUNCTION section_get_subsection(section, subsection_name) RESULT(res)
403 
404  TYPE(section_type), INTENT(IN) :: section
405  CHARACTER(len=*), INTENT(IN) :: subsection_name
406  TYPE(section_type), POINTER :: res
407 
408  INTEGER :: isub
409 
410  isub = section_get_subsection_index(section, subsection_name)
411  IF (isub > 0) THEN
412  res => section%subsections(isub)%section
413  ELSE
414  NULLIFY (res)
415  END IF
416 
417  END FUNCTION section_get_subsection
418 
419 ! **************************************************************************************************
420 !> \brief returns the index of the requested keyword (or -2 if not found)
421 !> \param section the section the keyword is in
422 !> \param keyword_name the keyword you are interested in
423 !> \return ...
424 !> \author fawzi
425 !> \note
426 !> private utility function
427 ! **************************************************************************************************
428  FUNCTION section_get_keyword_index(section, keyword_name) RESULT(res)
429 
430  TYPE(section_type), INTENT(IN) :: section
431  CHARACTER(len=*), INTENT(IN) :: keyword_name
432  INTEGER :: res
433 
434  INTEGER :: ik, in
435  CHARACTER(len=default_string_length) :: upc_name
436 
437  cpassert(section%ref_count > 0)
438  cpassert(ASSOCIATED(section%keywords))
439  res = -2
440  upc_name = keyword_name
441  CALL uppercase(upc_name)
442  DO ik = -1, 0
443  IF (ASSOCIATED(section%keywords(ik)%keyword)) THEN
444  IF (section%keywords(ik)%keyword%names(1) == upc_name) THEN
445  res = ik
446  END IF
447  END IF
448  END DO
449  IF (res == -2) THEN
450  k_search_loop: DO ik = 1, section%n_keywords
451  cpassert(ASSOCIATED(section%keywords(ik)%keyword))
452  DO in = 1, SIZE(section%keywords(ik)%keyword%names)
453  IF (section%keywords(ik)%keyword%names(in) == upc_name) THEN
454  res = ik
455  EXIT k_search_loop
456  END IF
457  END DO
458  END DO k_search_loop
459  END IF
460 
461  END FUNCTION section_get_keyword_index
462 
463 ! **************************************************************************************************
464 !> \brief returns the requested keyword
465 !> \param section the section the keyword is in
466 !> \param keyword_name the keyword you are interested in
467 !> \return ...
468 !> \author fawzi
469 ! **************************************************************************************************
470  RECURSIVE FUNCTION section_get_keyword(section, keyword_name) RESULT(res)
471 
472  TYPE(section_type), INTENT(IN) :: section
473  CHARACTER(len=*), INTENT(IN) :: keyword_name
474  TYPE(keyword_type), POINTER :: res
475 
476  INTEGER :: ik, my_index
477 
478  IF (index(keyword_name, "%") /= 0) THEN
479  my_index = index(keyword_name, "%") + 1
480  cpassert(ASSOCIATED(section%subsections))
481  DO ik = lbound(section%subsections, 1), ubound(section%subsections, 1)
482  IF (section%subsections(ik)%section%name == keyword_name(1:my_index - 2)) EXIT
483  END DO
484  cpassert(ik <= ubound(section%subsections, 1))
485  res => section_get_keyword(section%subsections(ik)%section, keyword_name(my_index:))
486  ELSE
487  ik = section_get_keyword_index(section, keyword_name)
488  IF (ik == -2) THEN
489  NULLIFY (res)
490  ELSE
491  res => section%keywords(ik)%keyword
492  END IF
493  END IF
494 
495  END FUNCTION section_get_keyword
496 
497 ! **************************************************************************************************
498 !> \brief adds a keyword to the given section
499 !> \param section the section to which the keyword should be added
500 !> \param keyword the keyword to add
501 !> \author fawzi
502 ! **************************************************************************************************
503  SUBROUTINE section_add_keyword(section, keyword)
504 
505  TYPE(section_type), INTENT(INOUT) :: section
506  TYPE(keyword_type), INTENT(IN), POINTER :: keyword
507 
508  INTEGER :: i, j, k
509  TYPE(keyword_p_type), DIMENSION(:), POINTER :: new_keywords
510 
511  cpassert(section%ref_count > 0)
512  cpassert(.NOT. section%frozen)
513  cpassert(ASSOCIATED(keyword))
514  cpassert(keyword%ref_count > 0)
515  CALL keyword_retain(keyword)
516  IF (keyword%names(1) == "_SECTION_PARAMETERS_") THEN
517  CALL keyword_release(section%keywords(-1)%keyword)
518  section%keywords(-1)%keyword => keyword
519  ELSE IF (keyword%names(1) == "_DEFAULT_KEYWORD_") THEN
520  CALL keyword_release(section%keywords(0)%keyword)
521  section%keywords(0)%keyword => keyword
522  ELSE
523  DO k = 1, SIZE(keyword%names)
524  DO i = 1, section%n_keywords
525  DO j = 1, SIZE(section%keywords(i)%keyword%names)
526  IF (keyword%names(k) == section%keywords(i)%keyword%names(j)) THEN
527  CALL cp_abort(__location__, &
528  "trying to add a keyword with a name ("// &
529  trim(keyword%names(k))//") that was already used in section " &
530  //trim(section%name))
531  END IF
532  END DO
533  END DO
534  END DO
535 
536  IF (ubound(section%keywords, 1) == section%n_keywords) THEN
537  ALLOCATE (new_keywords(-1:section%n_keywords + 10))
538  DO i = -1, section%n_keywords
539  new_keywords(i)%keyword => section%keywords(i)%keyword
540  END DO
541  DO i = section%n_keywords + 1, ubound(new_keywords, 1)
542  NULLIFY (new_keywords(i)%keyword)
543  END DO
544  DEALLOCATE (section%keywords)
545  section%keywords => new_keywords
546  END IF
547  section%n_keywords = section%n_keywords + 1
548  section%keywords(section%n_keywords)%keyword => keyword
549  END IF
550 
551  END SUBROUTINE section_add_keyword
552 
553 ! **************************************************************************************************
554 !> \brief adds a subsection to the given section
555 !> \param section to section to which you want to add a subsection
556 !> \param subsection the subsection to add
557 !> \author fawzi
558 ! **************************************************************************************************
559  SUBROUTINE section_add_subsection(section, subsection)
560 
561  TYPE(section_type), INTENT(INOUT) :: section
562  TYPE(section_type), INTENT(IN), POINTER :: subsection
563 
564  INTEGER :: i
565  TYPE(section_p_type), DIMENSION(:), POINTER :: new_subsections
566 
567  cpassert(section%ref_count > 0)
568  cpassert(ASSOCIATED(subsection))
569  cpassert(subsection%ref_count > 0)
570  IF (SIZE(section%subsections) < section%n_subsections + 1) THEN
571  ALLOCATE (new_subsections(section%n_subsections + 10))
572  DO i = 1, section%n_subsections
573  new_subsections(i)%section => section%subsections(i)%section
574  END DO
575  DO i = section%n_subsections + 1, SIZE(new_subsections)
576  NULLIFY (new_subsections(i)%section)
577  END DO
578  DEALLOCATE (section%subsections)
579  section%subsections => new_subsections
580  END IF
581  DO i = 1, section%n_subsections
582  IF (subsection%name == section%subsections(i)%section%name) &
583  CALL cp_abort(__location__, &
584  "trying to add a subsection with a name ("// &
585  trim(subsection%name)//") that was already used in section " &
586  //trim(section%name))
587  END DO
588  CALL section_retain(subsection)
589  section%n_subsections = section%n_subsections + 1
590  section%subsections(section%n_subsections)%section => subsection
591 
592  END SUBROUTINE section_add_subsection
593 
594 ! **************************************************************************************************
595 !> \brief creates a object where to store the values of a section
596 !> \param section_vals the parsed section that will be created
597 !> \param section the structure of the section that you want to parse
598 !> \author fawzi
599 ! **************************************************************************************************
600  RECURSIVE SUBROUTINE section_vals_create(section_vals, section)
601 
602  TYPE(section_vals_type), POINTER :: section_vals
603  TYPE(section_type), POINTER :: section
604 
605  INTEGER :: i
606 
607  cpassert(.NOT. ASSOCIATED(section_vals))
608  ALLOCATE (section_vals)
609  section_vals%ref_count = 1
610  CALL section_retain(section)
611  section_vals%section => section
612  section%frozen = .true.
613  ALLOCATE (section_vals%values(-1:section%n_keywords, 0))
614  ALLOCATE (section_vals%subs_vals(section%n_subsections, 1))
615  DO i = 1, section%n_subsections
616  NULLIFY (section_vals%subs_vals(i, 1)%section_vals)
617  CALL section_vals_create(section_vals%subs_vals(i, 1)%section_vals, &
618  section=section%subsections(i)%section)
619  END DO
620 
621  NULLIFY (section_vals%ibackup)
622 
623  END SUBROUTINE section_vals_create
624 
625 ! **************************************************************************************************
626 !> \brief retains the given section values (see doc/ReferenceCounting.html)
627 !> \param section_vals the object to retain
628 !> \author fawzi
629 ! **************************************************************************************************
630  SUBROUTINE section_vals_retain(section_vals)
631 
632  TYPE(section_vals_type), POINTER :: section_vals
633 
634  cpassert(ASSOCIATED(section_vals))
635  cpassert(section_vals%ref_count > 0)
636  section_vals%ref_count = section_vals%ref_count + 1
637 
638  END SUBROUTINE section_vals_retain
639 
640 ! **************************************************************************************************
641 !> \brief releases the given object
642 !> \param section_vals the section_vals to release
643 !> \author fawzi
644 ! **************************************************************************************************
645  RECURSIVE SUBROUTINE section_vals_release(section_vals)
646 
647  TYPE(section_vals_type), POINTER :: section_vals
648 
649  INTEGER :: i, j
650  TYPE(cp_sll_val_type), POINTER :: vals
651  TYPE(val_type), POINTER :: el
652 
653  IF (ASSOCIATED(section_vals)) THEN
654  cpassert(section_vals%ref_count > 0)
655  section_vals%ref_count = section_vals%ref_count - 1
656  IF (section_vals%ref_count == 0) THEN
657  CALL section_release(section_vals%section)
658  DO j = 1, SIZE(section_vals%values, 2)
659  DO i = -1, ubound(section_vals%values, 1)
660  vals => section_vals%values(i, j)%list
661  DO WHILE (cp_sll_val_next(vals, el_att=el))
662  CALL val_release(el)
663  END DO
664  CALL cp_sll_val_dealloc(section_vals%values(i, j)%list)
665  END DO
666  END DO
667  DEALLOCATE (section_vals%values)
668  DO j = 1, SIZE(section_vals%subs_vals, 2)
669  DO i = 1, SIZE(section_vals%subs_vals, 1)
670  CALL section_vals_release(section_vals%subs_vals(i, j)%section_vals)
671  END DO
672  END DO
673  DEALLOCATE (section_vals%subs_vals)
674  IF (ASSOCIATED(section_vals%ibackup)) THEN
675  DEALLOCATE (section_vals%ibackup)
676  END IF
677  DEALLOCATE (section_vals)
678  END IF
679  END IF
680 
681  END SUBROUTINE section_vals_release
682 
683 ! **************************************************************************************************
684 !> \brief returns various attributes about the section_vals
685 !> \param section_vals the section vals you want information from
686 !> \param ref_count ...
687 !> \param n_repetition number of repetitions of the section
688 !> \param n_subs_vals_rep number of repetitions of the subsections values
689 !> (max(1,n_repetition))
690 !> \param section ...
691 !> \param explicit if the section was explicitly present in
692 !> \author fawzi
693 !> \note For the other arguments see the attributes of section_vals_type
694 ! **************************************************************************************************
695  SUBROUTINE section_vals_get(section_vals, ref_count, n_repetition, &
696  n_subs_vals_rep, section, explicit)
697 
698  TYPE(section_vals_type), INTENT(IN) :: section_vals
699  INTEGER, INTENT(out), OPTIONAL :: ref_count, n_repetition, n_subs_vals_rep
700  TYPE(section_type), OPTIONAL, POINTER :: section
701  LOGICAL, INTENT(out), OPTIONAL :: explicit
702 
703  cpassert(section_vals%ref_count > 0)
704  IF (PRESENT(ref_count)) ref_count = section_vals%ref_count
705  IF (PRESENT(section)) section => section_vals%section
706  IF (PRESENT(n_repetition)) n_repetition = SIZE(section_vals%values, 2)
707  IF (PRESENT(n_subs_vals_rep)) n_subs_vals_rep = SIZE(section_vals%subs_vals, 2)
708  IF (PRESENT(explicit)) explicit = (SIZE(section_vals%values, 2) > 0)
709 
710  END SUBROUTINE section_vals_get
711 
712 ! **************************************************************************************************
713 !> \brief returns the values of the requested subsection
714 !> \param section_vals the root section
715 !> \param subsection_name the name of the requested subsection
716 !> \param i_rep_section index of the repetition of section_vals from which
717 !> you want to extract the subsection (defaults to 1)
718 !> \param can_return_null if the results can be null (defaults to false)
719 !> \return ...
720 !> \author fawzi
721 ! **************************************************************************************************
722  RECURSIVE FUNCTION section_vals_get_subs_vals(section_vals, subsection_name, &
723  i_rep_section, can_return_null) RESULT(res)
724 
725  TYPE(section_vals_type), INTENT(IN) :: section_vals
726  CHARACTER(len=*), INTENT(IN) :: subsection_name
727  INTEGER, INTENT(IN), OPTIONAL :: i_rep_section
728  LOGICAL, INTENT(IN), OPTIONAL :: can_return_null
729  TYPE(section_vals_type), POINTER :: res
730 
731  INTEGER :: irep, isection, my_index
732  LOGICAL :: is_path, my_can_return_null
733 
734  cpassert(section_vals%ref_count > 0)
735 
736  my_can_return_null = .false.
737  IF (PRESENT(can_return_null)) my_can_return_null = can_return_null
738  NULLIFY (res)
739  irep = 1
740  IF (PRESENT(i_rep_section)) irep = i_rep_section
741 
742  ! prepare for recursive parsing of subsections. i_rep_section will be used for last section
743  my_index = index(subsection_name, "%")
744  IF (my_index .EQ. 0) THEN
745  is_path = .false.
746  my_index = len_trim(subsection_name)
747  ELSE
748  is_path = .true.
749  irep = 1
750  my_index = my_index - 1
751  END IF
752 
753  cpassert(irep <= SIZE(section_vals%subs_vals, 2))
754 
755  isection = section_get_subsection_index(section_vals%section, subsection_name(1:my_index))
756  IF (isection > 0) res => section_vals%subs_vals(isection, irep)%section_vals
757  IF (.NOT. (ASSOCIATED(res) .OR. my_can_return_null)) &
758  CALL cp_abort(__location__, &
759  "could not find subsection "//trim(subsection_name(1:my_index))//" in section "// &
760  trim(section_vals%section%name)//" at ")
761  IF (is_path .AND. ASSOCIATED(res)) THEN
762  res => section_vals_get_subs_vals(res, subsection_name(my_index + 2:len_trim(subsection_name)), &
763  i_rep_section, can_return_null)
764  END IF
765 
766  END FUNCTION section_vals_get_subs_vals
767 
768 ! **************************************************************************************************
769 !> \brief returns the values of the n-th non default subsection (null if no
770 !> such section exists (not so many non default section))
771 !> \param section_vals the root section
772 !> \param i_section index of the section
773 !> \param i_rep_section index of the repetition of section_vals from which
774 !> you want to extract the subsection (defaults to 1)
775 !> \return ...
776 !> \author fawzi
777 ! **************************************************************************************************
778  FUNCTION section_vals_get_subs_vals2(section_vals, i_section, i_rep_section) RESULT(res)
779 
780  TYPE(section_vals_type), POINTER :: section_vals
781  INTEGER, INTENT(in) :: i_section
782  INTEGER, INTENT(in), OPTIONAL :: i_rep_section
783  TYPE(section_vals_type), POINTER :: res
784 
785  INTEGER :: i, irep, isect_att
786 
787  cpassert(ASSOCIATED(section_vals))
788  cpassert(section_vals%ref_count > 0)
789  NULLIFY (res)
790  irep = 1
791  IF (PRESENT(i_rep_section)) irep = i_rep_section
792  cpassert(irep <= SIZE(section_vals%subs_vals, 2))
793  isect_att = 0
794  DO i = 1, section_vals%section%n_subsections
795  IF (SIZE(section_vals%subs_vals(i, irep)%section_vals%values, 2) > 0) THEN
796  isect_att = isect_att + 1
797  IF (isect_att == i_section) THEN
798  res => section_vals%subs_vals(i, irep)%section_vals
799  EXIT
800  END IF
801  END IF
802  END DO
803  END FUNCTION section_vals_get_subs_vals2
804 
805 ! **************************************************************************************************
806 !> \brief returns the values of the n-th non default subsection (null if no
807 !> such section exists (not so many non default section))
808 !> \param section_vals the root section
809 !> \param subsection_name ...
810 !> \param i_rep_section index of the repetition of section_vals from which
811 !> you want to extract the subsection (defaults to 1)
812 !> \return ...
813 !> \author fawzi
814 ! **************************************************************************************************
815  FUNCTION section_vals_get_subs_vals3(section_vals, subsection_name, &
816  i_rep_section) RESULT(res)
817 
818  TYPE(section_vals_type), INTENT(IN) :: section_vals
819  CHARACTER(LEN=*), INTENT(IN) :: subsection_name
820  INTEGER, INTENT(in), OPTIONAL :: i_rep_section
821  TYPE(section_vals_type), POINTER :: res
822 
823  INTEGER :: i_section, irep
824 
825  cpassert(section_vals%ref_count > 0)
826  NULLIFY (res)
827  irep = 1
828  IF (PRESENT(i_rep_section)) irep = i_rep_section
829  cpassert(irep <= SIZE(section_vals%subs_vals, 2))
830  i_section = section_get_subsection_index(section_vals%section, subsection_name)
831  res => section_vals%subs_vals(i_section, irep)%section_vals
832 
833  END FUNCTION section_vals_get_subs_vals3
834 
835 ! **************************************************************************************************
836 !> \brief adds the place to store the values of a repetition of the section
837 !> \param section_vals the section you want to extend
838 !> \author fawzi
839 ! **************************************************************************************************
840  SUBROUTINE section_vals_add_values(section_vals)
841 
842  TYPE(section_vals_type), INTENT(INOUT) :: section_vals
843 
844  INTEGER :: i, j
845  TYPE(cp_sll_val_p_type), DIMENSION(:, :), POINTER :: new_values
846  TYPE(section_vals_p_type), DIMENSION(:, :), &
847  POINTER :: new_sps
848 
849  cpassert(section_vals%ref_count > 0)
850  ALLOCATE (new_values(-1:ubound(section_vals%values, 1), SIZE(section_vals%values, 2) + 1))
851  DO j = 1, SIZE(section_vals%values, 2)
852  DO i = -1, ubound(section_vals%values, 1)
853  new_values(i, j)%list => section_vals%values(i, j)%list
854  END DO
855  END DO
856  DEALLOCATE (section_vals%values)
857  section_vals%values => new_values
858  j = SIZE(new_values, 2)
859  DO i = -1, ubound(new_values, 1)
860  NULLIFY (new_values(i, j)%list)
861  END DO
862 
863  IF (SIZE(new_values, 2) > 1) THEN
864  ALLOCATE (new_sps(SIZE(section_vals%subs_vals, 1), &
865  SIZE(section_vals%subs_vals, 2) + 1))
866  DO j = 1, SIZE(section_vals%subs_vals, 2)
867  DO i = 1, SIZE(section_vals%subs_vals, 1)
868  new_sps(i, j)%section_vals => section_vals%subs_vals(i, j)%section_vals
869  END DO
870  END DO
871  DEALLOCATE (section_vals%subs_vals)
872  section_vals%subs_vals => new_sps
873  j = SIZE(new_sps, 2)
874  DO i = 1, SIZE(new_sps, 1)
875  NULLIFY (new_sps(i, j)%section_vals)
876  CALL section_vals_create(new_sps(i, SIZE(new_sps, 2))%section_vals, &
877  section=section_vals%section%subsections(i)%section)
878  END DO
879  END IF
880 
881  END SUBROUTINE section_vals_add_values
882 
883 ! **************************************************************************************************
884 !> \brief removes the values of a repetition of the section
885 !> \param section_vals the section you want to extend
886 !> \author fawzi
887 ! **************************************************************************************************
888  SUBROUTINE section_vals_remove_values(section_vals)
889 
890  TYPE(section_vals_type), POINTER :: section_vals
891 
892  INTEGER :: i, j
893  TYPE(cp_sll_val_p_type), DIMENSION(:, :), POINTER :: new_values
894  TYPE(cp_sll_val_type), POINTER :: vals
895  TYPE(val_type), POINTER :: el
896 
897  IF (ASSOCIATED(section_vals)) THEN
898  cpassert(section_vals%ref_count > 0)
899  NULLIFY (el, vals)
900  ! Allocate a null 0 dimension array of values
901  ALLOCATE (new_values(-1:section_vals%section%n_keywords, 0))
902  ! Release old values
903  DO j = 1, SIZE(section_vals%values, 2)
904  DO i = -1, ubound(section_vals%values, 1)
905  vals => section_vals%values(i, j)%list
906  DO WHILE (cp_sll_val_next(vals, el_att=el))
907  CALL val_release(el)
908  END DO
909  CALL cp_sll_val_dealloc(section_vals%values(i, j)%list)
910  END DO
911  END DO
912  DEALLOCATE (section_vals%values)
913  section_vals%values => new_values
914  END IF
915 
916  END SUBROUTINE section_vals_remove_values
917 
918 ! **************************************************************************************************
919 !> \brief ...
920 !> \param section_vals ...
921 !> \param keyword_name ...
922 !> \return ...
923 ! **************************************************************************************************
924  FUNCTION section_get_cval(section_vals, keyword_name) RESULT(res)
925 
926  TYPE(section_vals_type), INTENT(IN) :: section_vals
927  CHARACTER(len=*), INTENT(in) :: keyword_name
928  CHARACTER(LEN=default_string_length) :: res
929 
930  CALL section_vals_val_get(section_vals, keyword_name, c_val=res)
931 
932  END FUNCTION section_get_cval
933 
934 ! **************************************************************************************************
935 !> \brief ...
936 !> \param section_vals ...
937 !> \param keyword_name ...
938 !> \return ...
939 ! **************************************************************************************************
940  FUNCTION section_get_rval(section_vals, keyword_name) RESULT(res)
941 
942  TYPE(section_vals_type), INTENT(IN) :: section_vals
943  CHARACTER(len=*), INTENT(in) :: keyword_name
944  REAL(kind=dp) :: res
945 
946  CALL section_vals_val_get(section_vals, keyword_name, r_val=res)
947 
948  END FUNCTION section_get_rval
949 
950 ! **************************************************************************************************
951 !> \brief ...
952 !> \param section_vals ...
953 !> \param keyword_name ...
954 !> \return ...
955 ! **************************************************************************************************
956  FUNCTION section_get_rvals(section_vals, keyword_name) RESULT(res)
957 
958  TYPE(section_vals_type), INTENT(IN) :: section_vals
959  CHARACTER(len=*), INTENT(in) :: keyword_name
960  REAL(kind=dp), DIMENSION(:), POINTER :: res
961 
962  CALL section_vals_val_get(section_vals, keyword_name, r_vals=res)
963 
964  END FUNCTION section_get_rvals
965 
966 ! **************************************************************************************************
967 !> \brief ...
968 !> \param section_vals ...
969 !> \param keyword_name ...
970 !> \return ...
971 ! **************************************************************************************************
972  FUNCTION section_get_ival(section_vals, keyword_name) RESULT(res)
973 
974  TYPE(section_vals_type), INTENT(IN) :: section_vals
975  CHARACTER(len=*), INTENT(in) :: keyword_name
976  INTEGER :: res
977 
978  CALL section_vals_val_get(section_vals, keyword_name, i_val=res)
979 
980  END FUNCTION section_get_ival
981 
982 ! **************************************************************************************************
983 !> \brief ...
984 !> \param section_vals ...
985 !> \param keyword_name ...
986 !> \return ...
987 ! **************************************************************************************************
988  FUNCTION section_get_ivals(section_vals, keyword_name) RESULT(res)
989 
990  TYPE(section_vals_type), INTENT(IN) :: section_vals
991  CHARACTER(len=*), INTENT(in) :: keyword_name
992  INTEGER, DIMENSION(:), POINTER :: res
993 
994  CALL section_vals_val_get(section_vals, keyword_name, i_vals=res)
995 
996  END FUNCTION section_get_ivals
997 
998 ! **************************************************************************************************
999 !> \brief ...
1000 !> \param section_vals ...
1001 !> \param keyword_name ...
1002 !> \return ...
1003 ! **************************************************************************************************
1004  FUNCTION section_get_lval(section_vals, keyword_name) RESULT(res)
1005 
1006  TYPE(section_vals_type), INTENT(IN) :: section_vals
1007  CHARACTER(len=*), INTENT(in) :: keyword_name
1008  LOGICAL :: res
1009 
1010  CALL section_vals_val_get(section_vals, keyword_name, l_val=res)
1011 
1012  END FUNCTION section_get_lval
1013 
1014 ! **************************************************************************************************
1015 !> \brief returns the requested value
1016 !> \param section_vals ...
1017 !> \param keyword_name the name of the keyword you want
1018 !> \param i_rep_section which repetition of the section you are interested in
1019 !> (defaults to 1)
1020 !> \param i_rep_val which repetition of the keyword/val you are interested in
1021 !> (defaults to 1)
1022 !> \param n_rep_val returns number of val available
1023 !> \param val ...
1024 !> \param l_val ,i_val,r_val,c_val: returns the logical,integer,real or
1025 !> character value
1026 !> \param i_val ...
1027 !> \param r_val ...
1028 !> \param c_val ...
1029 !> \param l_vals ,i_vals,r_vals,c_vals: returns the logical,integer,real or
1030 !> character arrays. The val reamins the owner of the array
1031 !> \param i_vals ...
1032 !> \param r_vals ...
1033 !> \param c_vals ...
1034 !> \param explicit ...
1035 !> \author fawzi
1036 ! **************************************************************************************************
1037  SUBROUTINE section_vals_val_get(section_vals, keyword_name, i_rep_section, &
1038  i_rep_val, n_rep_val, val, l_val, i_val, r_val, c_val, l_vals, i_vals, r_vals, &
1039  c_vals, explicit)
1040 
1041  TYPE(section_vals_type), INTENT(IN), TARGET :: section_vals
1042  CHARACTER(len=*), INTENT(in) :: keyword_name
1043  INTEGER, INTENT(in), OPTIONAL :: i_rep_section, i_rep_val
1044  INTEGER, INTENT(out), OPTIONAL :: n_rep_val
1045  TYPE(val_type), OPTIONAL, POINTER :: val
1046  LOGICAL, INTENT(out), OPTIONAL :: l_val
1047  INTEGER, INTENT(out), OPTIONAL :: i_val
1048  REAL(kind=dp), INTENT(out), OPTIONAL :: r_val
1049  CHARACTER(LEN=*), INTENT(out), OPTIONAL :: c_val
1050  LOGICAL, DIMENSION(:), OPTIONAL, POINTER :: l_vals
1051  INTEGER, DIMENSION(:), OPTIONAL, POINTER :: i_vals
1052  REAL(kind=dp), DIMENSION(:), OPTIONAL, POINTER :: r_vals
1053  CHARACTER(LEN=default_string_length), &
1054  DIMENSION(:), OPTIONAL, POINTER :: c_vals
1055  LOGICAL, INTENT(out), OPTIONAL :: explicit
1056 
1057  INTEGER :: ik, irk, irs, len_key, my_index, &
1058  tmp_index
1059  LOGICAL :: valrequested
1060  TYPE(cp_sll_val_type), POINTER :: vals
1061  TYPE(keyword_type), POINTER :: keyword
1062  TYPE(section_type), POINTER :: section
1063  TYPE(section_vals_type), POINTER :: s_vals
1064  TYPE(val_type), POINTER :: my_val
1065 
1066  cpassert(section_vals%ref_count > 0)
1067 
1068  my_index = index(keyword_name, '%') + 1
1069  len_key = len_trim(keyword_name)
1070  IF (my_index > 1) THEN
1071  DO
1072  tmp_index = index(keyword_name(my_index:len_key), "%")
1073  IF (tmp_index <= 0) EXIT
1074  my_index = my_index + tmp_index
1075  END DO
1076  s_vals => section_vals_get_subs_vals(section_vals, keyword_name(1:my_index - 2))
1077  ELSE
1078  s_vals => section_vals
1079  END IF
1080 
1081  irk = 1
1082  irs = 1
1083  IF (PRESENT(i_rep_section)) irs = i_rep_section
1084  IF (PRESENT(i_rep_val)) irk = i_rep_val
1085  IF (PRESENT(val)) NULLIFY (val)
1086  IF (PRESENT(explicit)) explicit = .false.
1087  section => s_vals%section
1088  valrequested = PRESENT(l_val) .OR. PRESENT(i_val) .OR. PRESENT(r_val) .OR. &
1089  PRESENT(c_val) .OR. PRESENT(l_vals) .OR. PRESENT(i_vals) .OR. &
1090  PRESENT(r_vals) .OR. PRESENT(c_vals)
1091  ik = section_get_keyword_index(s_vals%section, keyword_name(my_index:len_key))
1092  IF (ik == -2) &
1093  CALL cp_abort(__location__, &
1094  "section "//trim(section%name)//" does not contain keyword "// &
1095  trim(keyword_name(my_index:len_key)))
1096  keyword => section%keywords(ik)%keyword
1097  IF (.NOT. (irs > 0 .AND. irs <= SIZE(s_vals%subs_vals, 2))) &
1098  CALL cp_abort(__location__, &
1099  "section repetition requested ("//cp_to_string(irs)// &
1100  ") out of bounds (1:"//cp_to_string(SIZE(s_vals%subs_vals, 2)) &
1101  //")")
1102  NULLIFY (my_val)
1103  IF (PRESENT(n_rep_val)) n_rep_val = 0
1104  IF (irs <= SIZE(s_vals%values, 2)) THEN ! the section was parsed
1105  vals => s_vals%values(ik, irs)%list
1106  IF (PRESENT(n_rep_val)) n_rep_val = cp_sll_val_get_length(vals)
1107  IF (.NOT. ASSOCIATED(vals)) THEN
1108  ! this keyword was not parsed
1109  IF (ASSOCIATED(keyword%default_value)) THEN
1110  my_val => keyword%default_value
1111  IF (PRESENT(n_rep_val)) n_rep_val = 1
1112  END IF
1113  ELSE
1114  my_val => cp_sll_val_get_el_at(s_vals%values(ik, irs)%list, &
1115  irk)
1116  IF (PRESENT(explicit)) explicit = .true.
1117  END IF
1118  ELSE IF (ASSOCIATED(keyword%default_value)) THEN
1119  IF (PRESENT(n_rep_val)) n_rep_val = 1
1120  my_val => keyword%default_value
1121  END IF
1122  IF (PRESENT(val)) val => my_val
1123  IF (valrequested) THEN
1124  IF (.NOT. ASSOCIATED(my_val)) &
1125  CALL cp_abort(__location__, &
1126  "Value requested, but no value set getting value from "// &
1127  "keyword "//trim(keyword_name(my_index:len_key))//" of section "// &
1128  trim(section%name))
1129  CALL val_get(my_val, l_val=l_val, i_val=i_val, r_val=r_val, &
1130  c_val=c_val, l_vals=l_vals, i_vals=i_vals, r_vals=r_vals, &
1131  c_vals=c_vals)
1132  END IF
1133 
1134  END SUBROUTINE section_vals_val_get
1135 
1136 ! **************************************************************************************************
1137 !> \brief returns the requested list
1138 !> \param section_vals ...
1139 !> \param keyword_name the name of the keyword you want
1140 !> \param i_rep_section which repetition of the section you are interested in
1141 !> (defaults to 1)
1142 !> \param list ...
1143 !> \author Joost VandeVondele
1144 !> \note
1145 !> - most useful if the full list is needed anyway, so that faster iteration can be used
1146 ! **************************************************************************************************
1147  SUBROUTINE section_vals_list_get(section_vals, keyword_name, i_rep_section, &
1148  list)
1149 
1150  TYPE(section_vals_type), INTENT(IN), POINTER :: section_vals
1151  CHARACTER(len=*), INTENT(in) :: keyword_name
1152  INTEGER, OPTIONAL :: i_rep_section
1153  TYPE(cp_sll_val_type), POINTER :: list
1154 
1155  INTEGER :: ik, irs, len_key, my_index, tmp_index
1156  TYPE(section_type), POINTER :: section
1157  TYPE(section_vals_type), POINTER :: s_vals
1158 
1159  cpassert(ASSOCIATED(section_vals))
1160  cpassert(section_vals%ref_count > 0)
1161  NULLIFY (list)
1162  my_index = index(keyword_name, '%') + 1
1163  len_key = len_trim(keyword_name)
1164  IF (my_index > 1) THEN
1165  DO
1166  tmp_index = index(keyword_name(my_index:len_key), "%")
1167  IF (tmp_index <= 0) EXIT
1168  my_index = my_index + tmp_index
1169  END DO
1170  s_vals => section_vals_get_subs_vals(section_vals, keyword_name(1:my_index - 2))
1171  ELSE
1172  s_vals => section_vals
1173  END IF
1174 
1175  irs = 1
1176  IF (PRESENT(i_rep_section)) irs = i_rep_section
1177  section => s_vals%section
1178  ik = section_get_keyword_index(s_vals%section, keyword_name(my_index:len_key))
1179  IF (ik == -2) &
1180  CALL cp_abort(__location__, &
1181  "section "//trim(section%name)//" does not contain keyword "// &
1182  trim(keyword_name(my_index:len_key)))
1183  IF (.NOT. (irs > 0 .AND. irs <= SIZE(s_vals%subs_vals, 2))) &
1184  CALL cp_abort(__location__, &
1185  "section repetition requested ("//cp_to_string(irs)// &
1186  ") out of bounds (1:"//cp_to_string(SIZE(s_vals%subs_vals, 2)) &
1187  //")")
1188  list => s_vals%values(ik, irs)%list
1189 
1190  END SUBROUTINE section_vals_list_get
1191 
1192 ! **************************************************************************************************
1193 !> \brief sets the requested value
1194 !> \param section_vals ...
1195 !> \param keyword_name the name of the keyword you want (can be a path
1196 !> separated by '%')
1197 !> \param i_rep_section isection which repetition of the section you are
1198 !> nterested in (defaults to 1)
1199 !> \param i_rep_val which repetition of the keyword/val you are interested in
1200 !> (defaults to 1)
1201 !> \param val ...
1202 !> \param l_val ,i_val,r_val,c_val: sets the logical,integer,real or
1203 !> character value
1204 !> \param i_val ...
1205 !> \param r_val ...
1206 !> \param c_val ...
1207 !> \param l_vals_ptr ,i_vals_ptr,r_vals,c_vals: sets the logical,integer,real or
1208 !> character arrays. The val becomes the owner of the array
1209 !> \param i_vals_ptr ...
1210 !> \param r_vals_ptr ...
1211 !> \param c_vals_ptr ...
1212 !> \author fawzi
1213 ! **************************************************************************************************
1214  SUBROUTINE section_vals_val_set(section_vals, keyword_name, i_rep_section, i_rep_val, &
1215  val, l_val, i_val, r_val, c_val, l_vals_ptr, i_vals_ptr, r_vals_ptr, c_vals_ptr)
1216 
1217  TYPE(section_vals_type), POINTER :: section_vals
1218  CHARACTER(len=*), INTENT(in) :: keyword_name
1219  INTEGER, INTENT(in), OPTIONAL :: i_rep_section, i_rep_val
1220  TYPE(val_type), OPTIONAL, POINTER :: val
1221  LOGICAL, INTENT(in), OPTIONAL :: l_val
1222  INTEGER, INTENT(in), OPTIONAL :: i_val
1223  REAL(kind=dp), INTENT(in), OPTIONAL :: r_val
1224  CHARACTER(LEN=*), INTENT(in), OPTIONAL :: c_val
1225  LOGICAL, DIMENSION(:), OPTIONAL, POINTER :: l_vals_ptr
1226  INTEGER, DIMENSION(:), OPTIONAL, POINTER :: i_vals_ptr
1227  REAL(kind=dp), DIMENSION(:), OPTIONAL, POINTER :: r_vals_ptr
1228  CHARACTER(LEN=default_string_length), &
1229  DIMENSION(:), OPTIONAL, POINTER :: c_vals_ptr
1230 
1231  INTEGER :: ik, irk, irs, len_key, my_index, &
1232  tmp_index
1233  LOGICAL :: valset
1234  TYPE(cp_sll_val_type), POINTER :: vals
1235  TYPE(keyword_type), POINTER :: keyword
1236  TYPE(section_type), POINTER :: section
1237  TYPE(section_vals_type), POINTER :: s_vals
1238  TYPE(val_type), POINTER :: my_val, old_val
1239 
1240  cpassert(ASSOCIATED(section_vals))
1241  cpassert(section_vals%ref_count > 0)
1242 
1243  my_index = index(keyword_name, '%') + 1
1244  len_key = len_trim(keyword_name)
1245  IF (my_index > 1) THEN
1246  DO
1247  tmp_index = index(keyword_name(my_index:len_key), "%")
1248  IF (tmp_index <= 0) EXIT
1249  my_index = my_index + tmp_index
1250  END DO
1251  s_vals => section_vals_get_subs_vals(section_vals, keyword_name(1:my_index - 2))
1252  ELSE
1253  s_vals => section_vals
1254  END IF
1255 
1256  irk = 1
1257  irs = 1
1258  IF (PRESENT(i_rep_section)) irs = i_rep_section
1259  IF (PRESENT(i_rep_val)) irk = i_rep_val
1260  section => s_vals%section
1261  ik = section_get_keyword_index(s_vals%section, keyword_name(my_index:len_key))
1262  IF (ik == -2) &
1263  CALL cp_abort(__location__, &
1264  "section "//trim(section%name)//" does not contain keyword "// &
1265  trim(keyword_name(my_index:len_key)))
1266  ! Add values..
1267  DO
1268  IF (irs <= SIZE(s_vals%values, 2)) EXIT
1269  CALL section_vals_add_values(s_vals)
1270  END DO
1271  IF (.NOT. (irs > 0 .AND. irs <= SIZE(s_vals%subs_vals, 2))) &
1272  CALL cp_abort(__location__, &
1273  "section repetition requested ("//cp_to_string(irs)// &
1274  ") out of bounds (1:"//cp_to_string(SIZE(s_vals%subs_vals, 2)) &
1275  //")")
1276  keyword => s_vals%section%keywords(ik)%keyword
1277  NULLIFY (my_val)
1278  IF (PRESENT(val)) my_val => val
1279  valset = PRESENT(l_val) .OR. PRESENT(i_val) .OR. PRESENT(r_val) .OR. &
1280  PRESENT(c_val) .OR. PRESENT(l_vals_ptr) .OR. PRESENT(i_vals_ptr) .OR. &
1281  PRESENT(r_vals_ptr) .OR. PRESENT(c_vals_ptr)
1282  IF (ASSOCIATED(my_val)) THEN
1283  ! check better?
1284  IF (valset) &
1285  CALL cp_abort(__location__, &
1286  " both val and values present, in setting "// &
1287  "keyword "//trim(keyword_name(my_index:len_key))//" of section "// &
1288  trim(section%name))
1289  ELSE
1290  ! ignore ?
1291  IF (.NOT. valset) &
1292  CALL cp_abort(__location__, &
1293  " empty value in setting "// &
1294  "keyword "//trim(keyword_name(my_index:len_key))//" of section "// &
1295  trim(section%name))
1296  cpassert(valset)
1297  IF (keyword%type_of_var == lchar_t) THEN
1298  CALL val_create(my_val, lc_val=c_val, lc_vals_ptr=c_vals_ptr)
1299  ELSE
1300  CALL val_create(my_val, l_val=l_val, i_val=i_val, r_val=r_val, &
1301  c_val=c_val, l_vals_ptr=l_vals_ptr, i_vals_ptr=i_vals_ptr, &
1302  r_vals_ptr=r_vals_ptr, &
1303  c_vals_ptr=c_vals_ptr, enum=keyword%enum)
1304  END IF
1305  cpassert(ASSOCIATED(my_val))
1306  cpassert(my_val%type_of_var == keyword%type_of_var)
1307  END IF
1308  vals => s_vals%values(ik, irs)%list
1309  IF (irk == -1) THEN
1310  CALL cp_sll_val_insert_el_at(vals, my_val, index=-1)
1311  ELSE IF (irk <= cp_sll_val_get_length(vals)) THEN
1312  IF (irk <= 0) &
1313  CALL cp_abort(__location__, &
1314  "invalid irk "//trim(adjustl(cp_to_string(irk)))// &
1315  " in keyword "//trim(keyword_name(my_index:len_key))//" of section "// &
1316  trim(section%name))
1317  old_val => cp_sll_val_get_el_at(vals, index=irk)
1318  CALL val_release(old_val)
1319  CALL cp_sll_val_set_el_at(vals, value=my_val, index=irk)
1320  ELSE IF (irk > cp_sll_val_get_length(vals) + 1) THEN
1321  ! change?
1322  CALL cp_abort(__location__, &
1323  "cannot add extra keyword repetitions to keyword" &
1324  //trim(keyword_name(my_index:len_key))//" of section "// &
1325  trim(section%name))
1326  ELSE
1327  CALL cp_sll_val_insert_el_at(vals, my_val, index=irk)
1328  END IF
1329  s_vals%values(ik, irs)%list => vals
1330  NULLIFY (my_val)
1331  END SUBROUTINE section_vals_val_set
1332 
1333 ! **************************************************************************************************
1334 !> \brief unsets (removes) the requested value (if it is a keyword repetitions
1335 !> removes the repetition, so be careful: the repetition indices bigger
1336 !> than the actual change.
1337 !> \param section_vals ...
1338 !> \param keyword_name the name of the keyword you want (can be a path
1339 !> separated by '%')
1340 !> \param i_rep_section which repetition of the section you are interested in
1341 !> (defaults to 1)
1342 !> \param i_rep_val which repetition of the keyword/val you are interested in
1343 !> (defaults to 1)
1344 !> \author fawzi
1345 ! **************************************************************************************************
1346  SUBROUTINE section_vals_val_unset(section_vals, keyword_name, i_rep_section, i_rep_val)
1347 
1348  TYPE(section_vals_type), POINTER :: section_vals
1349  CHARACTER(len=*), INTENT(in) :: keyword_name
1350  INTEGER, INTENT(in), OPTIONAL :: i_rep_section, i_rep_val
1351 
1352  INTEGER :: ik, irk, irs, len_key, my_index, &
1353  tmp_index
1354  TYPE(cp_sll_val_type), POINTER :: pos
1355  TYPE(section_type), POINTER :: section
1356  TYPE(section_vals_type), POINTER :: s_vals
1357  TYPE(val_type), POINTER :: old_val
1358 
1359  NULLIFY (pos)
1360  cpassert(ASSOCIATED(section_vals))
1361  cpassert(section_vals%ref_count > 0)
1362 
1363  my_index = index(keyword_name, '%') + 1
1364  len_key = len_trim(keyword_name)
1365  IF (my_index > 1) THEN
1366  DO
1367  tmp_index = index(keyword_name(my_index:len_key), "%")
1368  IF (tmp_index <= 0) EXIT
1369  my_index = my_index + tmp_index
1370  END DO
1371  s_vals => section_vals_get_subs_vals(section_vals, keyword_name(1:my_index - 2))
1372  ELSE
1373  s_vals => section_vals
1374  END IF
1375 
1376  irk = 1
1377  irs = 1
1378  IF (PRESENT(i_rep_section)) irs = i_rep_section
1379  IF (PRESENT(i_rep_val)) irk = i_rep_val
1380  section => s_vals%section
1381  ik = section_get_keyword_index(s_vals%section, keyword_name(my_index:len_key))
1382  IF (ik == -2) &
1383  CALL cp_abort(__location__, &
1384  "section "//trim(section%name)//" does not contain keyword "// &
1385  trim(keyword_name(my_index:len_key)))
1386  ! ignore unset of non set values
1387  IF (irs <= SIZE(s_vals%values, 2)) THEN
1388  IF (.NOT. (irs > 0 .AND. irs <= SIZE(s_vals%subs_vals, 2))) &
1389  CALL cp_abort(__location__, &
1390  "section repetition requested ("//cp_to_string(irs)// &
1391  ") out of bounds (1:"//cp_to_string(SIZE(s_vals%subs_vals, 2)) &
1392  //")")
1393  IF (irk == -1) THEN
1394  pos => cp_sll_val_get_rest(s_vals%values(ik, irs)%list, iter=-1)
1395  ELSE
1396  pos => cp_sll_val_get_rest(s_vals%values(ik, irs)%list, iter=irk - 1)
1397  END IF
1398  IF (ASSOCIATED(pos)) THEN
1399  old_val => cp_sll_val_get_el_at(s_vals%values(ik, irs)%list, index=irk)
1400  CALL val_release(old_val)
1401  CALL cp_sll_val_rm_el_at(s_vals%values(ik, irs)%list, index=irk)
1402  END IF
1403  END IF
1404 
1405  END SUBROUTINE section_vals_val_unset
1406 
1407 ! **************************************************************************************************
1408 !> \brief writes the values in the given section in a way that is suitable to
1409 !> the automatic parsing
1410 !> \param section_vals the section to write out
1411 !> \param unit_nr the unit where to write to
1412 !> \param hide_root ...
1413 !> \param hide_defaults ...
1414 !> \author fawzi
1415 !> \note
1416 !> skips required sections which weren't read
1417 ! **************************************************************************************************
1418  RECURSIVE SUBROUTINE section_vals_write(section_vals, unit_nr, hide_root, hide_defaults)
1419 
1420  TYPE(section_vals_type), INTENT(IN) :: section_vals
1421  INTEGER, INTENT(in) :: unit_nr
1422  LOGICAL, INTENT(in), OPTIONAL :: hide_root, hide_defaults
1423 
1424  INTEGER, PARAMETER :: incr = 2
1425 
1426  CHARACTER(len=default_string_length) :: myfmt
1427  INTEGER :: i_rep_s, ik, isec, ival, nr, nval
1428  INTEGER, SAVE :: indent = 1
1429  LOGICAL :: defaultsection, explicit, &
1430  my_hide_defaults, my_hide_root
1431  TYPE(cp_sll_val_type), POINTER :: new_pos, vals
1432  TYPE(keyword_type), POINTER :: keyword
1433  TYPE(section_type), POINTER :: section
1434  TYPE(section_vals_type), POINTER :: sval
1435  TYPE(val_type), POINTER :: val
1436 
1437  my_hide_root = .false.
1438  my_hide_defaults = .true.
1439  IF (PRESENT(hide_root)) my_hide_root = hide_root
1440  IF (PRESENT(hide_defaults)) my_hide_defaults = hide_defaults
1441 
1442  cpassert(section_vals%ref_count > 0)
1443  IF (unit_nr > 0) THEN
1444  CALL section_vals_get(section_vals, explicit=explicit, n_repetition=nr, section=section)
1445  IF (explicit .OR. (.NOT. my_hide_defaults)) THEN
1446  DO i_rep_s = 1, nr
1447  IF (.NOT. my_hide_root) THEN
1448  WRITE (unit=myfmt, fmt="(I0,A1)") indent, "X"
1449  IF (ASSOCIATED(section%keywords(-1)%keyword)) THEN
1450  WRITE (unit=unit_nr, fmt="("//trim(myfmt)//",A)", advance="NO") &
1451  default_section_character//trim(adjustl(section%name))
1452  ELSE
1453  WRITE (unit=unit_nr, fmt="("//trim(myfmt)//",A)") &
1454  default_section_character//trim(adjustl(section%name))
1455  END IF
1456  END IF
1457  defaultsection = (SIZE(section_vals%values, 2) == 0)
1458  IF (.NOT. defaultsection) THEN
1459  IF (.NOT. my_hide_root) indent = indent + incr
1460  WRITE (unit=myfmt, fmt="(I0,A1)") indent, "X"
1461  DO ik = -1, section%n_keywords
1462  keyword => section%keywords(ik)%keyword
1463  IF (ASSOCIATED(keyword)) THEN
1464  IF (keyword%type_of_var /= no_t .AND. keyword%names(1) (1:2) /= "__") THEN
1465  CALL section_vals_val_get(section_vals, keyword%names(1), &
1466  i_rep_s, n_rep_val=nval)
1467  IF (i_rep_s <= SIZE(section_vals%values, 2)) THEN
1468  ! Section was parsed
1469  vals => section_vals%values(ik, i_rep_s)%list
1470  DO ival = 1, nval
1471  IF (ival == 1) THEN
1472  new_pos => vals
1473  ELSE
1474  new_pos => new_pos%rest
1475  END IF
1476  IF (.NOT. ASSOCIATED(new_pos)) THEN
1477  ! this keyword was not parsed
1478  IF (ASSOCIATED(keyword%default_value)) THEN
1479  val => keyword%default_value
1480  IF (my_hide_defaults) cycle
1481  END IF
1482  ELSE
1483  val => new_pos%first_el
1484  END IF
1485  IF (keyword%names(1) /= '_DEFAULT_KEYWORD_' .AND. &
1486  keyword%names(1) /= '_SECTION_PARAMETERS_') THEN
1487  WRITE (unit=unit_nr, fmt="("//trim(myfmt)//",A)", advance="NO") &
1488  trim(keyword%names(1))
1489  ELSE IF (keyword%names(1) == '_DEFAULT_KEYWORD_' .AND. &
1490  keyword%type_of_var /= lchar_t) THEN
1491  WRITE (unit=unit_nr, fmt="("//trim(myfmt)//")", advance="NO")
1492  END IF
1493  CALL val_write(val, unit_nr=unit_nr, unit=keyword%unit, fmt=myfmt)
1494  END DO
1495  ELSE IF (ASSOCIATED(keyword%default_value)) THEN
1496  ! Section was not parsed but default for the keywords may exist
1497  IF (my_hide_defaults) cycle
1498  val => keyword%default_value
1499  IF (keyword%names(1) /= '_DEFAULT_KEYWORD_' .AND. &
1500  keyword%names(1) /= '_SECTION_PARAMETERS_') THEN
1501  WRITE (unit=unit_nr, fmt="("//trim(myfmt)//",A)", advance="NO") &
1502  trim(keyword%names(1))
1503  ELSE IF (keyword%names(1) == '_DEFAULT_KEYWORD_' .AND. &
1504  keyword%type_of_var /= lchar_t) THEN
1505  WRITE (unit=unit_nr, fmt="("//trim(myfmt)//")", advance="NO")
1506  END IF
1507  CALL val_write(val, unit_nr=unit_nr, unit=keyword%unit, fmt=myfmt)
1508  END IF
1509  END IF
1510  END IF
1511  END DO
1512  IF (ASSOCIATED(section_vals%subs_vals)) THEN
1513  DO isec = 1, SIZE(section_vals%subs_vals, 1)
1514  sval => section_vals%subs_vals(isec, i_rep_s)%section_vals
1515  IF (ASSOCIATED(sval)) THEN
1516  CALL section_vals_write(sval, unit_nr=unit_nr, hide_defaults=hide_defaults)
1517  END IF
1518  END DO
1519  END IF
1520  END IF
1521  IF (.NOT. my_hide_root) THEN
1522  indent = indent - incr
1523  WRITE (unit=myfmt, fmt="(I0,A1)") indent, "X"
1524  WRITE (unit=unit_nr, fmt="("//trim(myfmt)//",A)") &
1525  default_section_character//"END "//trim(adjustl(section%name))
1526  END IF
1527  END DO
1528  END IF
1529  END IF
1530 
1531  END SUBROUTINE section_vals_write
1532 
1533 ! **************************************************************************************************
1534 !> \brief writes the values in the given section in xml
1535 !> \param section ...
1536 !> \param level ...
1537 !> \param unit_number ...
1538 ! **************************************************************************************************
1539  RECURSIVE SUBROUTINE write_section_xml(section, level, unit_number)
1540 
1541  TYPE(section_type), POINTER :: section
1542  INTEGER, INTENT(IN) :: level, unit_number
1543 
1544  CHARACTER(LEN=3) :: repeats
1545  CHARACTER(LEN=8) :: short_string
1546  INTEGER :: i, l0, l1, l2
1547 
1548  IF (ASSOCIATED(section)) THEN
1549 
1550  cpassert(section%ref_count > 0)
1551 
1552  ! Indentation for current level, next level, etc.
1553 
1554  l0 = level
1555  l1 = level + 1
1556  l2 = level + 2
1557 
1558  IF (section%repeats) THEN
1559  repeats = "yes"
1560  ELSE
1561  repeats = "no "
1562  END IF
1563 
1564  WRITE (unit=unit_number, fmt="(A)") &
1565  repeat(" ", l0)//"<SECTION repeats="""//trim(repeats)//""">", &
1566  repeat(" ", l1)//"<NAME>"//trim(section%name)//"</NAME>", &
1567  repeat(" ", l1)//"<DESCRIPTION>"// &
1568  trim(substitute_special_xml_tokens(a2s(section%description))) &
1569  //"</DESCRIPTION>"
1570 
1571  IF (ASSOCIATED(section%citations)) THEN
1572  DO i = 1, SIZE(section%citations, 1)
1573  short_string = ""
1574  WRITE (unit=short_string, fmt="(I8)") section%citations(i)
1575  WRITE (unit=unit_number, fmt="(A)") &
1576  repeat(" ", l1)//"<REFERENCE>", &
1577  repeat(" ", l2)//"<NAME>"//trim(get_citation_key(section%citations(i)))//"</NAME>", &
1578  repeat(" ", l2)//"<NUMBER>"//trim(adjustl(short_string))//"</NUMBER>", &
1579  repeat(" ", l1)//"</REFERENCE>"
1580  END DO
1581  END IF
1582 
1583  WRITE (unit=unit_number, fmt="(A)") &
1584  repeat(" ", l1)//"<LOCATION>"//trim(section%location)//"</LOCATION>"
1585 
1586  DO i = -1, section%n_keywords
1587  IF (ASSOCIATED(section%keywords(i)%keyword)) THEN
1588  CALL write_keyword_xml(section%keywords(i)%keyword, l1, unit_number)
1589  END IF
1590  END DO
1591 
1592  DO i = 1, section%n_subsections
1593  CALL write_section_xml(section%subsections(i)%section, l1, unit_number)
1594  END DO
1595 
1596  WRITE (unit=unit_number, fmt="(A)") repeat(" ", l0)//"</SECTION>"
1597 
1598  END IF
1599 
1600  END SUBROUTINE write_section_xml
1601 
1602 ! **************************************************************************************************
1603 !> \brief ...
1604 !> \param section ...
1605 !> \param section_name ...
1606 !> \param unknown_string ...
1607 !> \param location_string ...
1608 !> \param matching_rank ...
1609 !> \param matching_string ...
1610 !> \param bonus ...
1611 ! **************************************************************************************************
1612  RECURSIVE SUBROUTINE section_typo_match(section, section_name, unknown_string, location_string, &
1613  matching_rank, matching_string, bonus)
1614 
1615  TYPE(section_type), INTENT(IN), POINTER :: section
1616  CHARACTER(LEN=*) :: section_name, unknown_string, &
1617  location_string
1618  INTEGER, DIMENSION(:), INTENT(INOUT) :: matching_rank
1619  CHARACTER(LEN=*), DIMENSION(:), INTENT(INOUT) :: matching_string
1620  INTEGER, INTENT(IN) :: bonus
1621 
1622  CHARACTER(LEN=LEN(matching_string(1))) :: line
1623  INTEGER :: i, imatch, imax, irank, newbonus
1624 
1625  IF (ASSOCIATED(section)) THEN
1626  cpassert(section%ref_count > 0)
1627  imatch = typo_match(trim(section%name), trim(unknown_string))
1628  IF (imatch > 0) THEN
1629  imatch = imatch + bonus
1630  WRITE (unit=line, fmt='(T2,A)') &
1631  " subsection "//trim(adjustl(section%name))// &
1632  " in section "//trim(adjustl(location_string))
1633  imax = SIZE(matching_rank, 1)
1634  irank = imax + 1
1635  DO i = imax, 1, -1
1636  IF (imatch > matching_rank(i)) irank = i
1637  END DO
1638  IF (irank <= imax) THEN
1639  matching_rank(irank + 1:imax) = matching_rank(irank:imax - 1)
1640  matching_string(irank + 1:imax) = matching_string(irank:imax - 1)
1641  matching_rank(irank) = imatch
1642  matching_string(irank) = line
1643  END IF
1644  END IF
1645 
1646  IF (section_name == section%name) THEN
1647  newbonus = 10
1648  ELSE
1649  newbonus = 0
1650  END IF
1651 
1652  DO i = -1, section%n_keywords
1653  IF (ASSOCIATED(section%keywords(i)%keyword)) THEN
1654  CALL keyword_typo_match(section%keywords(i)%keyword, unknown_string, location_string// &
1655  "%"//trim(section%name), matching_rank, matching_string, newbonus)
1656  END IF
1657  END DO
1658 
1659  DO i = 1, section%n_subsections
1660  CALL section_typo_match(section%subsections(i)%section, section_name, unknown_string, &
1661  location_string//"%"//trim(section%name), matching_rank, matching_string, newbonus)
1662  END DO
1663 
1664  END IF
1665 
1666  END SUBROUTINE section_typo_match
1667 
1668 ! **************************************************************************************************
1669 !> \brief replaces of the requested subsection with the one given
1670 !> \param section_vals the root section
1671 !> \param subsection_name the name of the subsection to replace
1672 !> \param new_section_vals the new section_vals to use
1673 !> \param i_rep_section index of the repetition of section_vals of which
1674 !> you want to replace the subsection (defaults to 1)
1675 !> \author fawzi
1676 ! **************************************************************************************************
1677  SUBROUTINE section_vals_set_subs_vals(section_vals, subsection_name, &
1678  new_section_vals, i_rep_section)
1679  TYPE(section_vals_type), POINTER :: section_vals
1680  CHARACTER(len=*), INTENT(in) :: subsection_name
1681  TYPE(section_vals_type), POINTER :: new_section_vals
1682  INTEGER, INTENT(in), OPTIONAL :: i_rep_section
1683 
1684  INTEGER :: irep, isection, len_key, my_index, &
1685  tmp_index
1686  TYPE(section_vals_type), POINTER :: s_vals
1687 
1688  cpassert(ASSOCIATED(section_vals))
1689  cpassert(section_vals%ref_count > 0)
1690  cpassert(ASSOCIATED(new_section_vals))
1691  cpassert(new_section_vals%ref_count > 0)
1692 
1693  irep = 1
1694  IF (PRESENT(i_rep_section)) irep = i_rep_section
1695 
1696  my_index = index(subsection_name, '%') + 1
1697  len_key = len_trim(subsection_name)
1698  IF (my_index > 1) THEN
1699  DO
1700  tmp_index = index(subsection_name(my_index:len_key), "%")
1701  IF (tmp_index <= 0) EXIT
1702  my_index = my_index + tmp_index
1703  END DO
1704  s_vals => section_vals_get_subs_vals(section_vals, subsection_name(1:my_index - 2))
1705  ELSE
1706  s_vals => section_vals
1707  END IF
1708 
1709  cpassert(irep <= SIZE(s_vals%subs_vals, 2))
1710 
1711  isection = section_get_subsection_index(s_vals%section, subsection_name(my_index:len_trim(subsection_name)))
1712  IF (isection <= 0) &
1713  CALL cp_abort(__location__, &
1714  "could not find subsection "//subsection_name(my_index:len_trim(subsection_name))//" in section "// &
1715  trim(section_vals%section%name)//" at ")
1716  CALL section_vals_retain(new_section_vals)
1717  CALL section_vals_release(s_vals%subs_vals(isection, irep)%section_vals)
1718  s_vals%subs_vals(isection, irep)%section_vals => new_section_vals
1719 
1720  END SUBROUTINE section_vals_set_subs_vals
1721 
1722 ! **************************************************************************************************
1723 !> \brief creates a deep copy from section_vals_in to section_vals_out
1724 !> \param section_vals_in the section_vals to copy
1725 !> \param section_vals_out the section_vals to create
1726 !> \param i_rep_start ...
1727 !> \param i_rep_end ...
1728 !> \author fawzi
1729 ! **************************************************************************************************
1730  SUBROUTINE section_vals_duplicate(section_vals_in, section_vals_out, &
1731  i_rep_start, i_rep_end)
1732  TYPE(section_vals_type), POINTER :: section_vals_in, section_vals_out
1733  INTEGER, INTENT(IN), OPTIONAL :: i_rep_start, i_rep_end
1734 
1735  cpassert(ASSOCIATED(section_vals_in))
1736  cpassert(.NOT. ASSOCIATED(section_vals_out))
1737  CALL section_vals_create(section_vals_out, section_vals_in%section)
1738  CALL section_vals_copy(section_vals_in, section_vals_out, i_rep_start, i_rep_end)
1739  END SUBROUTINE section_vals_duplicate
1740 
1741 ! **************************************************************************************************
1742 !> \brief deep copy from section_vals_in to section_vals_out
1743 !> \param section_vals_in the section_vals to copy
1744 !> \param section_vals_out the section_vals where to copy
1745 !> \param i_rep_low ...
1746 !> \param i_rep_high ...
1747 !> \author fawzi
1748 !> \note
1749 !> private, only works with a newly initialized section_vals_out
1750 ! **************************************************************************************************
1751  RECURSIVE SUBROUTINE section_vals_copy(section_vals_in, section_vals_out, &
1752  i_rep_low, i_rep_high)
1753  TYPE(section_vals_type), POINTER :: section_vals_in, section_vals_out
1754  INTEGER, INTENT(IN), OPTIONAL :: i_rep_low, i_rep_high
1755 
1756  INTEGER :: iend, irep, isec, istart, ival
1757  TYPE(cp_sll_val_type), POINTER :: v1, v2
1758  TYPE(val_type), POINTER :: el
1759 
1760  NULLIFY (v2, el)
1761 
1762  cpassert(ASSOCIATED(section_vals_in))
1763  cpassert(ASSOCIATED(section_vals_out))
1764  ! IF(.NOT. ASSOCIATED(section_vals_in%section, section_vals_out%section))&
1765  ! CPABORT("")
1766 
1767  istart = 1
1768  iend = SIZE(section_vals_in%values, 2)
1769  IF (PRESENT(i_rep_low)) istart = i_rep_low
1770  IF (PRESENT(i_rep_high)) iend = i_rep_high
1771  DO irep = istart, iend
1772  CALL section_vals_add_values(section_vals_out)
1773  DO ival = lbound(section_vals_in%values, 1), ubound(section_vals_in%values, 1)
1774  v1 => section_vals_in%values(ival, irep)%list
1775  IF (ASSOCIATED(v1)) THEN
1776  CALL val_duplicate(v1%first_el, el)
1777  CALL cp_sll_val_create(v2, el)
1778  NULLIFY (el)
1779  section_vals_out%values(ival, irep - istart + 1)%list => v2
1780  DO
1781  IF (.NOT. ASSOCIATED(v1%rest)) EXIT
1782  v1 => v1%rest
1783  CALL val_duplicate(v1%first_el, el)
1784  CALL cp_sll_val_create(v2%rest, first_el=el)
1785  NULLIFY (el)
1786  v2 => v2%rest
1787  END DO
1788  END IF
1789  END DO
1790  END DO
1791  IF (.NOT. PRESENT(i_rep_low) .AND. (.NOT. PRESENT(i_rep_high))) THEN
1792  IF (.NOT. (SIZE(section_vals_in%values, 2) == SIZE(section_vals_out%values, 2))) &
1793  cpabort("")
1794  IF (.NOT. (SIZE(section_vals_in%subs_vals, 2) == SIZE(section_vals_out%subs_vals, 2))) &
1795  cpabort("")
1796  END IF
1797  iend = SIZE(section_vals_in%subs_vals, 2)
1798  IF (PRESENT(i_rep_high)) iend = i_rep_high
1799  DO irep = istart, iend
1800  DO isec = 1, SIZE(section_vals_in%subs_vals, 1)
1801  CALL section_vals_copy(section_vals_in%subs_vals(isec, irep)%section_vals, &
1802  section_vals_out%subs_vals(isec, irep - istart + 1)%section_vals)
1803  END DO
1804  END DO
1805 
1806  END SUBROUTINE section_vals_copy
1807 
1808 END MODULE input_section_types
static int imax(int x, int y)
Returns the larger of two given integer (missing from the C standard)
type(cp_sll_val_type) function, pointer, public cp_sll_val_get_rest(sll, iter)
returns the rest of the list
integer function, public cp_sll_val_get_length(sll)
returns the length of the list
logical function, public cp_sll_val_next(iterator, el_att)
returns true if the actual element is valid (i.e. iterator ont at end) moves the iterator to the next...
subroutine, public cp_sll_val_rm_el_at(sll, index)
removes the element at the given index
subroutine, public cp_sll_val_create(sll, first_el, rest)
allocates and initializes a single linked list
subroutine, public cp_sll_val_set_el_at(sll, index, value)
sets the element at the given index
subroutine, public cp_sll_val_insert_el_at(sll, el, index)
inserts the element at the given index
type(val_type) function, pointer, public cp_sll_val_get_el_at(sll, index)
returns the element at the given index
subroutine, public cp_sll_val_dealloc(sll)
deallocates the singly linked list starting at sll. Does not work if loops are present!
various routines to log and control the output. The idea is that decisions about where to log should ...
Utility routines to read data from files. Kept as close as possible to the old parser because.
character(len=1), parameter, public default_section_character
represents keywords in an input
subroutine, public keyword_retain(keyword)
retains the given keyword (see doc/ReferenceCounting.html)
subroutine, public keyword_describe(keyword, unit_nr, level)
writes out a description of the keyword
subroutine, public write_keyword_xml(keyword, level, unit_number)
Prints a description of a keyword in XML format.
subroutine, public keyword_release(keyword)
releases the given keyword (see doc/ReferenceCounting.html)
subroutine, public keyword_typo_match(keyword, unknown_string, location_string, matching_rank, matching_string, bonus)
...
objects that represent the structure of input sections and the data contained in an input section
subroutine, public section_vals_val_unset(section_vals, keyword_name, i_rep_section, i_rep_val)
unsets (removes) the requested value (if it is a keyword repetitions removes the repetition,...
real(kind=dp) function, public section_get_rval(section_vals, keyword_name)
...
recursive subroutine, public section_typo_match(section, section_name, unknown_string, location_string, matching_rank, matching_string, bonus)
...
type(section_type) function, pointer, public section_get_subsection(section, subsection_name)
returns the requested subsection
recursive subroutine, public write_section_xml(section, level, unit_number)
writes the values in the given section in xml
recursive subroutine, public section_vals_create(section_vals, section)
creates a object where to store the values of a section
subroutine, public section_create(section, location, name, description, n_keywords, n_subsections, repeats, citations)
creates a list of keywords
subroutine, public section_vals_val_set(section_vals, keyword_name, i_rep_section, i_rep_val, val, l_val, i_val, r_val, c_val, l_vals_ptr, i_vals_ptr, r_vals_ptr, c_vals_ptr)
sets the requested value
integer function, dimension(:), pointer, public section_get_ivals(section_vals, keyword_name)
...
type(section_vals_type) function, pointer, public section_vals_get_subs_vals2(section_vals, i_section, i_rep_section)
returns the values of the n-th non default subsection (null if no such section exists (not so many no...
subroutine, public section_add_keyword(section, keyword)
adds a keyword to the given section
type(section_type), pointer, save, public typo_match_section
integer function, public section_get_keyword_index(section, keyword_name)
returns the index of the requested keyword (or -2 if not found)
subroutine, public section_vals_remove_values(section_vals)
removes the values of a repetition of the section
subroutine, public section_add_subsection(section, subsection)
adds a subsection to the given section
integer function, public section_get_ival(section_vals, keyword_name)
...
subroutine, public section_vals_list_get(section_vals, keyword_name, i_rep_section, list)
returns the requested list
integer, dimension(n_typo_matches), public typo_matching_rank
subroutine, public section_vals_retain(section_vals)
retains the given section values (see doc/ReferenceCounting.html)
recursive type(section_vals_type) function, pointer, public section_vals_get_subs_vals(section_vals, subsection_name, i_rep_section, can_return_null)
returns the values of the requested subsection
recursive subroutine, public section_release(section)
releases the given keyword list (see doc/ReferenceCounting.html)
recursive type(keyword_type) function, pointer, public section_get_keyword(section, keyword_name)
returns the requested keyword
recursive subroutine, public section_vals_write(section_vals, unit_nr, hide_root, hide_defaults)
writes the values in the given section in a way that is suitable to the automatic parsing
subroutine, public section_vals_get(section_vals, ref_count, n_repetition, n_subs_vals_rep, section, explicit)
returns various attributes about the section_vals
recursive subroutine, public section_describe(section, unit_nr, level, hide_root, recurse)
prints a description of the given section
type(section_vals_type) function, pointer, public section_vals_get_subs_vals3(section_vals, subsection_name, i_rep_section)
returns the values of the n-th non default subsection (null if no such section exists (not so many no...
subroutine, public section_vals_set_subs_vals(section_vals, subsection_name, new_section_vals, i_rep_section)
replaces of the requested subsection with the one given
integer function, public section_get_subsection_index(section, subsection_name)
returns the index of requested subsection (-1 if not found)
subroutine, public section_vals_duplicate(section_vals_in, section_vals_out, i_rep_start, i_rep_end)
creates a deep copy from section_vals_in to section_vals_out
character(len=default_string_length *5), dimension(n_typo_matches), public typo_matching_line
subroutine, public section_vals_val_get(section_vals, keyword_name, i_rep_section, i_rep_val, n_rep_val, val, l_val, i_val, r_val, c_val, l_vals, i_vals, r_vals, c_vals, explicit)
returns the requested value
subroutine, public section_vals_add_values(section_vals)
adds the place to store the values of a repetition of the section
recursive subroutine, public section_vals_release(section_vals)
releases the given object
logical function, public section_get_lval(section_vals, keyword_name)
...
a wrapper for basic fortran types.
integer, parameter, public lchar_t
subroutine, public val_duplicate(val_in, val_out)
creates a copy of the given value
subroutine, public val_write(val, unit_nr, unit, unit_str, fmt)
writes out the values stored in the val
subroutine, public val_get(val, has_l, has_i, has_r, has_lc, has_c, l_val, l_vals, i_val, i_vals, r_val, r_vals, c_val, c_vals, len_c, type_of_var, enum)
returns the stored values
subroutine, public val_create(val, l_val, l_vals, l_vals_ptr, i_val, i_vals, i_vals_ptr, r_val, r_vals, r_vals_ptr, c_val, c_vals, c_vals_ptr, lc_val, lc_vals, lc_vals_ptr, enum)
creates a keyword value
subroutine, public val_release(val)
releases the given val
integer, parameter, public no_t
Defines the basic variable types.
Definition: kinds.F:23
integer, parameter, public dp
Definition: kinds.F:34
integer, parameter, public default_string_length
Definition: kinds.F:57
integer, parameter, public default_path_length
Definition: kinds.F:58
An array-based list which grows on demand. When the internal array is full, a new array of twice the ...
Definition: list.F:24
Perform an abnormal program termination.
subroutine, public print_message(message, output_unit, declev, before, after)
Perform a basic blocking of the text in message and print it optionally decorated with a frame of sta...
provides a uniform framework to add references to CP2K cite and output these
pure character(len=default_string_length) function, public get_citation_key(key)
...
Utilities for string manipulations.
elemental integer function, public typo_match(string, typo_string)
returns a non-zero positive value if typo_string equals string apart from a few typos....
pure character(len=size(array)) function, public a2s(array)
Converts a character-array into a string.
character(len=2 *len(inp_string)) function, public substitute_special_xml_tokens(inp_string)
Substitutes the five predefined XML entities: &, <, >, ', and ".
elemental subroutine, public uppercase(string)
Convert all lower case characters in a string to upper case.