Soil Water Balance (SWB2)
Loading...
Searching...
No Matches
dictionary.F90
Go to the documentation of this file.
2
3 use iso_c_binding, only : c_int, c_float, c_double, c_bool
5 use exceptions
6 use logfiles
7 use fstring
9 use exceptions
10 implicit none
11
12 private
13
14 type, public :: dict_entry_t
15
16 character (len=:), allocatable :: key
17 character (len=:), allocatable :: secondary_key
18
19 type (fstring_list_t) :: sl
20 type (dict_entry_t), pointer :: previous => null()
21 type (dict_entry_t), pointer :: next => null()
22
23 contains
24
25 procedure :: add_key_sub
26 generic :: add_key => add_key_sub
27
28 procedure :: add_string_sub
29 procedure :: add_integer_sub
30 procedure :: add_float_sub
31 procedure :: add_double_sub
32 procedure :: add_logical_sub
33 generic :: add_value => add_string_sub, &
38 end type dict_entry_t
39
40
41 type, public :: dict_t
42
43 type (dict_entry_t), pointer :: first => null()
44 type (dict_entry_t), pointer :: last => null()
45 type (dict_entry_t), pointer :: current => null()
46 integer (c_int) :: count = 0
47
48 contains
49
50 procedure, private :: get_entry_by_key_fn
51 procedure, private :: get_entry_by_index_fn
52 generic :: get_entry => get_entry_by_key_fn, &
54
55 procedure, private :: get_next_entry_by_key_fn
56 procedure, private :: get_next_entry_fn
57 generic :: get_next_entry => get_next_entry_by_key_fn, &
59
60 procedure, private :: add_entry_to_dict_sub
61 generic :: add_entry => add_entry_to_dict_sub
62
63 procedure, private :: key_name_already_in_use_fn
64 generic :: key_already_in_use => key_name_already_in_use_fn
65
66 procedure :: find_dict_entry_fn
67 generic :: find_dict_entry => find_dict_entry_fn
68
69 procedure, private :: delete_entry_by_key_sub
70 generic :: delete_entry => delete_entry_by_key_sub
71
73 generic :: print_all => print_all_dictionary_entries_sub
74
75 procedure, private :: grep_dictionary_key_names_fn
76 generic :: grep_keys => grep_dictionary_key_names_fn
77
78 procedure, public :: get_value => get_value_as_string_sub
79
80 procedure, private :: get_values_as_int_sub
81 procedure, private :: get_values_as_float_sub
82 procedure, private :: get_values_as_logical_sub
83 procedure, private :: get_values_as_string_list_sub
88 generic :: get_values => get_values_as_int_sub, &
96
97 end type dict_t
98
99 ! CF = "Control File"; this dictionary will be populated elsewhere with all of the
100 ! directives found in the SWB control file.
101 type (dict_t), public :: cf_dict
102 type (dict_entry_t), public, pointer :: cf_entry
103
104contains
105
106 !!
107 !! This section contains methods bound to the DICT_ENTRY_T class
108 !!
109
110 subroutine add_key_sub(this, sKey)
111
112 class(dict_entry_t) :: this
113 character (len=*), intent(in) :: sKey
114
115 this%key = trim(skey)
116
117 end subroutine add_key_sub
118
119!--------------------------------------------------------------------------------------------------
120
121 subroutine add_string_sub(this, sValue)
122
123 class(dict_entry_t) :: this
124 character (len=*), intent(in) :: sValue
125
126 call this%sl%append(svalue)
127
128 end subroutine add_string_sub
129
130!--------------------------------------------------------------------------------------------------
131
132 subroutine add_float_sub(this, fValue)
133
134 class(dict_entry_t) :: this
135 real (c_float), intent(in) :: fValue
136
137 call this%sl%append( ascharacter( fvalue ) )
138
139 end subroutine add_float_sub
140
141!--------------------------------------------------------------------------------------------------
142
143 subroutine add_integer_sub(this, iValue)
144
145 class(dict_entry_t) :: this
146 integer (c_int), intent(in) :: iValue
147
148 call this%sl%append( ascharacter( ivalue ) )
149
150 end subroutine add_integer_sub
151
152!--------------------------------------------------------------------------------------------------
153
154 subroutine add_double_sub(this, dValue)
155
156 class(dict_entry_t) :: this
157 real (c_double), intent(in) :: dValue
158
159 call this%sl%append( ascharacter( dvalue ) )
160
161 end subroutine add_double_sub
162
163!--------------------------------------------------------------------------------------------------
164
165 subroutine add_logical_sub(this, lValue)
166
167 class(dict_entry_t) :: this
168 logical (c_bool), intent(in) :: lValue
169
170 call this%sl%append( ascharacter( lvalue ) )
171
172 end subroutine add_logical_sub
173
174!--------------------------------------------------------------------------------------------------
175
176 !!
177 !! The methods in the section below are bound to the DICT_T type, which is essentially a
178 !! linked list of DICT_ENTRY_T objects
179 !!
180
181 function get_entry_by_key_fn(this, sKey) result( pDict )
182
183 class(dict_t) :: this
184 character (len=*), intent(in) :: skey
185 type (dict_entry_t), pointer :: pdict
186
187 this%current => this%first
188
189 do while ( associated( this%current ) )
190
191 if ( this%current%key .strapprox. skey ) exit
192
193 this%current => this%current%next
194
195 enddo
196
197 if (.not. associated( this%current ) ) &
198 call warn( smessage="Failed to find a dictionary entry with a key value of "//dquote(skey), &
199 iloglevel=log_debug, &
200 lecho=false )
201
202 pdict => this%current
203
204 end function get_entry_by_key_fn
205
206!--------------------------------------------------------------------------------------------------
207
208 function get_entry_by_index_fn(this, iIndex) result( pDict )
209
210 class(dict_t) :: this
211 integer (c_int), intent(in) :: iindex
212 type (dict_entry_t), pointer :: pdict
213
214 ! [ LOCALS ]
215 integer (c_int) :: icurrentindex
216
217 icurrentindex = 1
218
219 this%current => this%first
220
221 do
222
223 if ( .not. associated( this%current ) ) exit
224
225 if ( icurrentindex == iindex ) exit
226
227 this%current => this%current%next
228
229 icurrentindex = icurrentindex + 1
230
231 enddo
232
233 if (.not. associated( this%current ) ) &
234 call warn( smessage="Failed to find a dictionary entry with a index value of " &
235 //ascharacter(iindex), &
236 iloglevel=log_debug, &
237 lecho=false )
238
239 pdict => this%current
240
241 end function get_entry_by_index_fn
242
243!--------------------------------------------------------------------------------------------------
244
245 function get_next_entry_by_key_fn(this, sKey) result( pDict )
246
247 class(dict_t) :: this
248 character (len=*), intent(in) :: skey
249 type (dict_entry_t), pointer :: pdict
250
251 pdict => null()
252
253 ! if "current" location is not null, it will point to the location of the
254 ! last key value found. move forward by one before examining the next key...
255 if (associated( this%current) ) pdict => this%current%next
256
257 do while ( associated( pdict ) )
258
259 if ( pdict%key .strequal. skey ) exit
260
261 pdict => pdict%next
262 this%current => pdict
263
264 enddo
265
266 if (.not. associated( pdict ) ) &
267 call warn( smessage="Failed to find another dictionary entry with a key value of "//dquote(skey), &
268 iloglevel=log_debug, &
269 lecho=false )
270
271 end function get_next_entry_by_key_fn
272
273!--------------------------------------------------------------------------------------------------
274
275 function get_next_entry_fn(this) result( pDict )
276
277 class(dict_t) :: this
278 type (dict_entry_t), pointer :: pdict
279
280 pdict => null()
281
282 ! if "current" location is not null, it will point to the location of the
283 ! last key value found. move forward by one before examining the next key...
284 if (associated( this%current) ) then
285 pdict => this%current%next
286 this%current => this%current%next
287 endif
288
289 if (.not. associated( pdict ) ) &
290 call warn( smessage="Reached end of dictionary.", &
291 iloglevel=log_debug, &
292 lecho=false )
293
294 end function get_next_entry_fn
295
296!--------------------------------------------------------------------------------------------------
297
298 function grep_dictionary_key_names_fn(this, sKey) result( slString )
299
300 class(dict_t) :: this
301 character (len=*), intent(in) :: skey
302 type (fstring_list_t) :: slstring
303
304 ! [ LOCALS ]
305
306 this%current => this%first
307
308 do while ( associated(this%current ) )
309
310 if ( this%current%key .containssimilar. skey ) &
311 call slstring%append(this%current%key)
312
313 this%current => this%current%next
314
315 enddo
316
317 if ( slstring%get(1) == '<NA>' ) &
318 call warn(smessage="Failed to find a dictionary entry associated with a key value of " &
319 //dquote(skey)//".", smodule=__file__, iline=__line__, iloglevel=log_debug, lecho=false )
320
322
323!--------------------------------------------------------------------------------------------------
324
325function key_name_already_in_use_fn(this, sKey) result( in_use )
326
327 class(dict_t) :: this
328 character (len=*), intent(in) :: skey
329 logical (c_bool) :: in_use
330
331 ! [ LOCALS ]
332 integer (c_int) :: icount
333
334 this%current => this%first
335 icount = 0
336
337 do while ( associated(this%current ) )
338
339 !iIndex = index(string=this%current%key, substring=asUppercase(sKey) )
340
341 !if ( iIndex > 0 ) iCount = iCount + 1
342
343 if ( this%current%key .strapprox. skey ) icount = icount + 1
344
345 this%current => this%current%next
346
347 enddo
348
349 if ( icount == 0 ) then
350
351 in_use = false
352
353 else
354
355 in_use = true
356
357 endif
358
360
361
362!--------------------------------------------------------------------------------------------------
363
364function find_dict_entry_fn(this, sSearchKey) result( pDict )
365
366 class(dict_t) :: this
367 character (len=*), intent(in) :: ssearchkey
368 type (dict_entry_t), pointer :: pdict
369
370 ! [ LOCALS ]
371
372 pdict => null()
373 this%current => this%first
374
375 do while ( associated(this%current ) )
376
377 !iIndex = index(string=this%current%key, substring=asUppercase(sSearchKey) )
378
379 !if ( iIndex > 0 ) then
380
381 if (this%current%key .strapprox. ssearchkey ) then
382
383 pdict => this%current
384 exit
385
386 endif
387
388 this%current => this%current%next
389
390 enddo
391
392end function find_dict_entry_fn
393
394!--------------------------------------------------------------------------------------------------
395
396 subroutine add_entry_to_dict_sub(this, dict_entry)
397
398 class(dict_t) :: this
399 type (DICT_ENTRY_T), pointer :: dict_entry
400
401 type (DICT_ENTRY_T), pointer :: temp_dict_entry
402 integer (c_int) :: iIndex
403
404 temp_dict_entry => null()
405
406 if ( associated(dict_entry) ) then
407
408 temp_dict_entry => this%find_dict_entry( dict_entry%key )
409
410 ! the dictionary already contains a dictionary entry with this
411 ! key value; append the values to the existing entry
412 if ( associated( temp_dict_entry ) ) then
413
414 do iindex=1, dict_entry%sl%count
415
416 call temp_dict_entry%sl%append( dict_entry%sl%get( iindex ) )
417
418 enddo
419
420 temp_dict_entry => null()
421
422 else
423
424 this%count = this%count + 1
425
426 if ( associated( this%last) ) then
427
428 ! dictionary has at least one entry
429
430 dict_entry%previous => this%last
431 dict_entry%next => null()
432 this%last%next => dict_entry
433 this%last => dict_entry
434 this%current => dict_entry
435
436 else ! this is the first dictionary entry
437
438 this%first => dict_entry
439 this%last => dict_entry
440 this%current => dict_entry
441 dict_entry%previous => null()
442 dict_entry%next => null()
443
444 endif
445
446 endif
447
448 else
449
450 call warn( smessage="Internal programming error: dictionary entry is null", &
451 smodule=__file__, iline=__line__ )
452
453 endif
454
455 end subroutine add_entry_to_dict_sub
456
457!--------------------------------------------------------------------------------------------------
458
459 subroutine delete_entry_by_key_sub(this, sKey)
460
461 class(dict_t) :: this
462 character (len=*), intent(in) :: sKey
463
464 ! [ LOCALS ]
465 type (DICT_ENTRY_T), pointer :: pTarget
466 type (DICT_ENTRY_T), pointer :: pTemp
467
468 ptarget => this%get_entry(skey)
469
470 if ( associated( ptarget ) ) then
471
472 ! first remove object from linked list
473 ptemp => ptarget%previous
474
475 if (associated( ptemp) ) then
476 ! if pTemp is unassociated, it means we are at the head of the list
477 ptemp%next => ptarget%next
478 ptarget%next%previous => ptemp
479
480 else
481
482 ptemp => ptarget%next
483 this%first => ptemp
484
485 endif
486
487 ! set "current" pointer to entry that was just before the now-deleted entry
488 this%current => ptemp
489
490 call ptarget%sl%clear()
491
492 endif
493
494 end subroutine delete_entry_by_key_sub
495
496!--------------------------------------------------------------------------------------------------
497
498 subroutine get_values_as_int_sub(this, sKey, iValues, is_fatal )
499
500 class(dict_t) :: this
501 character (len=*) :: sKey
502 integer (c_int), allocatable, intent(out) :: iValues(:)
503 logical (c_bool), optional :: is_fatal
504
505 ! [ LOCALS ]
506 type (DICT_ENTRY_T), pointer :: pTarget
507 integer (c_int) :: iStat
508 logical (c_bool) :: is_fatal_l
509 logical (c_bool) :: empty_entries
510
511 if ( present( is_fatal ) ) then
512 is_fatal_l = is_fatal
513 else
514 is_fatal_l = false
515 endif
516
517 ptarget => this%get_entry(skey)
518
519 if ( associated( ptarget ) ) then
520
521 if ( is_fatal_l ) then
522 empty_entries = ptarget%sl%empty_entries_present()
523 if( empty_entries ) call warn(smessage="There are missing values associated" &
524 //" with the key value of "//dquote(skey), &
525 iloglevel=log_all, lecho=true, lfatal=true )
526 endif
527
528 ivalues = ptarget%sl%get_integer()
529
530 else
531
532 allocate(ivalues(1), stat=istat)
533 call assert(istat == 0, "Failed to allocate memory to iValues array", &
534 __file__, __line__)
535
536 call warn(smessage="Failed to find a dictionary entry associated with key value of "//dquote(skey), &
537 smodule=__file__, iline=__line__, iloglevel=log_debug, lecho=false)
538
539 ivalues = itinyval
540
541 endif
542
543 end subroutine get_values_as_int_sub
544
545!--------------------------------------------------------------------------------------------------
546
547 subroutine get_values_as_logical_sub(this, sKey, lValues, is_fatal)
548
549 class(dict_t) :: this
550 character (len=*) :: sKey
551 logical (c_bool), allocatable, intent(out) :: lValues(:)
552 logical (c_bool), optional :: is_fatal
553
554 ! [ LOCALS ]
555 type (DICT_ENTRY_T), pointer :: pTarget
556 integer (c_int) :: iStat
557 logical (c_bool) :: is_fatal_l
558 logical (c_bool) :: empty_entries
559
560 if ( present( is_fatal ) ) then
561 is_fatal_l = is_fatal
562 else
563 is_fatal_l = false
564 endif
565
566 ptarget => this%get_entry(skey)
567
568 if ( associated( ptarget ) ) then
569
570 if ( is_fatal_l ) then
571 empty_entries = ptarget%sl%empty_entries_present()
572 if( empty_entries ) call warn(smessage="There are missing values associated" &
573 //" with the key value of "//dquote(skey), &
574 iloglevel=log_all, lecho=true, lfatal=true )
575 endif
576
577 lvalues = ptarget%sl%get_logical()
578
579 else
580
581 allocate(lvalues(1), stat=istat)
582 call assert(istat == 0, "Failed to allocate memory to lValues array", &
583 __file__, __line__)
584
585 call warn(smessage="Failed to find a dictionary entry associated with key value of "//dquote(skey), &
586 smodule=__file__, iline=__line__, iloglevel=log_debug, lecho=false)
587
588 lvalues = false
589
590 endif
591
592 end subroutine get_values_as_logical_sub
593
594!--------------------------------------------------------------------------------------------------
595
596 !> Search through keys for a match; return logical values.
597 !!
598 !! THis routine allows for multiple header values to be supplied
599 !! in the search for the appropriate column.
600 !! @param[in] this Object of DICT_T class.
601 !! @param[in] slKeys String list containing one or more possible key values to
602 !! search for.
603 !! @param[out] iValues Integer vector of values associated with one of the provided keys.
604
605 subroutine get_values_as_logical_given_list_of_keys_sub(this, slKeys, lValues, is_fatal)
606
607 class(dict_t) :: this
608 type (FSTRING_LIST_T) :: slKeys
609 logical (c_bool), allocatable, intent(out) :: lValues(:)
610 logical (c_bool), optional :: is_fatal
611
612 ! [ LOCALS ]
613 type (DICT_ENTRY_T), pointer :: pTarget
614 integer (c_int) :: iStat
615 integer (c_int) :: iCount
616 character (len=:), allocatable :: sText
617 logical (c_bool) :: is_fatal_l
618 logical (c_bool) :: empty_entries
619
620 if ( present( is_fatal ) ) then
621 is_fatal_l = is_fatal
622 else
623 is_fatal_l = false
624 endif
625
626 icount = 0
627
628 do while ( icount < slkeys%count )
629
630 icount = icount + 1
631
632 stext = slkeys%get( icount)
633
634 ptarget => this%get_entry( stext )
635
636 if ( associated( ptarget ) ) exit
637
638 enddo
639
640 if ( associated( ptarget ) ) then
641
642 if ( is_fatal_l ) then
643 empty_entries = ptarget%sl%empty_entries_present()
644 if( empty_entries ) call warn(smessage="There are missing values associated" &
645 //" with the key values of "//slkeys%list_all(), &
646 iloglevel=log_all, lecho=true, lfatal=true )
647 endif
648
649 lvalues = ptarget%sl%get_logical()
650
651 else
652
653 allocate(lvalues(1), stat=istat)
654 call assert(istat == 0, "Failed to allocate memory to lValues array", &
655 __file__, __line__)
656
657 call warn(smessage="Failed to find a dictionary entry associated with key value(s) of: "//dquote(slkeys%list_all()), &
658 smodule=__file__, iline=__line__, iloglevel=log_debug, lecho=false)
659
660 lvalues = false
661
662 endif
663
665
666!--------------------------------------------------------------------------------------------------
667
668 subroutine get_values_as_string_list_given_list_of_keys_sub(this, slKeys, slString, is_fatal )
669
670 class(dict_t) :: this
671 type (FSTRING_LIST_T) :: slKeys
672 type ( FSTRING_LIST_T ), intent(out) :: slString
673 logical (c_bool), optional :: is_fatal
674
675 ! [ LOCALS ]
676 type (DICT_ENTRY_T), pointer :: pTarget
677 integer (c_int) :: iCount
678 character (len=:), allocatable :: sText
679 logical (c_bool) :: is_fatal_l
680 logical (c_bool) :: empty_entries
681
682 if ( present( is_fatal ) ) then
683 is_fatal_l = is_fatal
684 else
685 is_fatal_l = false
686 endif
687
688 icount = 0
689
690 do while ( icount < slkeys%count )
691
692 icount = icount + 1
693
694 stext = slkeys%get( icount)
695
696 ptarget => this%get_entry( stext )
697
698 if ( associated( ptarget ) ) exit
699
700 enddo
701
702 if ( associated( ptarget ) ) then
703
704 if ( is_fatal_l ) then
705 empty_entries = ptarget%sl%empty_entries_present()
706 if( empty_entries ) call warn(smessage="There are missing values associated" &
707 //" with the key values of "//slkeys%list_all(), &
708 iloglevel=log_all, lecho=true, lfatal=true )
709 endif
710
711 slstring = ptarget%sl
712
713 else
714
715 call slstring%append("<NA>")
716 call warn(smessage="Failed to find a dictionary entry associated with key value(s) of: "//dquote(slkeys%list_all()), &
717 smodule=__file__, iline=__line__, iloglevel=log_debug, lecho=false)
718
719 endif
720
722
723!--------------------------------------------------------------------------------------------------
724
725 subroutine get_value_as_string_sub(this, sText, sKey, iIndex, is_fatal )
726
727 class(dict_t) :: this
728 character(len=:), allocatable, intent(out) :: sText
729 character (len=*), intent(in), optional :: sKey
730 integer (c_int), intent(in), optional :: iIndex
731 logical (c_bool), optional :: is_fatal
732
733 ! [ LOCALS ]
734 logical (c_bool) :: is_fatal_l
735
736 if ( present( is_fatal ) ) then
737 is_fatal_l = is_fatal
738 else
739 is_fatal_l = false
740 endif
741
742 if ( present( skey ) ) this%current => this%get_entry(skey)
743
744 if ( present( iindex ) ) this%current => this%get_entry( iindex )
745
746 if ( associated( this%current ) ) then
747
748 stext = this%current%sl%get( 1, this%current%sl%count )
749
750 else
751
752 stext= ""
753
754 endif
755
756 end subroutine get_value_as_string_sub
757
758!--------------------------------------------------------------------------------------------------
759
760 subroutine get_values_as_string_list_sub(this, sKey, slString, is_fatal)
761
762 class(dict_t) :: this
763 character (len=*), intent(in) :: sKey
764 type (FSTRING_LIST_T), intent(out) :: slString
765 logical (c_bool), optional :: is_fatal
766
767 ! [ LOCALS ]
768 type (DICT_ENTRY_T), pointer :: pTarget
769 logical (c_bool) :: is_fatal_l
770 logical (c_bool) :: empty_entries
771
772 ptarget => this%get_entry(skey)
773
774 if ( present(is_fatal) ) then
775 is_fatal_l = is_fatal
776 else
777 is_fatal_l = false
778 endif
779
780 if ( associated( ptarget ) ) then
781
782 if ( is_fatal_l ) then
783 empty_entries = ptarget%sl%empty_entries_present()
784 if( empty_entries ) call warn(smessage="There are missing values associated" &
785 //" with the key value of "//dquote(skey), &
786 iloglevel=log_all, lecho=true, lfatal=true )
787 endif
788
789 slstring = ptarget%sl
790
791 else
792
793 call slstring%append("<NA>")
794 call warn(smessage="Failed to find a dictionary entry associated with key value of "//dquote(skey), &
795 smodule=__file__, iline=__line__, iloglevel=log_debug, lecho=false)
796
797 endif
798
799
800 end subroutine get_values_as_string_list_sub
801
802!--------------------------------------------------------------------------------------------------
803
804 !> Search through keys for a match; return integer values.
805 !!
806 !! THis routine allows for multiple header values to be supplied
807 !! in the search for the appropriate column.
808 !! @param[in] this Object of DICT_T class.
809 !! @param[in] slKeys String list containing one or more possible key values to
810 !! search for.
811 !! @param[out] iValues Integer vector of values associated with one of the provided keys.
812
813 subroutine get_values_as_int_given_list_of_keys_sub(this, slKeys, iValues, is_fatal)
814
815 class(dict_t) :: this
816 type (FSTRING_LIST_T) :: slKeys
817 integer (c_int), allocatable, intent(out) :: iValues(:)
818 logical (c_bool), optional :: is_fatal
819
820 ! [ LOCALS ]
821 type (DICT_ENTRY_T), pointer :: pTarget
822 integer (c_int) :: iStat
823 integer (c_int) :: iCount
824 character (len=256) :: sText
825 logical (c_bool) :: is_fatal_l
826 logical (c_bool) :: empty_entries
827
828 if ( present( is_fatal ) ) then
829 is_fatal_l = is_fatal
830 else
831 is_fatal_l = false
832 endif
833
834 icount = 0
835
836 ptarget => null()
837
838 do while ( icount < slkeys%count )
839
840 icount = icount + 1
841
842 stext = slkeys%get( icount)
843
844 ptarget => this%get_entry( stext )
845
846 if ( associated( ptarget ) ) exit
847
848 enddo
849
850 if ( associated( ptarget ) ) then
851
852 if ( is_fatal_l ) then
853 empty_entries = ptarget%sl%empty_entries_present()
854 if( empty_entries ) call warn(smessage="There are missing values associated" &
855 //" with the key values of "//slkeys%list_all(), &
856 iloglevel=log_all, lecho=true, lfatal=true )
857 endif
858
859 ivalues = ptarget%sl%get_integer()
860
861 else
862
863 allocate(ivalues(1), stat=istat)
864 call assert(istat == 0, "Failed to allocate memory to iValues array", &
865 __file__, __line__)
866
867 call warn(smessage="Failed to find a dictionary entry associated with key value(s) of: "//dquote(slkeys%list_all()), &
868 smodule=__file__, iline=__line__, iloglevel=log_debug, lecho=false)
869
870 ivalues = itinyval
871
872 endif
873
875
876!--------------------------------------------------------------------------------------------------
877
878 !> Search through keys for a match; return float values.
879 !!
880 !! THis routine allows for multiple header values to be supplied
881 !! in the search for the appropriate column.
882 !! @param[in] this Object of DICT_T class.
883 !! @param[in] slKeys String list containing one or more possible key values to
884 !! search for.
885 !! @param[out] fValues Float vector of values associated with one of the provided keys.
886
887 subroutine get_values_as_float_given_list_of_keys_sub(this, slKeys, fValues, is_fatal)
888
889 class(dict_t) :: this
890 type (FSTRING_LIST_T) :: slKeys
891 real (c_float), allocatable, intent(out) :: fValues(:)
892 logical (c_bool), optional :: is_fatal
893
894 ! [ LOCALS ]
895 type (DICT_ENTRY_T), pointer :: pTarget
896 integer (c_int) :: iStat
897 integer (c_int) :: iCount
898 character (len=:), allocatable :: sText
899 logical (c_bool) :: is_fatal_l
900 logical (c_bool) :: empty_entries
901
902 if ( present( is_fatal ) ) then
903 is_fatal_l = is_fatal
904 else
905 is_fatal_l = false
906 endif
907
908 icount = 0
909 ptarget => null()
910
911 do while ( icount < slkeys%count )
912
913 icount = icount + 1
914
915 stext = slkeys%get( icount)
916
917 ptarget => this%get_entry( stext )
918
919 if ( associated( ptarget ) ) exit
920
921 enddo
922
923 if ( associated( ptarget ) ) then
924
925 if ( is_fatal_l ) then
926 empty_entries = ptarget%sl%empty_entries_present()
927 if( empty_entries ) call warn(smessage="There are missing values associated" &
928 //" with the key values of "//slkeys%list_all(), &
929 iloglevel=log_all, lecho=true, lfatal=true )
930 endif
931
932 fvalues = ptarget%sl%get_float()
933
934 else
935
936 allocate(fvalues(1), stat=istat)
937 call assert(istat == 0, "Failed to allocate memory to fValues array", &
938 __file__, __line__)
939
940 call warn(smessage="Failed to find a dictionary entry associated with key value(s) of: "//dquote(slkeys%list_all()), &
941 smodule=__file__, iline=__line__, iloglevel=log_debug, lecho=false)
942
943
944 fvalues = ftinyval
945
946 endif
947
948
950
951!--------------------------------------------------------------------------------------------------
952
953 subroutine get_values_as_float_sub(this, sKey, fValues, is_fatal)
954
955 class(dict_t) :: this
956 character (len=*), intent(in) :: sKey
957 real (c_float), allocatable, intent(out) :: fValues(:)
958 logical (c_bool), optional :: is_fatal
959
960 ! [ LOCALS ]
961 type (DICT_ENTRY_T), pointer :: pTarget
962 integer (c_int) :: iStat
963 logical (c_bool) :: is_fatal_l
964 logical (c_bool) :: empty_entries
965
966 if ( present( is_fatal ) ) then
967 is_fatal_l = is_fatal
968 else
969 is_fatal_l = false
970 endif
971
972 ptarget => this%get_entry(skey)
973
974 if ( associated( ptarget ) ) then
975
976 if ( is_fatal_l ) then
977 empty_entries = ptarget%sl%empty_entries_present()
978 if( empty_entries ) call warn(smessage="There are missing values associated" &
979 //" with the key value of "//dquote(skey), &
980 iloglevel=log_all, lecho=true, lfatal=true )
981 endif
982
983 fvalues = ptarget%sl%get_float()
984
985 else
986
987 allocate(fvalues(1), stat=istat)
988 call assert(istat == 0, "Failed to allocate memory to iValues array", &
989 __file__, __line__)
990
991 call warn(smessage="Failed to find a dictionary entry associated with key value of "//dquote(skey), &
992 smodule=__file__, iline=__line__, iloglevel=log_debug , lecho=false)
993
994 fvalues = ftinyval
995
996 endif
997
998 end subroutine get_values_as_float_sub
999
1000!--------------------------------------------------------------------------------------------------
1001
1002 subroutine print_all_dictionary_entries_sub(this, iLogLevel, sDescription, lEcho )
1003
1004 class(dict_t) :: this
1005 integer (c_int), intent(in), optional :: iLogLevel
1006 character (len=*), intent(in), optional :: sDescription
1007 logical (c_bool), intent(in), optional :: lEcho
1008
1009 ! [ LOCALS ]
1010 type (DICT_ENTRY_T), pointer :: current
1011 character (len=512) :: sTempBuf
1012 character (len=:), allocatable :: sDescription_
1013 integer (c_int) :: iCount
1014 integer (c_int) :: iLogLevel_l
1015 logical (c_bool) :: lEcho_l
1016
1017 if ( present( iloglevel ) ) then
1018 iloglevel_l = iloglevel
1019 else
1020 iloglevel_l = logs%iLogLevel
1021 end if
1022
1023 if ( present( lecho ) ) then
1024 lecho_l = lecho
1025 else
1026 lecho_l = false
1027 end if
1028
1029 if ( present( sdescription ) ) then
1030 sdescription_ = trim(sdescription)
1031 else
1032 sdescription_ = "dictionary data structure"
1033 endif
1034
1035 current => this%first
1036 icount = 0
1037
1038 call logs%write( "### Summary of all items stored in "//trim(sdescription_), &
1039 iloglevel=iloglevel_l, lecho=lecho_l )
1040
1041 do while ( associated( current ) )
1042
1043 icount = icount + 1
1044 stempbuf = current%key
1045
1046 call logs%write( ascharacter(icount)//") KEY: "//dquote(stempbuf), &
1047 iloglevel=iloglevel_l, lecho=lecho_l, itab=2, ilinesbefore=1, ilinesafter=1 )
1048
1049 select case ( iloglevel_l )
1050
1051 case ( log_general )
1052
1053 call current%sl%print( lu=logs%iUnitNum( log_general ) )
1054
1055 case ( log_debug )
1056
1057 call current%sl%print( lu=logs%iUnitNum( log_debug ) )
1058
1059 case ( log_all )
1060
1061 call current%sl%print( lu=logs%iUnitNum( log_general ) )
1062 call current%sl%print( lu=logs%iUnitNum( log_debug ) )
1063
1064 case default
1065
1066 end select
1067
1068 if ( lecho_l ) call current%sl%print()
1069
1070 current => current%next
1071
1072 enddo
1073
1075
1076end module dictionary
This module contains physical constants and convenience functions aimed at performing unit conversion...
logical(c_bool), parameter, public true
logical(c_bool), parameter, public false
integer(c_int), parameter, public itinyval
subroutine get_values_as_string_list_sub(this, skey, slstring, is_fatal)
type(dict_entry_t) function, pointer get_entry_by_key_fn(this, skey)
type(dict_entry_t) function, pointer get_next_entry_by_key_fn(this, skey)
subroutine add_key_sub(this, skey)
subroutine get_values_as_float_given_list_of_keys_sub(this, slkeys, fvalues, is_fatal)
Search through keys for a match; return float values.
type(dict_entry_t) function, pointer get_entry_by_index_fn(this, iindex)
subroutine add_integer_sub(this, ivalue)
subroutine get_values_as_logical_given_list_of_keys_sub(this, slkeys, lvalues, is_fatal)
Search through keys for a match; return logical values.
type(dict_entry_t), pointer, public cf_entry
subroutine print_all_dictionary_entries_sub(this, iloglevel, sdescription, lecho)
subroutine get_values_as_int_given_list_of_keys_sub(this, slkeys, ivalues, is_fatal)
Search through keys for a match; return integer values.
type(dict_entry_t) function, pointer get_next_entry_fn(this)
type(dict_t), public cf_dict
logical(c_bool) function key_name_already_in_use_fn(this, skey)
subroutine delete_entry_by_key_sub(this, skey)
subroutine get_values_as_int_sub(this, skey, ivalues, is_fatal)
subroutine add_double_sub(this, dvalue)
subroutine get_value_as_string_sub(this, stext, skey, iindex, is_fatal)
type(dict_entry_t) function, pointer find_dict_entry_fn(this, ssearchkey)
subroutine get_values_as_string_list_given_list_of_keys_sub(this, slkeys, slstring, is_fatal)
type(fstring_list_t) function grep_dictionary_key_names_fn(this, skey)
subroutine add_entry_to_dict_sub(this, dict_entry)
subroutine add_float_sub(this, fvalue)
subroutine get_values_as_float_sub(this, skey, fvalues, is_fatal)
subroutine add_logical_sub(this, lvalue)
subroutine add_string_sub(this, svalue)
subroutine get_values_as_logical_sub(this, skey, lvalues, is_fatal)
subroutine, public warn(smessage, smodule, iline, shints, lfatal, iloglevel, lecho)
type(logfile_t), public logs
Definition logfiles.F90:62
@ log_general
Definition logfiles.F90:22