1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
|
!> A one-shot command-line front end, useful for confirming that an instance
!> answers: `cepis --base-url http://localhost:8080 01001000`.
program main
use, intrinsic :: iso_fortran_env, only: real64, output_unit, error_unit
use cepis
implicit none
character(len=:), allocatable :: url, message
character(len=:), allocatable :: ceps(:)
type(cepis_client) :: client
integer :: status
logical :: want_health
call parse_arguments(url, ceps, want_health)
if (len(url) > 0) then
call cepis_client_init(client, status, message, base_url=url)
else
call cepis_client_init(client, status, message)
end if
if (status /= CEPIS_OK) then
write (error_unit, '(A)') 'cepis: '//message
stop 2
end if
if (want_health) then
call show_health(client)
else if (size(ceps) == 1) then
call show_one(client, trim(ceps(1)))
else
call show_many(client, ceps)
end if
contains
subroutine usage()
write (error_unit, '(A)') 'usage: cepis [--base-url URL] CEP [CEP ...]'
write (error_unit, '(A)') ' cepis [--base-url URL] --health'
stop 2
end subroutine usage
subroutine parse_arguments(base, values, health)
character(len=:), allocatable, intent(out) :: base
character(len=:), allocatable, intent(out) :: values(:)
logical, intent(out) :: health
character(len=4096) :: argument
character(len=64) :: collected(256)
integer :: count, i, length, total
base = ''
health = .false.
count = 0
total = command_argument_count()
i = 1
do while (i <= total)
call get_command_argument(i, argument, length)
if (argument(1:length) == '--health') then
health = .true.
else if (argument(1:length) == '--base-url') then
i = i + 1
if (i > total) call usage()
call get_command_argument(i, argument, length)
base = argument(1:length)
else if (argument(1:length) == '--help' .or. argument(1:length) == '-h') then
call usage()
else
if (count >= size(collected)) call usage()
count = count + 1
collected(count) = argument(1:min(length, len(collected)))
end if
i = i + 1
end do
if (.not. health .and. count == 0) call usage()
allocate (character(len=64) :: values(count))
do i = 1, count
values(i) = collected(i)
end do
end subroutine parse_arguments
subroutine show_health(handle)
type(cepis_client), intent(in) :: handle
type(cepis_health) :: report
integer :: code
character(len=:), allocatable :: detail
call handle%health(report, code, detail)
if (code /= CEPIS_OK) then
write (error_unit, '(A)') 'cepis: '//cepis_status_name(code)//': '//detail
stop 1
end if
write (output_unit, '(A)') 'status '//report%status
write (output_unit, '(A)') 'dne '//report%dne
write (output_unit, '(A,I0)') 'ceps ', report%ceps
write (output_unit, '(A,I0)') 'geo ', report%geo
write (output_unit, '(A)') 'base_gerada_em '//report%base_gerada_em
end subroutine show_health
subroutine show_one(handle, cep)
type(cepis_client), intent(in) :: handle
character(len=*), intent(in) :: cep
type(cepis_address) :: address
integer :: code
character(len=:), allocatable :: detail
call handle%lookup(cep, address, code, detail)
if (code /= CEPIS_OK) then
write (error_unit, '(A)') 'cepis: '//cepis_status_name(code)//': '//detail
if (address%has_faixa) call show_faixa(address%faixa)
stop 1
end if
write (output_unit, '(A)') 'cep '//address%formatted_cep()
write (output_unit, '(A)') 'logradouro '//address%logradouro
write (output_unit, '(A)') 'complemento '//address%complemento
write (output_unit, '(A)') 'unidade '//address%unidade
write (output_unit, '(A)') 'bairro '//address%bairro
write (output_unit, '(A)') 'localidade '//address%localidade
write (output_unit, '(A)') 'uf '//address%uf
write (output_unit, '(A)') 'estado '//address%estado
write (output_unit, '(A)') 'regiao '//address%regiao
write (output_unit, '(A)') 'ibge '//address%ibge
write (output_unit, '(A)') 'gia '//address%gia
write (output_unit, '(A)') 'ddd '//address%ddd
write (output_unit, '(A)') 'siafi '//address%siafi
if (address%has_geo) then
write (output_unit, '(A,F0.6,A,F0.6,A,I0,A)') 'geo ', &
address%geo%lat, ', ', address%geo%lon, ' (', address%geo%raio_m, &
' m, '//address%geo%precisao//')'
end if
end subroutine show_one
!> What the API knows about a CEP that does not exist: the municipality it
!> would have fallen under. The lookup still failed, so this goes to stderr
!> with the error, and the exit status stays 1.
subroutine show_faixa(faixa)
type(cepis_faixa), intent(in) :: faixa
write (error_unit, '(A)') ' faixa '//faixa%localidade//'/'// &
faixa%uf//' ibge '//faixa%ibge
write (error_unit, '(A,I0,A)') ' existentes '//faixa%formatted_cep_ini()// &
'..'//faixa%formatted_cep_fim()//' ', faixa%ceps, &
' CEPs (the range is sparse; most numbers in it do not exist)'
end subroutine show_faixa
subroutine show_many(handle, values)
type(cepis_client), intent(in) :: handle
character(len=*), intent(in) :: values(:)
type(cepis_address), allocatable :: addresses(:)
integer :: code, i
character(len=:), allocatable :: detail
call handle%lookup_many(values, addresses, code, detail)
if (code /= CEPIS_OK) then
write (error_unit, '(A)') 'cepis: '//cepis_status_name(code)//': '//detail
stop 1
end if
do i = 1, size(addresses)
if (addresses(i)%found) then
write (output_unit, '(A)') trim(values(i))//' '// &
addresses(i)%localidade//'/'//addresses(i)%uf//' '// &
addresses(i)%logradouro
else
write (output_unit, '(A)') trim(values(i))//' not found'
end if
end do
end subroutine show_many
end program main
|