Skip to content

Commit 317a09a

Browse files
authored
Merge pull request #316 from urbanjost/update_new
Update subcommand "new" to reflect the addition of support for the ex…
2 parents 9fe39db + 188aa74 commit 317a09a

File tree

7 files changed

+907
-205
lines changed

7 files changed

+907
-205
lines changed

fpm/src/fpm/cmd/new.f90

Lines changed: 553 additions & 110 deletions
Large diffs are not rendered by default.

fpm/src/fpm_command_line.f90

Lines changed: 93 additions & 34 deletions
Large diffs are not rendered by default.

fpm/src/fpm_filesystem.f90

Lines changed: 113 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
module fpm_filesystem
2+
use,intrinsic :: iso_fortran_env, only : stdin=>input_unit, stdout=>output_unit, stderr=>error_unit
23
use fpm_environment, only: get_os_type, &
34
OS_UNKNOWN, OS_LINUX, OS_MACOS, OS_WINDOWS, &
45
OS_CYGWIN, OS_SOLARIS, OS_FREEBSD
@@ -7,6 +8,7 @@ module fpm_filesystem
78
private
89
public :: basename, canon_path, dirname, is_dir, join_path, number_of_rows, read_lines, list_files, env_variable, &
910
mkdir, exists, get_temp_filename, windows_path, unix_path, getline, delete_file, to_fortran_name
11+
public :: fileopen, fileclose, filewrite, warnwrite
1012

1113
integer, parameter :: LINE_BUFFER_LEN = 1000
1214

@@ -73,7 +75,7 @@ function canon_path(path) result(canon)
7375
! Canonicalize path for comparison
7476
! Handles path string redundancies
7577
! Does not test existence of path
76-
!
78+
!
7779
! To be replaced by realpath/_fullname in stdlib_os
7880
!
7981
character(*), intent(in) :: path
@@ -127,7 +129,7 @@ function canon_path(path) result(canon)
127129
end if
128130

129131
end if
130-
132+
131133

132134
temp(j:j) = nixpath(i:i)
133135
j = j + 1
@@ -145,30 +147,28 @@ function dirname(path) result (dir)
145147
character(*), intent(in) :: path
146148
character(:), allocatable :: dir
147149

148-
character(:), allocatable :: file_parts(:)
149-
150150
dir = path(1:scan(path,'/\',back=.true.))
151151

152152
end function dirname
153153

154154

155-
logical function is_dir(dir)
156-
character(*), intent(in) :: dir
157-
integer :: stat
155+
logical function is_dir(dir)
156+
character(*), intent(in) :: dir
157+
integer :: stat
158158

159-
select case (get_os_type())
159+
select case (get_os_type())
160160

161161
case (OS_UNKNOWN, OS_LINUX, OS_MACOS, OS_CYGWIN, OS_SOLARIS, OS_FREEBSD)
162-
call execute_command_line("test -d " // dir , exitstat=stat)
162+
call execute_command_line("test -d " // dir , exitstat=stat)
163163

164-
case (OS_WINDOWS)
165-
call execute_command_line('cmd /c "if not exist ' // windows_path(dir) // '\ exit /B 1"', exitstat=stat)
164+
case (OS_WINDOWS)
165+
call execute_command_line('cmd /c "if not exist ' // windows_path(dir) // '\ exit /B 1"', exitstat=stat)
166166

167-
end select
167+
end select
168168

169-
is_dir = (stat == 0)
169+
is_dir = (stat == 0)
170170

171-
end function is_dir
171+
end function is_dir
172172

173173

174174
function join_path(a1,a2,a3,a4,a5) result(path)
@@ -315,7 +315,7 @@ recursive subroutine list_files(dir, files, recurse)
315315
do i=1,size(files)
316316
if (is_dir(files(i)%s)) then
317317

318-
call list_files(files(i)%s, dir_files, recurse=.true.)
318+
call list_files(files(i)%s, dir_files, recurse=.true.)
319319
sub_dir_files = [sub_dir_files, dir_files]
320320

321321
end if
@@ -347,7 +347,7 @@ function get_temp_filename() result(tempfile)
347347

348348
type(c_ptr) :: c_tempfile_ptr
349349
character(len=1), pointer :: c_tempfile(:)
350-
350+
351351
interface
352352

353353
function c_tempnam(dir,pfx) result(tmp) bind(c,name="tempnam")
@@ -389,7 +389,7 @@ function windows_path(path) result(winpath)
389389
winpath(idx:idx) = '\'
390390
idx = index(winpath,'/')
391391
end do
392-
392+
393393
end function windows_path
394394

395395

@@ -408,7 +408,7 @@ function unix_path(path) result(nixpath)
408408
nixpath(idx:idx) = '/'
409409
idx = index(nixpath,'\')
410410
end do
411-
411+
412412
end function unix_path
413413

414414

@@ -464,6 +464,101 @@ subroutine delete_file(file)
464464
end if
465465
end subroutine delete_file
466466

467+
subroutine warnwrite(fname,data)
468+
!> write trimmed character data to a file if it does not exist
469+
character(len=*),intent(in) :: fname
470+
character(len=*),intent(in) :: data(:)
471+
472+
if(.not.exists(fname))then
473+
call filewrite(fname,data)
474+
else
475+
write(stderr,'(*(g0,1x))')'<INFO> ',fname,&
476+
& 'already exists. Not overwriting'
477+
endif
478+
479+
end subroutine warnwrite
480+
481+
subroutine fileopen(filename,lun,ier)
482+
! procedure to open filename as a sequential "text" file
483+
484+
character(len=*),intent(in) :: filename
485+
integer,intent(out) :: lun
486+
integer,intent(out),optional :: ier
487+
integer :: ios
488+
character(len=256) :: message
489+
490+
message=' '
491+
ios=0
492+
if(filename.ne.' ')then
493+
open(file=filename, &
494+
& newunit=lun, &
495+
& form='formatted', & ! FORM = FORMATTED | UNFORMATTED
496+
& access='sequential', & ! ACCESS = SEQUENTIAL| DIRECT | STREAM
497+
& action='write', & ! ACTION = READ|WRITE| READWRITE
498+
& position='rewind', & ! POSITION= ASIS | REWIND | APPEND
499+
& status='new', & ! STATUS = NEW| REPLACE| OLD| SCRATCH| UNKNOWN
500+
& iostat=ios, &
501+
& iomsg=message)
502+
else
503+
lun=stdout
504+
ios=0
505+
endif
506+
if(ios.ne.0)then
507+
write(stderr,'(*(a:,1x))')&
508+
& '<ERROR> *filewrite*:',filename,trim(message)
509+
lun=-1
510+
if(present(ier))then
511+
ier=ios
512+
else
513+
stop 1
514+
endif
515+
endif
516+
517+
end subroutine fileopen
518+
519+
subroutine fileclose(lun,ier)
520+
! simple close of a LUN. On error show message and stop (by default)
521+
integer,intent(in) :: lun
522+
integer,intent(out),optional :: ier
523+
character(len=256) :: message
524+
integer :: ios
525+
if(lun.ne.-1)then
526+
close(unit=lun,iostat=ios,iomsg=message)
527+
if(ios.ne.0)then
528+
write(stderr,'(*(a:,1x))')'<ERROR> *filewrite*:',trim(message)
529+
if(present(ier))then
530+
ier=ios
531+
else
532+
stop 2
533+
endif
534+
endif
535+
endif
536+
end subroutine fileclose
537+
538+
subroutine filewrite(filename,filedata)
539+
! procedure to write filedata to file filename
540+
541+
character(len=*),intent(in) :: filename
542+
character(len=*),intent(in) :: filedata(:)
543+
integer :: lun, i, ios
544+
character(len=256) :: message
545+
call fileopen(filename,lun)
546+
if(lun.ne.-1)then ! program currently stops on error on open, but might
547+
! want it to continue so -1 (unallowed LUN) indicates error
548+
! write file
549+
do i=1,size(filedata)
550+
write(lun,'(a)',iostat=ios,iomsg=message)trim(filedata(i))
551+
if(ios.ne.0)then
552+
write(stderr,'(*(a:,1x))')&
553+
& '<ERROR> *filewrite*:',filename,trim(message)
554+
stop 4
555+
endif
556+
enddo
557+
endif
558+
! close file
559+
call fileclose(lun)
560+
561+
end subroutine filewrite
467562

468563
pure function to_fortran_name(string) result(res)
469564
! Returns string with special characters replaced with an underscore.
@@ -475,5 +570,4 @@ pure function to_fortran_name(string) result(res)
475570
res = replace(string, SPECIAL_CHARACTERS, '_')
476571
end function to_fortran_name
477572

478-
479573
end module fpm_filesystem

fpm/src/fpm_source_parsing.f90

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
!>
77
!> Both functions additionally calculate and store a file digest (hash) which
88
!> is used by the backend ([[fpm_backend]]) to skip compilation of unmodified sources.
9-
!>
10-
!> Both functions return an instance of the [[srcfile_t]] type.
9+
!>
10+
!> Both functions return an instance of the [[srcfile_t]] type.
1111
!>
1212
!> For more information, please read the documentation for each function:
1313
!>
@@ -38,7 +38,7 @@ module fpm_source_parsing
3838
contains
3939

4040
!> Parsing of free-form fortran source files
41-
!>
41+
!>
4242
!> The following statements are recognised and parsed:
4343
!>
4444
!> - `Module`/`submodule`/`program` declaration
@@ -171,7 +171,7 @@ function parse_f_source(f_filename,error) result(f_source)
171171
if (index(adjustl(file_lines(i)%s(ic+7:)),'"') == 1 .or. &
172172
index(adjustl(file_lines(i)%s(ic+7:)),"'") == 1 ) then
173173

174-
174+
175175
n_include = n_include + 1
176176

177177
if (pass == 2) then
@@ -264,7 +264,7 @@ function parse_f_source(f_filename,error) result(f_source)
264264
if (index(temp_string,':') > 0) then
265265

266266
temp_string = temp_string(index(temp_string,':')+1:)
267-
267+
268268
end if
269269

270270
if (.not.validate_name(temp_string)) then
@@ -288,7 +288,7 @@ function parse_f_source(f_filename,error) result(f_source)
288288

289289
temp_string = lower(split_n(file_lines(i)%s,n=2,delims=' ',stat=stat))
290290
if (stat == 0) then
291-
291+
292292
if (scan(temp_string,'=(')>0 ) then
293293
! Ignore:
294294
! program =*
@@ -343,7 +343,7 @@ function validate_name(name) result(valid)
343343
(name(i:i) >= '0' .and. name(i:i) <= '9').or. &
344344
(lower(name(i:i)) >= 'a' .and. lower(name(i:i)) <= 'z').or. &
345345
name(i:i) == '_') ) then
346-
346+
347347
valid = .false.
348348
return
349349
end if
@@ -359,7 +359,7 @@ end function parse_f_source
359359

360360

361361
!> Parsing of c source files
362-
!>
362+
!>
363363
!> The following statements are recognised and parsed:
364364
!>
365365
!> - `#include` preprocessor statement
@@ -396,17 +396,17 @@ function parse_c_source(c_filename,error) result(c_source)
396396
c_source%unit_type = FPM_UNIT_UNKNOWN
397397
return
398398
end if
399-
399+
400400
c_source%digest = fnv_1a(file_lines)
401-
401+
402402
do pass = 1,2
403403
n_include = 0
404404
file_loop: do i=1,size(file_lines)
405405

406406
! Process 'INCLUDE' statements
407407
if (index(adjustl(lower(file_lines(i)%s)),'#include') == 1 .and. &
408408
index(file_lines(i)%s,'"') > 0) then
409-
409+
410410
n_include = n_include + 1
411411

412412
if (pass == 2) then
@@ -440,7 +440,7 @@ end function parse_c_source
440440
!> n=0 will return the last item
441441
!> n=-1 will return the penultimate item etc.
442442
!>
443-
!> stat = 1 on return if the index
443+
!> stat = 1 on return if the index
444444
!> is not found
445445
!>
446446
function split_n(string,delims,n,stat) result(substring)
@@ -476,4 +476,4 @@ function split_n(string,delims,n,stat) result(substring)
476476

477477
end function split_n
478478

479-
end module fpm_source_parsing
479+
end module fpm_source_parsing

0 commit comments

Comments
 (0)