MONC
Functions/Subroutines | Variables
configuration_file_parser_mod Module Reference

Parses a configuration file and loads the contents into the options database which can then be interogated by components in the model. More...

Functions/Subroutines

subroutine, public parse_configuration_file (options_database, user_configuration_file)
 Parses a specific configuration and adds the contents into the options database. More...
 
recursive subroutine process_configuration_file (options_database, filename, is_user_file, file_id)
 Will actually open a specific file and read it in line by line, parsing this and storing the configuration options. More...
 
recursive subroutine process_configuration_line (options_database, raw_line, is_user_file, found_global)
 Processes a line from the configuration file, breaks it up into its key and value and depending upon the specifics of the line it will store it in the options database in a variety of ways. More...
 
logical function parse_global_configuration_if_available (options_database)
 Parses the global configuration file if it is available and calls on to add all of this to the options database. More...
 
logical function has_multiple_values (configuration_value)
 Determines if a specific string contains multiple values such as str1, str2, str3. More...
 
subroutine get_mode_and_split_points_from_line (raw_line, mode, start_split, end_split)
 Processes a line to determine the mode (replace or additive) and where the split point is between the key and value. More...
 
subroutine handle_array_element_set (options_database, config_key, config_value, mode)
 Handles setting a specific array element, when the key has something like k(n) - n being the index to set. More...
 
integer function get_key_array_index (config_key)
 Given a configuration key of the form k(n), this returns the n. More...
 
logical function is_key_array_index_specifier (config_key)
 Determines whether a configuration key represents a specific array element, i.e. is of the form k(n) More...
 
subroutine process_configuration_array (options_database, config_key, config_value, mode)
 Will process a configuration array of values such as v1,v2,v3,v4. More...
 
subroutine store_configuration (options_database, config_key, config_value, array_index)
 Stores a specific configuration by determining the type of a value and calling on to the options database for storage. More...
 
character(len=len(string_value)) function remove_string_quotation (string_value)
 Removes quotations from a string if these are included, regardless of before it will return the contents i.e. "abc" = abc, hg"abc"re = abc. More...
 

Variables

integer, parameter user_file_id =15
 
integer, parameter global_file_id =16
 

Detailed Description

Parses a configuration file and loads the contents into the options database which can then be interogated by components in the model.

Function/Subroutine Documentation

◆ get_key_array_index()

integer function configuration_file_parser_mod::get_key_array_index ( character(*), intent(in)  config_key)
private

Given a configuration key of the form k(n), this returns the n.

Parameters
config_keyThe configuration key to parse and extract the index from
Returns
The index encoded in the key

Definition at line 197 of file configurationfileparser.F90.

197  character(*), intent(in) :: config_key
198 
199  integer :: open_brace_index, close_brace_index
200 
201  open_brace_index=scan(config_key,"(")
202  close_brace_index=scan(config_key,")")
203 
204  if (close_brace_index - open_brace_index .lt. 2) then
205  call log_master_log(log_error, "Array element format for key "//&
206  trim(config_key)//" but no element provided")
207  end if
208 
209  get_key_array_index=conv_to_integer(config_key(open_brace_index+1:close_brace_index-1))
Here is the caller graph for this function:

◆ get_mode_and_split_points_from_line()

subroutine configuration_file_parser_mod::get_mode_and_split_points_from_line ( character(*), intent(in)  raw_line,
integer, intent(out)  mode,
integer, intent(out)  start_split,
integer, intent(out)  end_split 
)
private

Processes a line to determine the mode (replace or additive) and where the split point is between the key and value.

Parameters
raw_lineThe raw configuration line to process The mode, 1=replace, 2=additive and 0=none (unparsable)
start_splitThe last element before the split, i.e. the key is up to and including this element
end_splitThe element after the split, i.e. the value is this key to the end

Definition at line 145 of file configurationfileparser.F90.

145  character(*), intent(in) :: raw_line
146  integer, intent(out) :: mode, start_split, end_split
147 
148  integer :: split_point
149 
150  split_point=index(raw_line, "+=")
151  if (split_point .eq. 0) split_point=index(raw_line, "=+")
152  if (split_point .ne. 0) then
153  mode=2
154  start_split=split_point-1
155  end_split=split_point+2
156  else
157  split_point=index(raw_line, "=")
158  if (split_point .ne. 0) then
159  mode=1
160  start_split=split_point-1
161  end_split=split_point+1
162  else
163  mode=0
164  end if
165  end if
Here is the caller graph for this function:

◆ handle_array_element_set()

subroutine configuration_file_parser_mod::handle_array_element_set ( type(hashmap_type), intent(inout)  options_database,
character(*), intent(in)  config_key,
character(*), intent(in)  config_value,
integer, intent(in)  mode 
)
private

Handles setting a specific array element, when the key has something like k(n) - n being the index to set.

Parameters
options_databaseThe options database
config_keyThe configuration key including the index
config_valueThe configuration value to set
modeWhether this is replace or additive

Definition at line 175 of file configurationfileparser.F90.

175  type(hashmap_type), intent(inout) :: options_database
176  character(*), intent(in) :: config_key, config_value
177  integer, intent(in) :: mode
178 
179  integer :: array_index, key_end_index
180 
181  if (mode .eq. 2) then
182  array_index=options_get_array_size(options_database, config_key)+1
183  key_end_index=len(config_key)
184  else
185  array_index=get_key_array_index(config_key)
186  key_end_index=scan(config_key,"(")-1
187  end if
188 
189  call store_configuration(options_database, config_key(:key_end_index), &
190  trim(adjustl(config_value)), array_index)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ has_multiple_values()

logical function configuration_file_parser_mod::has_multiple_values ( character(*), intent(in)  configuration_value)
private

Determines if a specific string contains multiple values such as str1, str2, str3.

Parameters
configuration_valueThe string value
Returns
Whether or not the string is a vector of values (and needs to be split up)

Definition at line 132 of file configurationfileparser.F90.

132  character(*), intent(in) :: configuration_value
133 
134  has_multiple_values=scan(configuration_value, ",") .ne. 0
Here is the caller graph for this function:

◆ is_key_array_index_specifier()

logical function configuration_file_parser_mod::is_key_array_index_specifier ( character(*), intent(in)  config_key)
private

Determines whether a configuration key represents a specific array element, i.e. is of the form k(n)

Parameters
config_keyThe configuration key to check
Returns
Whether the key represents a specific element or not

Definition at line 217 of file configurationfileparser.F90.

217  character(*), intent(in) :: config_key
218 
219  integer :: loc
220 
221  loc=scan(config_key,"(")
222  if (loc .ne. 0) then
223  loc=scan(config_key,")")
224  if (loc .ne. 0) then
225  is_key_array_index_specifier=.true.
226  return
227  end if
228  end if
229  is_key_array_index_specifier=.false.
Here is the caller graph for this function:

◆ parse_configuration_file()

subroutine, public configuration_file_parser_mod::parse_configuration_file ( type(hashmap_type), intent(inout)  options_database,
character(*), intent(in)  user_configuration_file 
)

Parses a specific configuration and adds the contents into the options database.

Parameters
options_databaseThe options database
user_configuration_fileFilename of the initial (user) configuration file to open and process

Definition at line 27 of file configurationfileparser.F90.

27  type(hashmap_type), intent(inout) :: options_database
28  character(*), intent(in) :: user_configuration_file
29 
30  call process_configuration_file(options_database, user_configuration_file, .true., &
31  user_file_id)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ parse_global_configuration_if_available()

logical function configuration_file_parser_mod::parse_global_configuration_if_available ( type(hashmap_type), intent(inout)  options_database)
private

Parses the global configuration file if it is available and calls on to add all of this to the options database.

Parameters
options_databaseThe options database
Returns
Whether the global configuration file was processed

Definition at line 116 of file configurationfileparser.F90.

116  type(hashmap_type), intent(inout) :: options_database
117 
118  if (options_has_key(options_database, "global_configuration")) then
119  parse_global_configuration_if_available=.true.
120  call process_configuration_file(options_database, &
121  trim(options_get_string(options_database, "global_configuration")), .false., &
122  global_file_id)
123  else
124  parse_global_configuration_if_available=.false.
125  end if
Here is the call graph for this function:
Here is the caller graph for this function:

◆ process_configuration_array()

subroutine configuration_file_parser_mod::process_configuration_array ( type(hashmap_type), intent(inout)  options_database,
character(*), intent(in)  config_key,
character(*), intent(in)  config_value,
integer, intent(in)  mode 
)
private

Will process a configuration array of values such as v1,v2,v3,v4.

Parameters
options_databaseThe options database
config_keyThe configuration key
config_valueThe values each separated by comma The mode to use for storage, 1=insert, 2=additive

Definition at line 238 of file configurationfileparser.F90.

238  type(hashmap_type), intent(inout) :: options_database
239  character(*), intent(in) :: config_key, config_value
240  integer, intent(in) :: mode
241 
242  character(len=len(config_value)) :: raw_value
243  character(len=len(config_key)) :: parsed_config_key
244 
245  integer :: comma_posn, index
246 
247  if (mode == 1) then
248  call options_remove_key(options_database, config_key)
249  if (is_key_array_index_specifier(config_key)) then
250  index=get_key_array_index(config_key)
251  parsed_config_key=config_key(:scan(config_key,"(")-1)
252  else
253  parsed_config_key=config_key
254  index=1
255  end if
256  else if (mode==2) then
257  index=options_get_array_size(options_database, config_key)+1
258  end if
259 
260  raw_value=config_value
261  comma_posn=scan(raw_value, ",")
262  do while (comma_posn .gt. 0)
263  call store_configuration(options_database, parsed_config_key, &
264  trim(adjustl(raw_value(1:comma_posn-1))), index)
265  raw_value=raw_value(comma_posn+1:)
266  comma_posn=scan(raw_value, ",")
267  index=index+1
268  end do
269  call store_configuration(options_database, parsed_config_key, &
270  trim(adjustl(raw_value(1:))), index)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ process_configuration_file()

recursive subroutine configuration_file_parser_mod::process_configuration_file ( type(hashmap_type), intent(inout)  options_database,
character(*), intent(in)  filename,
logical, intent(in)  is_user_file,
integer, intent(in)  file_id 
)
private

Will actually open a specific file and read it in line by line, parsing this and storing the configuration options.

Parameters
options_databaseThe options database
filenameName of file to open
is_user_fileWhether or not this is the user configuration file or not
file_idThe ID to use in the open call

Definition at line 42 of file configurationfileparser.F90.

42  type(hashmap_type), intent(inout) :: options_database
43  character(*), intent(in) :: filename
44  integer, intent(in) :: file_id
45  logical, intent(in) :: is_user_file
46 
47  integer :: file_status
48  logical :: continue_parsing, found_global
49  character(len=10000) :: raw_line
50 
51  found_global=.false.
52  continue_parsing=.true.
53  open(unit=file_id, file=filename, status='old', access='sequential', form='formatted',&
54  action='read', iostat=file_status)
55  if (file_status .ne. 0) then
56  call log_master_log(log_error, "Configuration file "//trim(filename)//" does not exist")
57  end if
58 
59  do while (continue_parsing)
60  read(file_id, '(A)', iostat=file_status) raw_line
61  if (is_iostat_end(file_status)) then
62  continue_parsing=.false.
63  else
64  raw_line=adjustl(raw_line)
65  if (len_trim(raw_line) .gt. 0) then
66  call process_configuration_line(options_database, raw_line, is_user_file, &
67  found_global)
68  end if
69  end if
70  end do
71  close(file_id)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ process_configuration_line()

recursive subroutine configuration_file_parser_mod::process_configuration_line ( type(hashmap_type), intent(inout)  options_database,
character(*), intent(in)  raw_line,
logical, intent(in)  is_user_file,
logical, intent(inout)  found_global 
)
private

Processes a line from the configuration file, breaks it up into its key and value and depending upon the specifics of the line it will store it in the options database in a variety of ways.

Parameters
options_databaseThe options database
raw_lineThe raw text line to process
is_user_fileWhether this line was read from the user file or not
found_globalWhether or not we have found the global configuration file

Definition at line 83 of file configurationfileparser.F90.

83  type(hashmap_type), intent(inout) :: options_database
84  character(*), intent(in) :: raw_line
85  logical, intent(in) :: is_user_file
86  logical, intent(inout) :: found_global
87 
88  integer :: mode, start_split, end_split
89  character(len=10000) :: config_key, config_value
90 
91  call get_mode_and_split_points_from_line(raw_line, mode, start_split, end_split)
92 
93  if (mode .ge. 1 .and. raw_line(1:1) .ne. '#' .and. raw_line(1:1) .ne. '!') then
94  config_key=raw_line(1:start_split)
95  config_value=adjustl(raw_line(end_split:))
96 
97  if (has_multiple_values(config_value)) then
98  call process_configuration_array(options_database, config_key, config_value, mode)
99  else
100  if (is_key_array_index_specifier(config_key) .or. mode .eq. 2) then
101  call handle_array_element_set(options_database, config_key, config_value, mode)
102  else
103  call store_configuration(options_database, config_key, config_value)
104  if (is_user_file .and. .not. found_global) &
105  found_global=parse_global_configuration_if_available(options_database)
106  end if
107  end if
108  end if
Here is the call graph for this function:
Here is the caller graph for this function:

◆ remove_string_quotation()

character(len=len(string_value)) function configuration_file_parser_mod::remove_string_quotation ( character(len=*), intent(in)  string_value)
private

Removes quotations from a string if these are included, regardless of before it will return the contents i.e. "abc" = abc, hg"abc"re = abc.

Parameters
string_valueThe string value which may or may not contain string quotation marks
Returns
Either the quotation marks stripped out or the string unchanged if there were no quotes

Definition at line 337 of file configurationfileparser.F90.

337  character(len=*), intent(in) :: string_value
338  character(len=len(string_value)) :: remove_string_quotation
339 
340  integer :: quotation_index_start, quotation_index_end
341 
342  quotation_index_start=scan(string_value, """")
343  if (quotation_index_start .gt. 0) then
344  quotation_index_end=scan(string_value(quotation_index_start+1:), """")+&
345  quotation_index_start
346  if (quotation_index_end .gt. 0) then
347  remove_string_quotation=string_value(quotation_index_start+1:quotation_index_end-1)
348  else
349  remove_string_quotation=string_value
350  end if
351  else
352  remove_string_quotation=string_value
353  end if
Here is the caller graph for this function:

◆ store_configuration()

subroutine configuration_file_parser_mod::store_configuration ( type(hashmap_type), intent(inout)  options_database,
character(*), intent(in)  config_key,
character(*), intent(in)  config_value,
integer, intent(in), optional  array_index 
)
private

Stores a specific configuration by determining the type of a value and calling on to the options database for storage.

Parameters
options_databaseThe options database
config_keyThe configuration key
config_valueThe configuration value
array_indexThe index in the array to insert the element into

Definition at line 280 of file configurationfileparser.F90.

280  type(hashmap_type), intent(inout) :: options_database
281  character(*), intent(in) :: config_key, config_value
282  integer, intent(in), optional :: array_index
283 
284  integer :: comment_location
285  character(len=len(config_value)) :: parsed_value
286 
287  comment_location=scan(config_value,"#")
288  if (comment_location == 0) comment_location=scan(config_value,"!")
289  if (comment_location .gt. 0) then
290  parsed_value=config_value(:comment_location-1)
291  else
292  parsed_value=config_value
293  end if
294 
295  if (conv_is_logical(trim(parsed_value))) then
296  if (present(array_index)) then
297  call options_add(options_database, trim(config_key), &
298  conv_to_logical(trim(parsed_value)), &
299  array_index=array_index)
300  else
301  call options_add(options_database, trim(config_key), &
302  conv_to_logical(trim(parsed_value)))
303  end if
304  else if (conv_is_integer(parsed_value)) then
305  if (present(array_index)) then
306  call options_add(options_database, trim(config_key), &
307  conv_to_integer(trim(parsed_value)), &
308  array_index=array_index)
309  else
310  call options_add(options_database, trim(config_key), &
311  conv_to_integer(trim(parsed_value)))
312  end if
313  else if (conv_is_real(parsed_value)) then
314  if (present(array_index)) then
315  call options_add(options_database, trim(config_key), &
316  conv_single_real_to_double(conv_to_real(trim(parsed_value))), array_index=array_index)
317  else
318  call options_add(options_database, trim(config_key), conv_single_real_to_double(conv_to_real(trim(parsed_value))))
319  end if
320  else
321  if (present(array_index)) then
322  call options_add(options_database, trim(config_key), &
323  trim(remove_string_quotation(parsed_value)), array_index=array_index)
324  else
325  call options_add(options_database, trim(config_key), &
326  trim(remove_string_quotation(parsed_value)))
327  end if
328  end if
Here is the call graph for this function:
Here is the caller graph for this function:

Variable Documentation

◆ global_file_id

integer, parameter configuration_file_parser_mod::global_file_id =16
private

Definition at line 17 of file configurationfileparser.F90.

◆ user_file_id

integer, parameter configuration_file_parser_mod::user_file_id =15
private

Definition at line 17 of file configurationfileparser.F90.

17  integer, parameter :: user_file_id=15, global_file_id=16