Skip to content

Commit 1cd0d03

Browse files
committed
simplify new_test.f90 using functions already existing in fpm(1) source
1 parent 5846d3c commit 1cd0d03

File tree

2 files changed

+42
-189
lines changed

2 files changed

+42
-189
lines changed

fpm/src/fpm_command_line.f90

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -130,14 +130,14 @@ subroutine get_command_line_settings(cmd_settings)
130130
case(1)
131131
write(stderr,'(*(g0,/))')'ERROR: directory name required'
132132
write(stderr,'(*(7x,g0,/))') &
133-
& 'usage: fpm new NAME [--lib|--src] [--app] [--test] [--backfill]'
133+
& 'USAGE: fpm new NAME [--lib|--src] [--app] [--test] [--backfill]'
134134
stop 1
135135
case(2)
136136
name=trim(unnamed(2))
137137
case default
138138
write(stderr,'(g0)')'ERROR: only one directory name allowed'
139139
write(stderr,'(7x,g0)') &
140-
& 'usage: fpm new NAME [--lib|--src] [--app] [--test] [--backfill]'
140+
& 'USAGE: fpm new NAME [--lib|--src] [--app] [--test] [--backfill]'
141141
stop 2
142142
end select
143143
!! canon_path is not converting ".", etc.
@@ -648,7 +648,7 @@ subroutine set_help()
648648
help_install=[character(len=80) :: &
649649
' fpm(1) subcommand "install" ', &
650650
' ', &
651-
' Usage: fpm install NAME ', &
651+
' USAGE: fpm install NAME ', &
652652
'' ]
653653
end subroutine set_help
654654

fpm/test/new_test/new_test.f90

Lines changed: 39 additions & 186 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
11
program new_test
22
use,intrinsic :: iso_fortran_env, only : stdin=>input_unit, stdout=>output_unit, stderr=>error_unit
3-
use fpm_filesystem, only : is_dir, list_files, exists
4-
use fpm_strings, only : string_t
3+
use fpm_filesystem, only : is_dir, list_files, exists, windows_path
4+
use fpm_strings, only : string_t, operator(.in.)
55
use fpm_environment, only : run, get_os_type
66
use fpm_environment, only : OS_UNKNOWN, OS_LINUX, OS_MACOS, OS_CYGWIN, OS_SOLARIS, OS_FREEBSD, OS_WINDOWS
77
type(string_t), allocatable :: file_names(:)
8-
character(len=:), allocatable :: fnames(:)
9-
character(len=:), allocatable :: directory
108
integer :: i, j, k
119
character(len=*),parameter :: cmdpath = 'build/gfortran_debug/app/fpm'
1210
character(len=:),allocatable :: path
@@ -31,6 +29,7 @@ program new_test
3129
character(len=:),allocatable :: directories(:)
3230
character(len=:),allocatable :: expected(:)
3331
logical,allocatable :: tally(:)
32+
logical :: IS_OS_WINDOWS
3433
write(*,'(g0:,1x)')'TEST new SUBCOMMAND (draft):'
3534
allocate(tally(0))
3635
directories=[character(len=80) :: 'A','B','C','D','E','F','G','BB','CC']
@@ -45,19 +44,21 @@ program new_test
4544
enddo
4645

4746
!! SEE IF EXPECTED FILES ARE GENERATED
48-
!! DOS versus POSIX filenames
49-
! assuming fpm command is in path and the new version
47+
!! Issues:
48+
!! o assuming fpm command is in expected path and the new version
49+
!! o DOS versus POSIX filenames
50+
is_os_windows=.false.
5051
select case (get_os_type())
5152
case (OS_UNKNOWN, OS_LINUX, OS_MACOS, OS_CYGWIN, OS_SOLARIS, OS_FREEBSD)
5253
path=cmdpath
5354
case (OS_WINDOWS)
54-
path=u2d(cmdpath)
55+
path=windows_path(path)
56+
is_os_windows=.true.
5557
case default
5658
write(*,*)'ERROR: unknown OS. Stopping test'
5759
stop 2
5860
end select
59-
60-
61+
! execute the fpm(1) commands
6162
do i=1,size(cmds)
6263
message=''
6364
write(*,*)path//' '//cmds(i)
@@ -80,207 +81,59 @@ program new_test
8081
write(*,*)'ERROR:',trim( directories(i) ),' is not a directory'
8182
else
8283
select case(directories(i))
83-
case('A')
84-
expected=[ character(len=80)::&
84+
case('A'); expected=[ character(len=80)::&
8585
&'A/app','A/fpm.toml','A/README.md','A/src','A/test','A/app/main.f90','A/src/A.f90','A/test/main.f90']
86-
case('B')
87-
expected=[ character(len=80)::&
86+
case('B'); expected=[ character(len=80)::&
8887
&'B/fpm.toml','B/README.md','B/src','B/src/B.f90']
89-
case('C')
90-
expected=[ character(len=80)::&
88+
case('C'); expected=[ character(len=80)::&
9189
&'C/app','C/fpm.toml','C/README.md','C/app/main.f90']
92-
case('D')
93-
expected=[ character(len=80)::&
90+
case('D'); expected=[ character(len=80)::&
9491
&'D/fpm.toml','D/README.md','D/test','D/test/main.f90']
95-
case('E')
96-
expected=[ character(len=80)::&
92+
case('E'); expected=[ character(len=80)::&
9793
&'E/fpm.toml','E/README.md','E/src','E/test','E/src/E.f90','E/test/main.f90']
98-
case('F')
99-
expected=[ character(len=80)::&
94+
case('F'); expected=[ character(len=80)::&
10095
&'F/app','F/fpm.toml','F/README.md','F/src','F/app/main.f90','F/src/F.f90']
101-
case('G')
102-
expected=[ character(len=80)::&
96+
case('G'); expected=[ character(len=80)::&
10397
&'G/app','G/fpm.toml','G/README.md','G/test','G/app/main.f90','G/test/main.f90']
104-
case('BB')
105-
expected=[ character(len=80)::&
98+
case('BB'); expected=[ character(len=80)::&
10699
&'BB/fpm.toml','BB/README.md','BB/src','BB/test','BB/src/BB.f90','BB/test/main.f90']
107-
case('CC')
108-
expected=[ character(len=80)::&
100+
case('CC'); expected=[ character(len=80)::&
109101
&'CC/app','CC/fpm.toml','CC/README.md','CC/src','CC/test','CC/app/main.f90','CC/src/CC.f90','CC/test/main.f90']
110102
case default
111103
write(*,*)'ERROR: internal error. unknown directory name ',trim(directories(i))
112104
stop 4
113105
end select
114106
!! MSwindows has hidden files in it
107+
!! Warning: This only looks for expected files. If there are more files than expected it does not fail
115108
call list_files(trim(directories(i)), file_names,recurse=.true.)
116-
if(allocated(fnames))deallocate(fnames)
117-
allocate(character(len=0) :: fnames(0))
118-
do j=1,size(file_names)
119-
if(file_names(j)%s(1:1).eq.'.'.or.index(file_names(j)%s,'/.').ne.0.or.index(file_names(j)%s,'\.').ne.0)cycle
120-
fnames=[character(len=max(len(fnames),len(file_names(j)%s))) :: fnames,file_names(j)%s]
121-
enddo
122-
write(*,'(*(g0))',advance='no')'>>>DIRECTORY ',trim(directories(i)),': '
123-
write(*,'(*(g0:,", "))')( file_names(j)%s, j=1,size(file_names) )
124-
if(size(expected).ne.size(fnames))then
125-
write(*,*)'unexpected number of files in file list=',size(fnames),' expected ',size(expected)
126-
tally=[tally,.false.]
127-
cycle TESTS
128-
else
129-
select case (get_os_type())
130-
case (OS_UNKNOWN, OS_LINUX, OS_MACOS, OS_CYGWIN, OS_SOLARIS, OS_FREEBSD)
131-
case (OS_WINDOWS)
132-
do j=1,size(expected)
133-
expected(j)=u2d(expected(j))
134-
enddo
135-
case default
136-
write(*,*)'ERROR: unknown OS. Stopping test'
137-
stop 3
138-
end select
139-
do j=1,size(expected)
140-
if( .not.any(fnames(j)==expected) )then
141-
tally=[tally,.false.]
142-
write(*,'("ERROR: EXPECTED ",*(g0:,", "))')( trim(expected(k)), k=1,size(expected) )
143-
write(*,'(*(g0))')' NO MATCH FOR ',fnames(j)
144-
cycle TESTS
145-
endif
146-
enddo
147-
tally=[tally,.true.]
109+
110+
if(size(expected).ne.size(file_names))then
111+
write(*,*)'WARNING: unexpected number of files in file list=',size(file_names),' expected ',size(expected)
112+
write(*,'("EXPECTED: ",*(g0:,","))')(trim(expected(j)),j=1,size(expected))
113+
write(*,'("FOUND: ",*(g0:,","))')(trim(file_names(j)%s),j=1,size(file_names))
148114
endif
115+
116+
do j=1,size(expected)
117+
118+
if(is_os_windows) expected(j)=windows_path(expected(j))
119+
if( .not.(trim(expected(j)).in.file_names) )then
120+
tally=[tally,.false.]
121+
write(*,'("ERROR: FOUND ",*(g0:,", "))')( trim(file_names(k)%s), k=1,size(file_names) )
122+
write(*,'(*(g0))')' BUT NO MATCH FOR ',expected(j)
123+
tally=[tally,.false.]
124+
cycle TESTS
125+
endif
126+
enddo
127+
tally=[tally,.true.]
149128
endif
150129
enddo TESTS
130+
151131
write(*,'("TALLY=",*(g0))')tally
152132
if(all(tally))then
153133
write(*,'(*(g0))')'PASSED: all ',count(tally),' tests passed '
154134
else
155135
write(*,*)'FAILED: PASSED=',count(tally),' FAILED=',count(.not.tally)
156136
stop 5
157137
endif
158-
!-----------------------------------------------------------------------------------------------------------------------------------
159-
contains
160-
!-----------------------------------------------------------------------------------------------------------------------------------
161-
function u2d(pathname) result(dos)
162-
! simplistically replace / with \ to make posix pathname DOS pathname
163-
character(len=*),intent(in) :: pathname
164-
character(len=:),allocatable :: dos
165-
integer :: i
166-
dos=pathname
167-
do i=1,len(pathname)
168-
if(pathname(i:i).eq.'/')dos(i:i)='\'
169-
enddo
170-
end function u2d
171-
!-----------------------------------------------------------------------------------------------------------------------------------
172-
function djb2_hash_arr(chars,continue) result(hash_128)
173-
use,intrinsic :: ISO_FORTRAN_ENV, only : int8,int16,int32,int64
174-
implicit none
175-
176-
!$@(#) djb2_hash(3fp): DJB2 hash of array (algorithm by Daniel J. Bernstein ) for character array
177-
178-
character(len=1),intent(in) :: chars(:)
179-
logical,intent(in),optional :: continue
180-
integer :: i
181-
integer(kind=int64) :: hash_128
182-
integer(kind=int64),save :: hash_64=5381
183-
184-
if(present(continue))then
185-
hash_64 = hash_64
186-
else
187-
hash_64 = 5381_int64
188-
endif
189-
do i=1,size(chars)
190-
hash_64 = (ishft(hash_64,5) + hash_64) + ichar(chars(i),kind=int64)
191-
enddo
192-
hash_128=transfer([hash_64,0_int64],hash_128)
193-
DEBUG : block
194-
integer :: ios
195-
write(6,'("*djb2_hash* hashing string=",*(a))',advance='no')chars
196-
write(6,'(1x,"hash=",i0,1x,"hex hash=",z32.32)')hash_128,hash_128
197-
flush(6,iostat=ios)
198-
endblock DEBUG
199-
end function djb2_hash_arr
200-
!-----------------------------------------------------------------------------------------------------------------------------------
201-
subroutine slurp(filename,text,length,lines)
202-
use,intrinsic :: iso_fortran_env, only : stdin=>input_unit, stdout=>output_unit, stderr=>error_unit
203-
implicit none
204-
205-
!$@(#) M_io::slurp(3f): allocate text array and read file filename into it
206-
207-
class(*),intent(in) :: filename ! filename to shlep
208-
character(len=1),allocatable,intent(out) :: text(:) ! array to hold file
209-
integer,intent(out),optional :: length ! length of longest line
210-
integer,intent(out),optional :: lines ! number of lines
211138

212-
integer :: nchars=0 ! holds size of file
213-
integer :: igetunit ! use newunit=igetunit in f08
214-
integer :: ios=0 ! used for I/O error status
215-
integer :: length_local
216-
integer :: lines_local
217-
integer :: i
218-
integer :: icount
219-
character(len=256) :: message
220-
character(len=4096) :: local_filename
221-
222-
length_local=0
223-
lines_local=0
224-
225-
message=''
226-
select type(FILENAME)
227-
type is (character(len=*))
228-
open(newunit=igetunit, file=trim(filename), action="read", iomsg=message,&
229-
&form="unformatted", access="stream",status='old',iostat=ios)
230-
local_filename=filename
231-
type is (integer)
232-
rewind(unit=filename,iostat=ios,iomsg=message)
233-
write(local_filename,'("unit ",i0)')filename
234-
igetunit=filename
235-
end select
236-
237-
if(ios.eq.0)then ! if file was successfully opened
238-
239-
inquire(unit=igetunit, size=nchars)
240-
241-
if(nchars.le.0)then
242-
call stderr_local( '*slurp* empty file '//trim(local_filename) )
243-
return
244-
endif
245-
! read file into text array
246-
!
247-
if(allocated(text))deallocate(text) ! make sure text array not allocated
248-
allocate ( text(nchars) ) ! make enough storage to hold file
249-
read(igetunit,iostat=ios,iomsg=message) text ! load input file -> text array
250-
if(ios.ne.0)then
251-
call stderr_local( '*slurp* bad read of '//trim(local_filename)//':'//trim(message) )
252-
endif
253-
else
254-
call stderr_local('*slurp* '//message)
255-
allocate ( text(0) ) ! make enough storage to hold file
256-
endif
257-
258-
close(iostat=ios,unit=igetunit) ! close if opened successfully or not
259-
260-
if(present(lines).or.present(length))then ! get length of longest line and number of lines
261-
icount=0
262-
do i=1,nchars
263-
if(text(i).eq.NEW_LINE('A'))then
264-
lines_local=lines_local+1
265-
length_local=max(length_local,icount)
266-
icount=0
267-
endif
268-
icount=icount+1
269-
enddo
270-
if(nchars.ne.0)then
271-
if(text(nchars).ne.NEW_LINE('A'))then
272-
lines_local=lines_local+1
273-
length_local=max(length_local,icount)
274-
endif
275-
endif
276-
if(present(lines))lines=lines_local
277-
if(present(length))length=length_local
278-
endif
279-
end subroutine slurp
280-
!-----------------------------------------------------------------------------------------------------------------------------------
281-
subroutine stderr_local(message)
282-
character(len=*) :: message
283-
write(stderr,'(a)')trim(message) ! write message to standard error
284-
end subroutine stderr_local
285-
!-----------------------------------------------------------------------------------------------------------------------------------
286139
end program new_test

0 commit comments

Comments
 (0)