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 209 of file configurationfileparser.F90.

210  character(*), intent(in) :: config_key
211 
212  integer :: open_brace_index, close_brace_index
213 
214  open_brace_index=scan(config_key,"(")
215  close_brace_index=scan(config_key,")")
216 
217  if (close_brace_index - open_brace_index .lt. 2) then
218  call log_master_log(log_error, "Array element format for key "//&
219  trim(config_key)//" but no element provided")
220  end if
221 
222  get_key_array_index=conv_to_integer(config_key(open_brace_index+1:close_brace_index-1))
Here is the call graph for this function:
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 @mode 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 157 of file configurationfileparser.F90.

158  character(*), intent(in) :: raw_line
159  integer, intent(out) :: mode, start_split, end_split
160 
161  integer :: split_point
162 
163  split_point=index(raw_line, "+=")
164  if (split_point .eq. 0) split_point=index(raw_line, "=+")
165  if (split_point .ne. 0) then
166  mode=2
167  start_split=split_point-1
168  end_split=split_point+2
169  else
170  split_point=index(raw_line, "=")
171  if (split_point .ne. 0) then
172  mode=1
173  start_split=split_point-1
174  end_split=split_point+1
175  else
176  mode=0
177  end if
178  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 187 of file configurationfileparser.F90.

188  type(hashmap_type), intent(inout) :: options_database
189  character(*), intent(in) :: config_key, config_value
190  integer, intent(in) :: mode
191 
192  integer :: array_index, key_end_index
193 
194  if (mode .eq. 2) then
195  array_index=options_get_array_size(options_database, config_key)+1
196  key_end_index=len(config_key)
197  else
198  array_index=get_key_array_index(config_key)
199  key_end_index=scan(config_key,"(")-1
200  end if
201 
202  call store_configuration(options_database, config_key(:key_end_index), &
203  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 144 of file configurationfileparser.F90.

145  character(*), intent(in) :: configuration_value
146 
147  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 229 of file configurationfileparser.F90.

230  character(*), intent(in) :: config_key
231 
232  integer :: loc
233 
234  loc=scan(config_key,"(")
235  if (loc .ne. 0) then
236  loc=scan(config_key,")")
237  if (loc .ne. 0) then
238  is_key_array_index_specifier=.true.
239  return
240  end if
241  end if
242  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 26 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 128 of file configurationfileparser.F90.

129  type(hashmap_type), intent(inout) :: options_database
130 
131  if (options_has_key(options_database, "global_configuration")) then
132  parse_global_configuration_if_available=.true.
133  call process_configuration_file(options_database, &
134  trim(options_get_string(options_database, "global_configuration")), .false., &
135  global_file_id)
136  else
137  parse_global_configuration_if_available=.false.
138  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 @mode The mode to use for storage, 1=insert, 2=additive

Definition at line 250 of file configurationfileparser.F90.

251  type(hashmap_type), intent(inout) :: options_database
252  character(*), intent(in) :: config_key, config_value
253  integer, intent(in) :: mode
254 
255  character(len=len(config_value)) :: raw_value
256  character(len=len(config_key)) :: parsed_config_key
257 
258  integer :: comma_posn, index
259 
260  if (mode == 1) then
261  call options_remove_key(options_database, config_key)
262  if (is_key_array_index_specifier(config_key)) then
263  index=get_key_array_index(config_key)
264  parsed_config_key=config_key(:scan(config_key,"(")-1)
265  else
266  parsed_config_key=config_key
267  index=1
268  end if
269  else if (mode==2) then
270  index=options_get_array_size(options_database, config_key)+1
271  end if
272 
273  raw_value=config_value
274  comma_posn=scan(raw_value, ",")
275  do while (comma_posn .gt. 0)
276  call store_configuration(options_database, parsed_config_key, &
277  trim(adjustl(raw_value(1:comma_posn-1))), index)
278  raw_value=raw_value(comma_posn+1:)
279  comma_posn=scan(raw_value, ",")
280  index=index+1
281  end do
282  call store_configuration(options_database, parsed_config_key, &
283  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

Remove in-line commments. If there's a comma in the comment, an array is assumed

Makes a section of store_configuration redundant.

Left adjust

Definition at line 40 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, comment_point
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
65  ! and errors will occur. See has_multiple_values.
67  comment_point=index(raw_line,'#')
68  if (comment_point .eq. 0) comment_point=index(raw_line,'!')
69  if (comment_point .ne. 0) raw_line = raw_line(:comment_point - 1)
70 
72  raw_line=adjustl(raw_line)
73  if (len_trim(raw_line) .gt. 0) then
74  call process_configuration_line(options_database, raw_line, is_user_file, &
75  found_global)
76  end if
77  end if
78  end do
79  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

If multiple values exist in comma-separated format (a common event) or

Definition at line 89 of file configurationfileparser.F90.

91  type(hashmap_type), intent(inout) :: options_database
92  character(*), intent(in) :: raw_line
93  logical, intent(in) :: is_user_file
94  logical, intent(inout) :: found_global
95 
96  integer :: mode, start_split, end_split
97  character(len=10000) :: config_key, config_value
98 
99  call get_mode_and_split_points_from_line(raw_line, mode, start_split, end_split)
100 
101  if (mode .ge. 1 .and. raw_line(1:1) .ne. '#' .and. raw_line(1:1) .ne. '!') then
102  config_key=raw_line(1:start_split)
103  config_value=adjustl(raw_line(end_split:))
105  ! The key already exists with multiple values, treat as an array.
106  ! The second case is important if, for instance, the global_config defaults
107  ! to an array with multiple values, but the option may be acceptably entered
108  ! as a single value. This ensures the full key will be removed.
109  if (has_multiple_values(config_value) .or. &
110  options_has_key(options_database, trim(config_key)//"a_size")) then
111  call process_configuration_array(options_database, config_key, config_value, mode)
112  else
113  if (is_key_array_index_specifier(config_key) .or. mode .eq. 2) then
114  call handle_array_element_set(options_database, config_key, config_value, mode)
115  else
116  call store_configuration(options_database, config_key, config_value)
117  if (is_user_file .and. .not. found_global) &
118  found_global=parse_global_configuration_if_available(options_database)
119  end if
120  end if
121  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 349 of file configurationfileparser.F90.

350  character(len=*), intent(in) :: string_value
351  character(len=len(string_value)) :: remove_string_quotation
352 
353  integer :: quotation_index_start, quotation_index_end
354 
355  quotation_index_start=scan(string_value, """")
356  if (quotation_index_start .gt. 0) then
357  quotation_index_end=scan(string_value(quotation_index_start+1:), """")+&
358  quotation_index_start
359  if (quotation_index_end .gt. 0) then
360  remove_string_quotation=string_value(quotation_index_start+1:quotation_index_end-1)
361  else
362  remove_string_quotation=string_value
363  end if
364  else
365  remove_string_quotation=string_value
366  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 292 of file configurationfileparser.F90.

293  type(hashmap_type), intent(inout) :: options_database
294  character(*), intent(in) :: config_key, config_value
295  integer, intent(in), optional :: array_index
296 
297  integer :: comment_location
298  character(len=len(config_value)) :: parsed_value
299 
300  comment_location=scan(config_value,"#")
301  if (comment_location == 0) comment_location=scan(config_value,"!")
302  if (comment_location .gt. 0) then
303  parsed_value=config_value(:comment_location-1)
304  else
305  parsed_value=config_value
306  end if
307 
308  if (conv_is_logical(trim(parsed_value))) then
309  if (present(array_index)) then
310  call options_add(options_database, trim(config_key), &
311  conv_to_logical(trim(parsed_value)), &
312  array_index=array_index)
313  else
314  call options_add(options_database, trim(config_key), &
315  conv_to_logical(trim(parsed_value)))
316  end if
317  else if (conv_is_integer(parsed_value)) then
318  if (present(array_index)) then
319  call options_add(options_database, trim(config_key), &
320  conv_to_integer(trim(parsed_value)), &
321  array_index=array_index)
322  else
323  call options_add(options_database, trim(config_key), &
324  conv_to_integer(trim(parsed_value)))
325  end if
326  else if (conv_is_real(parsed_value)) then
327  if (present(array_index)) then
328  call options_add(options_database, trim(config_key), &
329  conv_single_real_to_double(conv_to_real(trim(parsed_value))), array_index=array_index)
330  else
331  call options_add(options_database, trim(config_key), conv_single_real_to_double(conv_to_real(trim(parsed_value))))
332  end if
333  else
334  if (present(array_index)) then
335  call options_add(options_database, trim(config_key), &
336  trim(remove_string_quotation(parsed_value)), array_index=array_index)
337  else
338  call options_add(options_database, trim(config_key), &
339  trim(remove_string_quotation(parsed_value)))
340  end if
341  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
logging_mod::log_error
integer, parameter, public log_error
Only log ERROR messages.
Definition: logging.F90:11
logging_mod::log_master_log
subroutine, public log_master_log(level, message)
Will log just from the master process.
Definition: logging.F90:47