Skip to content

Commit 58811b2

Browse files
committed
register a compile command
1 parent 3c950a8 commit 58811b2

File tree

2 files changed

+81
-4
lines changed

2 files changed

+81
-4
lines changed

fpm.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ fortran-regex.tag = "1.1.2"
2121
jonquil.git = "https://github.com/toml-f/jonquil"
2222
jonquil.rev = "4fbd4cf34d577c0fd25e32667ee9e41bf231ece8"
2323
fortran-shlex.git = "https://github.com/perazz/fortran-shlex"
24-
fortran-shlex.tag = "1.0.1"
24+
fortran-shlex.tag = "1.2.1"
2525

2626
[[test]]
2727
name = "cli-test"

src/fpm_compile_commands.F90

Lines changed: 80 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
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
3+
use fpm_toml, only: serializable_t, set_string, set_list, get_value, get_list, toml_table, add_table
44
use fpm_strings, only: string_t, operator(==)
5-
use fpm_error, only: error_t
5+
use fpm_error, only: error_t, syntax_error, fatal_error
6+
use fpm_os, only: get_current_directory
7+
use shlex_module, only: shlex_split => split
68
implicit none
79

810
!> Definition of a build command
@@ -25,11 +27,14 @@ module fpm_compile_commands
2527

2628
type, extends(serializable_t) :: compile_command_table_t
2729

28-
2930
type(compile_command_t), allocatable :: command(:)
3031

3132
contains
3233

34+
!> Operation
35+
procedure :: destroy => cct_destroy
36+
procedure :: register => cct_register
37+
3338
!> Serialization interface
3439
procedure :: serializable_is_same => cct_is_same
3540
procedure :: dump_to_toml => cct_dump_toml
@@ -145,7 +150,79 @@ subroutine cct_dump_toml(self, table, error)
145150
1 format('compile_command_',i0)
146151

147152
end subroutine cct_dump_toml
153+
154+
!> Cleanup a compile command table
155+
elemental subroutine cct_destroy(self)
156+
157+
!> Instance of the serializable object
158+
class(compile_command_table_t), intent(inout) :: self
159+
160+
if (allocated(self%command)) deallocate(self%command)
161+
162+
end subroutine cct_destroy
163+
164+
!> Register a new compile command
165+
subroutine cct_register(self, command, error)
148166

167+
!> Instance of the serializable object
168+
class(compile_command_table_t), intent(inout) :: self
169+
170+
!> Data structure
171+
character(len=*), intent(in) :: command
172+
173+
!> Error handling
174+
type(error_t), allocatable, intent(out) :: error
175+
176+
! Local variables
177+
type(compile_command_t) :: cmd
178+
character(len=:), allocatable :: args(:), cwd, source_file
179+
logical :: sh_success
180+
integer :: i,n
181+
182+
! Early check
183+
if (len_trim(command) <= 0) then
184+
call syntax_error(error, "compile_command_table_t trying to register an empty command")
185+
return
186+
end if
187+
188+
! Tokenize the input command into args(:)
189+
args = shlex_split(command, join_spaced=.true., keep_quotes=.true., success=sh_success)
190+
n = size(args)
191+
192+
if (n==0 .or. .not.sh_success) then
193+
call syntax_error(error, "compile_command_table_t failed tokenizing: <"//command//">")
194+
return
195+
end if
196+
197+
! Get current working directory
198+
call get_current_directory(cwd, error)
199+
if (allocated(error)) return
200+
201+
! Try to find the source file
202+
allocate(character(len=0) :: source_file)
203+
find_source_file: do i = 1, n-1
204+
if (args(i) == "-c") then
205+
source_file = args(i+1)
206+
exit find_source_file
207+
end if
208+
end do find_source_file
209+
210+
! Fallback: use last argument if not found
211+
if (len_trim(source_file)==0) source_file = args(n)
212+
213+
! Fill in the compile_command_t
214+
cmd = compile_command_t(directory = string_t(cwd), &
215+
arguments = [(string_t(trim(args(i))), i=1,n)], &
216+
file = string_t(source_file))
217+
218+
if (allocated(self%command)) then
219+
self%command = [self%command, cmd]
220+
else
221+
allocate(self%command(1), source=cmd)
222+
end if
223+
224+
end subroutine cct_register
225+
149226
!> Read compile_command_table_t from toml table (no checks made at this stage)
150227
subroutine cct_load_toml(self, table, error)
151228

0 commit comments

Comments
 (0)