Skip to content

Commit 5e1ad32

Browse files
committed
Refactoring. Added module.
1 parent 1462af6 commit 5e1ad32

File tree

15 files changed

+695
-274
lines changed

15 files changed

+695
-274
lines changed

Makefile

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,7 @@ SRC = $(SRCDIR)/dm_ansi.f90 \
276276
$(SRCDIR)/dm_mail.f90 \
277277
$(SRCDIR)/dm_mime.f90 \
278278
$(SRCDIR)/dm_modbus.f90 \
279+
$(SRCDIR)/dm_modbus_type.f90 \
279280
$(SRCDIR)/dm_mqtt.f90 \
280281
$(SRCDIR)/dm_mqueue.f90 \
281282
$(SRCDIR)/dm_mqueue_util.f90 \
@@ -375,6 +376,7 @@ OBJ = dm_ansi.o \
375376
dm_mail.o \
376377
dm_mime.o \
377378
dm_modbus.o \
379+
dm_modbus_type.o \
378380
dm_mqtt.o \
379381
dm_mqueue.o \
380382
dm_mqueue_util.o \
@@ -607,6 +609,7 @@ $(OBJ): $(SRC)
607609
$(FC) $(FFLAGS) $(LDFLAGS) -c src/dm_beat.f90
608610
$(FC) $(FFLAGS) $(LDFLAGS) -c src/dm_mqueue.f90
609611
$(FC) $(FFLAGS) $(LDFLAGS) -c src/dm_logger.f90
612+
$(FC) $(FFLAGS) $(LDFLAGS) -c src/dm_mqueue_util.f90
610613
$(FC) $(FFLAGS) $(LDFLAGS) -c src/dm_test.f90
611614
$(FC) $(FFLAGS) $(LDFLAGS) -c src/dm_nml.f90
612615
$(FC) $(FFLAGS) $(LDFLAGS) $(INCHDF5) -c src/dm_hdf5.f90
@@ -640,14 +643,14 @@ $(OBJ): $(SRC)
640643
$(FC) $(FFLAGS) $(LDFLAGS) -c src/dm_geocom_type.f90
641644
$(FC) $(FFLAGS) $(LDFLAGS) -c src/dm_geocom_api.f90
642645
$(FC) $(FFLAGS) $(LDFLAGS) -c src/dm_geocom.f90
646+
$(FC) $(FFLAGS) $(LDFLAGS) -c src/dm_modbus_type.f90
647+
$(FC) $(FFLAGS) $(LDFLAGS) -c src/dm_modbus.f90
643648
$(FC) $(FFLAGS) $(LDFLAGS) -c src/dm_lua.f90
644649
$(FC) $(FFLAGS) $(LDFLAGS) -c src/dm_lua_api.f90
645650
$(FC) $(FFLAGS) $(LDFLAGS) -c src/dm_lua_geocom.f90
646651
$(FC) $(FFLAGS) $(LDFLAGS) -c src/dm_lua_lib.f90
647652
$(FC) $(FFLAGS) $(LDFLAGS) -c src/dm_config.f90
648653
$(FC) $(FFLAGS) $(LDFLAGS) -c src/dm_rts.f90
649-
$(FC) $(FFLAGS) $(LDFLAGS) -c src/dm_mqueue_util.f90
650-
$(FC) $(FFLAGS) $(LDFLAGS) -c src/dm_modbus.f90
651654
$(FC) $(FFLAGS) $(LDFLAGS) -c src/dm_crypto.f90
652655
$(FC) $(FFLAGS) $(LDFLAGS) -c src/dm_image.f90
653656
$(FC) $(FFLAGS) $(LDFLAGS) -c src/dm_gm.f90

README.md

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,13 @@ Breaking API changes have to be expected until version 1.0.0.
2525

2626
**DMPACK** is a scientific monitoring system and sensor network middleware
2727
developed for automated control measurements of buildings, infrastructure,
28-
terrain, geodetic nets, and other objects. The software runs on sensor nodes,
29-
usually IoT gateways, industrial embedded systems, or single-board computers,
30-
and obtains observation data from arbitrary sensors, like robotic total
31-
stations, digital levels, inclinometers, weather stations, or GNSS receivers.
28+
terrain, geodetic nets, and other objects.
29+
30+
The software runs on sensor nodes, usually IoT gateways, industrial embedded
31+
systems, or single-board computers, and obtains observation data from arbitrary
32+
sensors, like robotic total stations, digital levels, inclinometers, weather
33+
stations, or GNSS receivers.
34+
3235
The raw sensor data is then processed, stored, and optionally transmitted to a
3336
server. The software package may be used to monitor objects like:
3437

app/dmmbctl.f90

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,6 @@ integer function read_args(app) result(rc)
6565
type(app_type), intent(out) :: app
6666

6767
character(len=4) :: byte_order, parity
68-
integer :: stat
6968
integer :: read_address, write_address
7069
logical :: has_baud_rate, has_byte_size, has_path, has_parity, has_stop_bits
7170
logical :: has_address, has_port, has_registers
@@ -269,9 +268,9 @@ integer function read_args(app) result(rc)
269268

270269
! Floating-point number.
271270
if (app%float) then
272-
stat = dm_modbus_byte_order_from_name(byte_order, app%byte_order)
271+
app%byte_order = dm_modbus_byte_order_from_name(byte_order)
273272

274-
if (dm_is_error(stat)) then
273+
if (.not. dm_modbus_is_valid_byte_order(app%byte_order)) then
275274
call dm_error_out(rc, 'argument --float is not a valid byte order')
276275
return
277276
end if

src/dm_api_status.f90

Lines changed: 33 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,13 @@ module dm_api_status
3838
integer function dm_api_status_from_string(string, api) result(rc)
3939
!! Reads API status type from given string. Only keys found in the
4040
!! string are overwritten in the derived type. No error is returned if
41-
!! the string does not contain any of the keys. The function returns
42-
!! `E_EMPTY` if the passed string is empty.
41+
!! the string does not contain any of the keys.
42+
!!
43+
!! The function returns the following error codes:
44+
!!
45+
!! * `E_EMPTY` if the string is empty.
46+
!! * `E_FORMAT` if the string format is invalid.
47+
!!
4348
use :: dm_string
4449

4550
integer, parameter :: LINE_LEN = 1 + (API_STATUS_LEN * 2)
@@ -49,35 +54,33 @@ integer function dm_api_status_from_string(string, api) result(rc)
4954

5055
integer :: i, n, nlines
5156
character(len=LINE_LEN) :: lines(API_STATUS_NKEYS)
52-
character(len=API_STATUS_LEN) :: pair(2)
57+
character(len=API_STATUS_LEN) :: pair(2), key, value
5358

5459
rc = E_EMPTY
5560
if (len_trim(string) == 0) return
5661

62+
rc = E_FORMAT
5763
call dm_string_split(string, lines, del=NL, n=nlines)
5864
if (nlines == 0) return
5965

6066
do i = 1, nlines
6167
call dm_string_split(lines(i), pair, del='=', n=n)
6268
if (n /= 2) exit
6369

64-
select case (pair(1))
65-
case ('version')
66-
api%version = dm_ascii_escape(pair(2))
67-
case ('dmpack')
68-
api%dmpack = dm_ascii_escape(pair(2))
69-
case ('host')
70-
api%host = dm_ascii_escape(pair(2))
71-
case ('server')
72-
api%server = dm_ascii_escape(pair(2))
73-
case ('timestamp')
74-
api%timestamp = dm_ascii_escape(pair(2))
75-
case ('message')
76-
api%message= dm_ascii_escape(pair(2))
77-
case ('error')
78-
api%error = dm_atoi(pair(2))
79-
case default
80-
cycle
70+
call dm_lower(pair(1))
71+
72+
key = adjustl(pair(1))
73+
value = adjustl(pair(2))
74+
75+
select case (key)
76+
case ('version'); api%version = dm_ascii_escape(value)
77+
case ('dmpack'); api%dmpack = dm_ascii_escape(value)
78+
case ('host'); api%host = dm_ascii_escape(value)
79+
case ('server'); api%server = dm_ascii_escape(value)
80+
case ('timestamp'); api%timestamp = dm_ascii_escape(value)
81+
case ('message'); api%message = dm_ascii_escape(value)
82+
case ('error'); api%error = dm_atoi(value)
83+
case default; cycle
8184
end select
8285
end do
8386

@@ -100,22 +103,22 @@ pure elemental logical function dm_api_status_equals(api1, api2) result(equals)
100103
equals = .true.
101104
end function dm_api_status_equals
102105

103-
function dm_api_status_to_string(api) result(str)
106+
function dm_api_status_to_string(api) result(string)
104107
!! Returns string representation of given API status type. The string
105108
!! contains new-line characters.
106-
type(api_status_type), intent(inout) :: api !! API status type.
107-
character(len=:), allocatable :: str !! String representation.
109+
type(api_status_type), intent(inout) :: api !! API status type.
110+
character(len=:), allocatable :: string !! String representation.
108111

109-
str = 'version=' // trim(api%version) // NL // &
110-
'dmpack=' // trim(api%dmpack) // NL // &
111-
'host=' // trim(api%host) // NL // &
112-
'server=' // trim(api%server) // NL // &
113-
'timestamp=' // trim(api%timestamp)
112+
string = 'version=' // trim(api%version) // NL // &
113+
'dmpack=' // trim(api%dmpack) // NL // &
114+
'host=' // trim(api%host) // NL // &
115+
'server=' // trim(api%server) // NL // &
116+
'timestamp=' // trim(api%timestamp)
114117

115118
if (len_trim(api%message) > 0) then
116-
str = str // NL // 'message=' // trim(api%message)
119+
string = string // NL // 'message=' // trim(api%message)
117120
end if
118121

119-
str = str // NL // 'error=' // dm_itoa(api%error)
122+
string = string // NL // 'error=' // dm_itoa(api%error)
120123
end function dm_api_status_to_string
121124
end module dm_api_status

src/dm_ascii.f90

Lines changed: 57 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,6 @@ module dm_ascii
4040

4141
character(len=*), parameter, public :: CR_LF = ASCII_CR // ASCII_LF !! Carriage return + line feed (`\r\n`).
4242

43-
public :: dm_ascii_escape
44-
public :: dm_ascii_unescape
45-
4643
public :: dm_ascii_is_alpha
4744
public :: dm_ascii_is_alpha_numeric
4845
public :: dm_ascii_is_blank
@@ -54,50 +51,10 @@ module dm_ascii
5451
public :: dm_ascii_is_octal_digit
5552
public :: dm_ascii_is_upper
5653
public :: dm_ascii_is_white_space
57-
contains
58-
pure function dm_ascii_escape(str) result(res)
59-
!! Escapes given character string by replacing ASCII control characters
60-
!! by an escape string. For instance, character `ASCII_LF` (new line)
61-
!! is turned into literal `\n`. Non-printable characters without common
62-
!! literal are replaced with `\x` plus ASCII character code in
63-
!! hexadecimal, from `\x00` to `\x1F`.
64-
character(len=*), intent(in) :: str !! Input string.
65-
character(len=:), allocatable :: res !! Output string.
66-
67-
character(len=4) :: a
68-
integer :: i, stat
69-
70-
res = ''
71-
72-
do i = 1, len_trim(str)
73-
select case (str(i:i))
74-
case (ASCII_NUL:ASCII_ACK, ASCII_SO:ASCII_SUB, ASCII_FS:ASCII_US) ! 0:6, 14:26, 28:31
75-
write (a, '("\x", z2.2)', iostat=stat) iachar(str(i:i))
76-
if (stat == 0) res = res // a
77-
case (ASCII_BEL) ! 7
78-
res = res // '\a'
79-
case (ASCII_BS) ! 8
80-
res = res // '\b'
81-
case (ASCII_TAB) ! 9
82-
res = res // '\t'
83-
case (ASCII_LF) ! 10
84-
res = res // '\n'
85-
case (ASCII_VT) ! 11
86-
res = res // '\v'
87-
case (ASCII_FF) ! 12
88-
res = res // '\f'
89-
case (ASCII_CR) ! 13
90-
res = res // '\r'
91-
case (ASCII_ESC) ! 27
92-
res = res // '\e'
93-
case (achar(92)) ! \
94-
res = res // '\\'
95-
case default
96-
res = res // str(i:i)
97-
end select
98-
end do
99-
end function dm_ascii_escape
10054

55+
public :: dm_ascii_escape
56+
public :: dm_ascii_unescape
57+
contains
10158
pure elemental logical function dm_ascii_is_alpha(a) result(is)
10259
!! Returns whether character is alpha letter.
10360
character, intent(in) :: a !! Character to check.
@@ -190,11 +147,54 @@ pure elemental logical function dm_ascii_is_white_space(a) result(is)
190147
is = ((a == ' ') .or. (ia >= int(z'09') .and. ia <= int(z'0D')))
191148
end function dm_ascii_is_white_space
192149

193-
pure function dm_ascii_unescape(str) result(res)
150+
pure function dm_ascii_escape(string) result(res)
151+
!! Escapes given character string by replacing ASCII control characters
152+
!! by an escape string. For instance, character `ASCII_LF` (new line)
153+
!! is turned into literal `\n`. Non-printable characters without common
154+
!! literal are replaced with `\x` plus ASCII character code in
155+
!! hexadecimal, from `\x00` to `\x1F`.
156+
character(len=*), intent(in) :: string !! Input string.
157+
character(len=:), allocatable :: res !! Output string.
158+
159+
character(len=4) :: a
160+
integer :: i, stat
161+
162+
res = ''
163+
164+
do i = 1, len_trim(string)
165+
select case (string(i:i))
166+
case (ASCII_NUL:ASCII_ACK, ASCII_SO:ASCII_SUB, ASCII_FS:ASCII_US) ! 0:6, 14:26, 28:31
167+
write (a, '("\x", z2.2)', iostat=stat) iachar(string(i:i))
168+
if (stat == 0) res = res // a
169+
case (ASCII_BEL) ! 7
170+
res = res // '\a'
171+
case (ASCII_BS) ! 8
172+
res = res // '\b'
173+
case (ASCII_TAB) ! 9
174+
res = res // '\t'
175+
case (ASCII_LF) ! 10
176+
res = res // '\n'
177+
case (ASCII_VT) ! 11
178+
res = res // '\v'
179+
case (ASCII_FF) ! 12
180+
res = res // '\f'
181+
case (ASCII_CR) ! 13
182+
res = res // '\r'
183+
case (ASCII_ESC) ! 27
184+
res = res // '\e'
185+
case (achar(92)) ! \
186+
res = res // '\\'
187+
case default
188+
res = res // string(i:i)
189+
end select
190+
end do
191+
end function dm_ascii_escape
192+
193+
pure function dm_ascii_unescape(string) result(res)
194194
!! Returns unescaped string of given string with escaped ASCII
195195
!! characters.
196-
character(len=*), intent(in) :: str !! Input string.
197-
character(len=:), allocatable :: res !! Output string.
196+
character(len=*), intent(in) :: string !! Input string.
197+
character(len=:), allocatable :: res !! Output string.
198198

199199
integer :: i, k, n, stat
200200
logical :: esc, npc
@@ -204,14 +204,14 @@ pure function dm_ascii_unescape(str) result(res)
204204
npc = .false. ! Non-printable character flag.
205205

206206
i = 1
207-
n = len_trim(str)
207+
n = len_trim(string)
208208

209209
do while (i <= n)
210210
if (esc) then
211211
! Escaped character literals.
212212
esc = .false.
213213

214-
select case (str(i:i))
214+
select case (string(i:i))
215215
case ('a'); res = res // ASCII_BEL
216216
case ('b'); res = res // ASCII_BS
217217
case ('t'); res = res // ASCII_TAB
@@ -221,32 +221,32 @@ pure function dm_ascii_unescape(str) result(res)
221221
case ('r'); res = res // ASCII_CR
222222
case ('e'); res = res // ASCII_ESC
223223
case ('x'); npc = .true.
224-
case (achar(92)); res = res // str(i:i)
224+
case (achar(92)); res = res // string(i:i)
225225
end select
226226
else if (npc) then
227227
! Escaped non-printable characters, from `\x00` to `\xFF`.
228228
npc = .false.
229229

230230
if (i + 1 <= n) then
231-
read (str(i:i + 1), '(z2)', iostat=stat) k
231+
read (string(i:i + 1), '(z2)', iostat=stat) k
232232

233233
if (stat == 0) then
234234
res = res // achar(k)
235235
else
236-
res = res // '\x' // str(i:i + 1)
236+
res = res // '\x' // string(i:i + 1)
237237
end if
238238

239239
i = i + 1
240240
else
241-
res = res // '\x' // str(i:i)
241+
res = res // '\x' // string(i:i)
242242
end if
243243
else
244-
if (str(i:i) == '\') then
244+
if (string(i:i) == '\') then
245245
! Found escape character.
246246
esc = .true.
247247
else
248248
! All other characters.
249-
res = res // str(i:i)
249+
res = res // string(i:i)
250250
end if
251251
end if
252252

0 commit comments

Comments
 (0)