Skip to content

Commit 15b6d79

Browse files
committed
use custom writer
1 parent 1be09c9 commit 15b6d79

File tree

2 files changed

+94
-22
lines changed

2 files changed

+94
-22
lines changed

src/fpm_backend_output.f90

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ subroutine output_write_compile_commands(progress,error)
193193
! Write compile commands
194194
path = join_path('build','compile_commands.json')
195195

196-
call progress%compile_commands%dump(file=path, error=error, json=.true.)
196+
call progress%compile_commands%write(filename=path, error=error)
197197

198198
end subroutine output_write_compile_commands
199199

src/fpm_compile_commands.F90

Lines changed: 93 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
!># Store compiler commands in a `compile_commands.json` table
22
module fpm_compile_commands
3-
use fpm_toml, only: serializable_t, set_string, set_list, get_value, get_list, toml_table, add_table
3+
use fpm_toml, only: serializable_t, set_string, set_value, set_list, get_value, get_list, toml_table, add_table, toml_array, add_array, toml_stat
4+
use jonquil, only: json_serialize, json_ser_config
45
use fpm_strings, only: string_t, operator(==)
56
use fpm_error, only: error_t, syntax_error, fatal_error
67
use fpm_os, only: get_current_directory
@@ -34,6 +35,7 @@ module fpm_compile_commands
3435
!> Operation
3536
procedure :: destroy => cct_destroy
3637
procedure :: register => cct_register
38+
procedure :: write => cct_write
3739

3840
!> Serialization interface
3941
procedure :: serializable_is_same => cct_is_same
@@ -110,47 +112,117 @@ logical function compile_command_is_same(this,that)
110112
compile_command_is_same = .true.
111113

112114
end function compile_command_is_same
113-
114-
!> Dump compile_command_table_t to toml table
115-
subroutine cct_dump_toml(self, table, error)
116-
115+
116+
!> Dump compile_command_table_t to a toml array
117+
subroutine cct_dump_array(self, array, error)
117118
!> Instance of the serializable object
118119
class(compile_command_table_t), intent(inout) :: self
119120

120121
!> Data structure
121-
type(toml_table), intent(inout) :: table
122+
type(toml_array), intent(inout) :: array
122123

123124
!> Error handling
124-
type(error_t), allocatable, intent(out) :: error
125+
type(error_t), allocatable, intent(out) :: error
125126

126-
integer :: ii
127-
type(toml_table), pointer :: ptr
128-
character(64) :: name
127+
integer :: ii, stat
128+
type(toml_table), pointer :: item
129129

130130
if (.not.allocated(self%command)) return
131131

132132
do ii = 1, size(self%command)
133133
associate (cmd => self%command(ii))
134134

135135
! Set node for this command
136-
write(name,1) ii
137-
call add_table(table, trim(name), ptr)
138-
if (.not. associated(ptr)) then
139-
call fatal_error(error, "compile_command_table_t cannot create entry for "//trim(name))
136+
call add_table(array, item, stat)
137+
if (stat /= toml_stat%success) then
138+
call fatal_error(error, "Cannot store entry in compile_command_table_t array")
140139
return
141-
end if
142-
143-
! Dump node
144-
call cmd%dump_to_toml(ptr, error)
140+
end if
141+
call cmd%dump_to_toml(item, error)
145142
if (allocated(error)) return
146-
143+
147144
endassociate
148-
end do
145+
end do
146+
147+
end subroutine cct_dump_array
149148

150-
1 format('compile_command_',i0)
149+
!> Dump compile_command_table_t to toml table
150+
subroutine cct_dump_toml(self, table, error)
151+
152+
!> Instance of the serializable object
153+
class(compile_command_table_t), intent(inout) :: self
154+
155+
!> Data structure
156+
type(toml_table), intent(inout) :: table
157+
158+
!> Error handling
159+
type(error_t), allocatable, intent(out) :: error
160+
161+
integer :: stat, ii
162+
type(toml_array), pointer :: array
163+
164+
if (.not.allocated(self%command)) return
165+
166+
! Create array
167+
call add_array(table, 'compile_commands', array, stat=stat)
168+
if (stat/=toml_stat%success .or. .not.associated(array)) then
169+
call fatal_error(error,"compile_command_table_t cannot create entry")
170+
return
171+
end if
172+
173+
! Dump to it
174+
call cct_dump_array(self, array, error)
151175

152176
end subroutine cct_dump_toml
153177

178+
!> Write compile_commands.json file. Because Jonquil does not support non-named arrays,
179+
!> create a custom json here.
180+
subroutine cct_write(self, filename, error)
181+
182+
!> Instance of the serializable object
183+
class(compile_command_table_t), intent(inout) :: self
184+
185+
!> The file name
186+
character(*), intent(in) :: filename
187+
188+
!> Error handling
189+
type(error_t), allocatable, intent(out) :: error
190+
191+
type(toml_array) :: array
192+
type(json_ser_config) :: cfg
193+
integer :: stat, lun
194+
195+
! Init array
196+
array = toml_array()
197+
198+
! Dump information to the array
199+
call cct_dump_array(self, array, error)
200+
if (allocated(error)) return
201+
202+
! Open file and write to it
203+
open(newunit=lun,file=filename,form='formatted',action='write',status='replace',iostat=stat)
204+
if (stat/=0) then
205+
call fatal_error(error, 'cannot open file '//filename//' for writing')
206+
return
207+
end if
208+
209+
! Ensure the array has no key
210+
if (allocated(array%key)) deallocate(array%key)
211+
212+
cfg%indent = repeat(' ',4)
213+
write (lun, '(A)', iostat=stat, err=1) '{'
214+
write (lun, '(A)', iostat=stat, err=1) json_serialize(array, cfg)
215+
write (lun, '(A)', iostat=stat, err=1) '}'
216+
217+
close(lun,iostat=stat)
218+
219+
1 if (stat/=0) then
220+
call fatal_error(error, 'cannot close file '//filename//' after writing')
221+
return
222+
end if
223+
224+
end subroutine cct_write
225+
154226
!> Cleanup a compile command table
155227
elemental subroutine cct_destroy(self)
156228

0 commit comments

Comments
 (0)