Skip to content

Commit 227f36c

Browse files
committed
cleanup/simplify
1 parent fb47dff commit 227f36c

File tree

4 files changed

+169
-182
lines changed

4 files changed

+169
-182
lines changed

src/Utilities/Message.f90

Lines changed: 129 additions & 141 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
!> @brief Generic utilities to store and issue messages to an output unit.
1+
!> @brief Store and issue logging messages to output units.
22
module MessageModule
33

44
use KindModule, only: LGP, I4B, DP
@@ -10,128 +10,102 @@ module MessageModule
1010
implicit none
1111
public :: MessagesType
1212
public :: write_message
13-
public :: write_message_counter
13+
public :: write_message_indented
1414
public :: write_message_centered
1515

16-
!> @brief Container for related messages sharing a name and title.
16+
!> @brief Container for related messages.
1717
!!
18-
!! A maximum number of messages may be configured. Message storage
19-
!! arrays are dynamically reallocated up to the specified capacity.
18+
!! A maximum capacity can be configured. Message storage
19+
!! is dynamically resized up to the configured capacity.
2020
!<
2121
type :: MessagesType
22-
character(len=LINELENGTH) :: title !< title of the message
23-
character(len=LINELENGTH) :: name !< message name
24-
integer(I4B) :: nmessage = 0 !< number of messages stored
25-
integer(I4B) :: max_message = 1000 !< default maximum number of messages that can be stored
26-
integer(I4B) :: max_exceeded = 0 !< flag indicating if the maximum number of messages has exceed the maximum number
27-
integer(I4B) :: inc_message = 100 !< amount to increment message array by when calling ExpandArray
28-
character(len=MAXCHARLEN), allocatable, dimension(:) :: messages !< message array
22+
! character(len=LINELENGTH) :: title !< message title
23+
! character(len=LINELENGTH) :: name !< message name
24+
integer(I4B) :: num_messages = 0 !< number of messages currently stored
25+
integer(I4B) :: max_messages = 1000 !< default max message storage capacity
26+
integer(I4B) :: max_exceeded = 0 !< number of messages in excess of maximum
27+
integer(I4B) :: exp_messages = 100 !< number of slots to expand message array
28+
real(DP) :: exp_factor = 1.1 !< factor to multiply the number of expansion slots
29+
character(len=MAXCHARLEN), private, allocatable, dimension(:) :: messages
2930
contains
30-
procedure :: init_message
31-
procedure :: count_message
32-
procedure :: set_max_message
33-
procedure :: store_message
34-
procedure :: print_message
35-
procedure :: deallocate_message
31+
procedure :: count
32+
procedure :: store
33+
procedure :: write_all
34+
procedure :: deallocate
3635
end type MessagesType
3736

3837
contains
3938

40-
!> @brief Initialize message storage.
41-
subroutine init_message(this)
42-
class(MessagesType) :: this !< MessageType object
43-
44-
! -- initialize message variables
45-
this%nmessage = 0
46-
this%max_message = 1000
47-
this%max_exceeded = 0
48-
this%inc_message = 100
49-
end subroutine init_message
50-
5139
!> @brief Return the number of messages currently stored.
52-
function count_message(this) result(nmessage)
40+
function count(this) result(nmsg)
5341
class(MessagesType) :: this !< MessageType object
54-
integer(I4B) :: nmessage
55-
56-
! -- set nmessage
42+
integer(I4B) :: nmsg
5743
if (allocated(this%messages)) then
58-
nmessage = this%nmessage
44+
nmsg = this%num_messages
5945
else
60-
nmessage = 0
46+
nmsg = 0
6147
end if
62-
end function count_message
48+
end function count
6349

64-
!> @brief Set the maximum number of messages.
65-
subroutine set_max_message(this, imax)
66-
class(MessagesType) :: this !< MessageType object
67-
integer(I4B), intent(in) :: imax !< maximum number of messages that will be stored
68-
69-
! -- set max_message
70-
this%max_message = imax
71-
end subroutine set_max_message
72-
73-
!> @brief Store a message for printing at the end of the simulation.
74-
subroutine store_message(this, msg, substring)
50+
!> @brief Add a message to storage.
51+
!!
52+
!! An optional string may be provided to filter out duplicate messages.
53+
!! If any stored messages contain the string the message is not stored.
54+
!<
55+
subroutine store(this, message, filter)
7556
! -- dummy variables
7657
class(MessagesType) :: this !< MessageType object
77-
character(len=*), intent(in) :: msg !< message
78-
character(len=*), intent(in), optional :: substring !< optional string that can be used
79-
!! to prevent storing duplicate messages
58+
character(len=*), intent(in) :: message !< message
59+
character(len=*), intent(in), optional :: filter !< duplicate filter
8060
! -- local variables
81-
logical(LGP) :: inc_array
82-
logical(LGP) :: increment_message
8361
integer(I4B) :: i
84-
integer(I4B) :: idx
8562
!
86-
! -- determine if messages should be expanded
87-
inc_array = .TRUE.
88-
if (allocated(this%messages)) then
89-
i = this%nmessage
90-
if (i < size(this%messages)) then
91-
inc_array = .FALSE.
63+
! -- allocate/expand arrays if needed
64+
if (.not. allocated(this%messages)) then
65+
allocate (this%messages(int(this%max_messages / 10)))
66+
else
67+
i = this%num_messages
68+
if (i == size(this%messages)) then
69+
call ExpandArray(this%messages, increment=this%exp_messages)
70+
this%exp_messages = int(this%exp_messages * this%exp_factor)
9271
end if
9372
end if
9473
!
95-
! -- resize message
96-
if (inc_array) then
97-
call ExpandArray(this%messages, increment=this%inc_message)
98-
this%inc_message = int(this%inc_message * 1.1)
99-
end if
100-
!
101-
! -- Determine if the substring exists in the passed message.
102-
! If substring is in passed message, do not add the duplicate
103-
! passed message.
104-
increment_message = .TRUE.
105-
if (present(substring)) then
106-
do i = 1, this%nmessage
107-
idx = index(this%messages(i), substring)
108-
if (idx > 0) then
109-
increment_message = .FALSE.
110-
exit
111-
end if
74+
! -- if a duplicate filter is provided and any message contains it, skip it
75+
if (present(filter)) then
76+
do i = 1, this%num_messages
77+
if (index(this%messages(i), filter) > 0) return
11278
end do
11379
end if
11480
!
115-
! -- store this message and calculate nmessage
116-
if (increment_message) then
117-
i = this%nmessage + 1
118-
if (i <= this%max_message) then
119-
this%nmessage = i
120-
this%messages(i) = msg
121-
else
122-
this%max_exceeded = this%max_exceeded + 1
123-
end if
81+
! -- store message and update count unless
82+
! at capacity, then update excess count
83+
i = this%num_messages + 1
84+
if (i <= this%max_messages) then
85+
this%num_messages = i
86+
this%messages(i) = message
87+
print *, 'stored message: ', message
88+
else
89+
this%max_exceeded = this%max_exceeded + 1
12490
end if
125-
end subroutine store_message
91+
end subroutine store
12692

127-
!> @brief Print stored messages.
128-
subroutine print_message(this, title, name, iunit)
93+
!> @brief Write all stored messages to standard output.
94+
!!
95+
!! An optional title to precede the messages may be provided.
96+
!! The title is printed on a separate line. An arbitrary kind
97+
!! may be specified, e.g. 'note', 'warning' or 'error. A file
98+
!! unit can also be specified to write in addition to stdout.
99+
!<
100+
subroutine write_all(this, title, kind, iunit)
129101
! -- dummy variables
130102
class(MessagesType) :: this !< MessageType object
131-
character(len=*), intent(in) :: title !< message title
132-
character(len=*), intent(in) :: name !< message name
133-
integer(I4B), intent(in), optional :: iunit !< optional file unit to save messages to
103+
character(len=*), intent(in), optional :: title !< message title
104+
character(len=*), intent(in), optional :: kind !< message kind (e.g. note, warning, error)
105+
integer(I4B), intent(in), optional :: iunit !< optional file unit
134106
! -- local
107+
character(len=LINELENGTH) :: ltitle
108+
character(len=LINELENGTH) :: lkind
135109
character(len=LINELENGTH) :: errmsg
136110
character(len=LINELENGTH) :: cerr
137111
integer(I4B) :: iu
@@ -142,61 +116,76 @@ subroutine print_message(this, title, name, iunit)
142116
character(len=*), parameter :: stdfmt = "(/,A,/)"
143117
!
144118
! -- process optional variables
119+
if (present(title)) then
120+
ltitle = title
121+
else
122+
ltitle = ''
123+
end if
124+
if (present(kind)) then
125+
lkind = kind
126+
else
127+
lkind = ''
128+
end if
145129
if (present(iunit)) then
146130
iu = iunit
147131
else
148132
iu = istdout
149133
end if
150134
!
151-
! -- write the title and all message entries
135+
! -- write messages, if any
152136
if (allocated(this%messages)) then
153-
isize = this%nmessage
154-
if (isize > 0) then
155-
!
156-
! -- calculate the maximum width of the prepended string
157-
! for the counter
158-
write (cerr, '(i0)') isize
159-
iwidth = len_trim(cerr) + 1
160-
!
161-
! -- write title for message
137+
isize = this%num_messages
138+
if (isize == 0) return
139+
!
140+
! -- calculate the maximum width of the prepended string
141+
! for the counter
142+
write (cerr, '(i0)') isize
143+
iwidth = len_trim(cerr) + 1
144+
!
145+
! -- write title, if provided
146+
if (trim(ltitle) /= '') then
162147
if (iu > 0) &
163-
call write_message(iunit=iu, text=title, fmt=stdfmt)
164-
call write_message(text=title, fmt=stdfmt)
165-
!
166-
! -- write each message
167-
do i = 1, isize
168-
if (iu > 0) &
169-
call write_message_counter( &
170-
iunit=iu, &
171-
text=this%messages(i), &
172-
icount=i, &
173-
iwidth=iwidth)
174-
call write_message_counter( &
175-
text=this%messages(i), &
176-
icount=i, &
177-
iwidth=iwidth)
178-
end do
179-
!
180-
! -- write the number of additional messages
181-
if (this%max_exceeded > 0) then
182-
write (errmsg, '(i0,3(1x,a))') &
183-
this%max_exceeded, 'additional', trim(name), &
184-
'detected but not printed.'
185-
if (iu > 0) &
186-
call write_message(iunit=iu, text=trim(errmsg), fmt='(/,1x,a)')
187-
call write_message(text=trim(errmsg), fmt='(/,1x,a)')
188-
end if
148+
call write_message(iunit=iu, text=ltitle, fmt=stdfmt)
149+
call write_message(text=ltitle, fmt=stdfmt)
150+
end if
151+
!
152+
! -- write each message
153+
do i = 1, isize
154+
if (iu > 0) &
155+
call write_message_indented( &
156+
iunit=iu, &
157+
text=this%messages(i), &
158+
icount=i, &
159+
iwidth=iwidth)
160+
call write_message_indented( &
161+
text=this%messages(i), &
162+
icount=i, &
163+
iwidth=iwidth)
164+
end do
165+
!
166+
! -- warn about messages we couldn't save/show
167+
if (this%max_exceeded > 0) then
168+
write (errmsg, '(i0,3(1x,a))') &
169+
this%max_exceeded, trim(lkind), &
170+
'messages over capacity.'
171+
if (iu > 0) &
172+
call write_message(iunit=iu, text=trim(errmsg), fmt='(/,1x,a)')
173+
call write_message(text=trim(errmsg), fmt='(/,1x,a)')
189174
end if
190175
end if
191-
end subroutine print_message
176+
end subroutine write_all
192177

193-
!> @ brief Deallocate message stored if needed.
194-
subroutine deallocate_message(this)
178+
!> @ brief Deallocate message storage.
179+
subroutine deallocate (this)
195180
class(MessagesType) :: this
196181
if (allocated(this%messages)) deallocate (this%messages)
197-
end subroutine deallocate_message
182+
end subroutine deallocate
198183

199-
!> @brief Configurable routine to write a message to an output unit.
184+
!> @brief Write a message to an output unit.
185+
!!
186+
!! Use `advance` to toggle advancing output. Use `skipbefore/after` to
187+
!! configure the number of whitespace lines before/after the message.
188+
!<
200189
subroutine write_message(text, iunit, fmt, &
201190
skipbefore, skipafter, advance)
202191
! -- dummy
@@ -266,17 +255,16 @@ subroutine write_message(text, iunit, fmt, &
266255
end if
267256
end subroutine write_message
268257

269-
!> @brief Write a message, splitting across lines as needed.
258+
!> @brief Write a message with configurable indentation.
270259
!!
271-
!! Subroutine that formats and writes a single message that
272-
!! may exceeed 78 characters in length. Messages longer than
273-
!! 78 characters are written across multiple lines. When a
274-
!! counter is passed in subsequent lines are indented.
260+
!! The message may exceed 78 characters in length. Messages longer than
261+
!! 78 characters are written across multiple lines. After icount lines,
262+
!! subsequent lines are indented. Use skipbefore/after to configure the
263+
!! number of empty lines before/after the message.
275264
!<
276-
subroutine write_message_counter(text, iunit, icount, iwidth, &
277-
skipbefore, skipafter)
265+
subroutine write_message_indented(text, iunit, icount, iwidth, &
266+
skipbefore, skipafter)
278267
! -- dummy
279-
280268
character(len=*), intent(in) :: text !< message to be written
281269
integer(I4B), intent(in), optional :: iunit !< the unit number to which the message is written
282270
integer(I4B), intent(in), optional :: icount !< counter to prepended to the message
@@ -412,7 +400,7 @@ subroutine write_message_counter(text, iunit, icount, iwidth, &
412400
call write_message(text=line, iunit=iu, fmt=fmt_cont, &
413401
skipafter=isa)
414402
end if
415-
end subroutine write_message_counter
403+
end subroutine write_message_indented
416404

417405
!> @brief Write horizontally centered text, left-padding as needed.
418406
subroutine write_message_centered(text, linelen, iunit)

0 commit comments

Comments
 (0)