11module test_filesystem
22 use testsuite, only: new_unittest, unittest_t, error_t, test_failed
33 use fpm_filesystem, only: canon_path, is_dir, mkdir, os_delete_dir, &
4- join_path, is_absolute_path, get_home
4+ join_path, is_absolute_path, get_home, &
5+ delete_file, read_lines, get_temp_filename
56 use fpm_environment, only: OS_WINDOWS, get_os_type, os_is_unix
7+ use fpm_strings, only: string_t, split_lines_first_last
68 implicit none
79 private
810
@@ -20,7 +22,9 @@ subroutine collect_filesystem(tests)
2022 & new_unittest(" canon-path" , test_canon_path), &
2123 & new_unittest(" create-delete-directory" , test_mkdir_rmdir), &
2224 & new_unittest(" test-is-absolute-path" , test_is_absolute_path), &
23- & new_unittest(" test-get-home" , test_get_home) &
25+ & new_unittest(" test-get-home" , test_get_home), &
26+ & new_unittest(" test-split-lines-first-last" , test_split_lines_first_last), &
27+ & new_unittest(" test-crlf-lines" , test_dir_with_crlf) &
2428 ]
2529
2630 end subroutine collect_filesystem
@@ -289,5 +293,141 @@ subroutine test_get_home(error)
289293 end if
290294
291295 end subroutine test_get_home
296+
297+ ! Test line splitting on MS windows
298+ subroutine test_split_lines_first_last (error )
299+ ! > Error handling
300+ type (error_t), allocatable , intent (out ) :: error
301+
302+ character , parameter :: CR = achar (13 )
303+ character , parameter :: LF = new_line(' A' )
304+ character (* ), parameter :: CRLF = CR// LF
305+ integer , allocatable :: first(:), last(:)
306+
307+ call split_lines_first_last(CR// LF// ' line1' // CR// ' line2' // LF// ' line3' // CR// LF// ' hello' , first, last)
308+ if (.not. (all (first==[3 ,9 ,15 ,22 ]) .and. all (last==[7 ,13 ,19 ,26 ]))) then
309+ call test_failed(error, " Test split_lines_first_last #1 failed" )
310+ return
311+ end if
312+
313+ call split_lines_first_last(' single_line' , first, last)
314+ if (.not. (all (first==[1 ]) .and. all (last==[11 ]))) then
315+ call test_failed(error, " Test split_lines_first_last #2 failed" )
316+ return
317+ end if
318+
319+ call split_lines_first_last(CR// LF// CR// LF// ' test' , first, last)
320+ if (.not. (all (first == [5 ]) .and. all (last == [8 ]))) then
321+ call test_failed(error, " Test split_lines_first_last #3 failed" )
322+ return
323+ end if
324+
325+ call split_lines_first_last(' a' // CR// ' b' // LF// ' c' // CR// LF// ' d' , first, last)
326+ if (.not. (all (first == [1 , 3 , 5 , 8 ]) .and. all (last == [1 , 3 , 5 , 8 ]))) then
327+ call test_failed(error, " Test split_lines_first_last #4 failed" )
328+ return
329+ end if
330+
331+ call split_lines_first_last(' ' , first, last)
332+ if (.not. (size (first) == 0 .and. size (last) == 0 )) then
333+ call test_failed(error, " Test split_lines_first_last #5 failed" )
334+ return
335+ end if
336+
337+ call split_lines_first_last(' build.f90' // CRLF// &
338+ ' dependency.f90' // CRLF// &
339+ ' example.f90' // CRLF// &
340+ ' executable.f90' // CRLF// &
341+ ' fortran.f90' // CRLF, &
342+ first, last)
343+
344+ if (.not. (all (first == [1 ,12 ,28 ,41 ,57 ]) .and. all (last == [9 ,25 ,38 ,54 ,67 ]))) then
345+ call test_failed(error, " Test split_lines_first_last #6 failed" )
346+ return
347+ end if
348+
349+ end subroutine test_split_lines_first_last
350+
351+ ! On MS windows, directory listings are printed to files with CR//LF endings.
352+ ! Check that the lines can be properly read back from such files.
353+ subroutine test_dir_with_crlf (error )
354+ type (error_t), allocatable , intent (out ) :: error
355+
356+ character , parameter :: CR = achar (13 )
357+ character , parameter :: LF = new_line(' A' )
358+ character (* ), parameter :: CRLF = CR// LF
359+
360+ character (* ), parameter :: test_lines = ' build.f90' // CRLF// &
361+ ' dependency.f90' // CRLF// &
362+ ' example.f90' // CRLF// &
363+ ' executable.f90' // CRLF// &
364+ ' fortran.f90' // CRLF
365+
366+ type (string_t), allocatable :: lines(:)
367+ character (len= :), allocatable :: temp_file
368+ character (256 ) :: msg
369+ integer :: unit, i, ios
370+
371+ temp_file = get_temp_filename()
372+
373+ open (newunit= unit,file= temp_file,access= ' stream' ,action= ' write' ,iostat= ios)
374+ if (ios/= 0 ) then
375+ call test_failed(error, " cannot create temporary file" )
376+ return
377+ end if
378+
379+ write (unit,iostat= ios) test_lines
380+ if (ios/= 0 ) then
381+ call test_failed(error, " cannot write to temporary file" )
382+ return
383+ end if
384+
385+ close (unit,iostat= ios)
386+ if (ios/= 0 ) then
387+ call test_failed(error, " cannot close temporary file" )
388+ return
389+ end if
390+
391+ lines = read_lines(temp_file)
392+
393+ if (.not. allocated (lines)) then
394+ write (msg, 1 ) ' no output'
395+ call test_failed(error, msg)
396+ return
397+ end if
398+
399+ if (size (lines)/= 5 ) then
400+ write (msg, 1 ) ' wrong number of lines: expected ' ,5 ,' , actual ' ,size (lines)
401+ call test_failed(error, msg)
402+ return
403+ end if
404+
405+ if (lines(1 )% s/= ' build.f90' ) then
406+ call test_failed(error, " Failed reading file with CRLF: at build.f90" )
407+ return
408+ end if
409+ if (lines(2 )% s/= ' dependency.f90' ) then
410+ call test_failed(error, " Failed reading file with CRLF: at dependency.f90" )
411+ return
412+ end if
413+ if (lines(3 )% s/= ' example.f90' ) then
414+ call test_failed(error, " Failed reading file with CRLF: at example.f90" )
415+ return
416+ end if
417+ if (lines(4 )% s/= ' executable.f90' ) then
418+ call test_failed(error, " Failed reading file with CRLF: at executable.f90" )
419+ return
420+ end if
421+ if (lines(5 )% s/= ' fortran.f90' ) then
422+ call test_failed(error, " Failed reading file with CRLF: at fortran.f90" )
423+ return
424+ end if
425+
426+ call delete_file(temp_file)
427+
428+ 1 format (" Failed reading file with CRLF: " ,a,:,i0,:,a,:,i0)
429+
430+ end subroutine test_dir_with_crlf
431+
292432
293433end module test_filesystem
0 commit comments