From fec8c688994d92e80641f8abc213e867bb6b4df8 Mon Sep 17 00:00:00 2001 From: zoziha13 <1325686572@qq.com> Date: Sat, 26 Jun 2021 02:37:17 +0800 Subject: [PATCH 01/14] add: 1. src/stdlib_io_disp.fypp 2. src/tests/string/test_io_disp.f90 3. stdlib_io.fypp%disp interface modify: 1. doc/spec/stdlib_io.md%disp(doc) 2. src/Makefile.manual%disp(make) 3. src/tests/string/Makefile.manual%disp(make) 4. src/CMakelists.txt%disp(cmake) 5. src/CMakelists.txt%disp(cmake) note: make test passed. cmake test passed --- doc/specs/stdlib_io.md | 95 ++++++++++++++++++++++++++ src/CMakeLists.txt | 1 + src/Makefile.manual | 9 ++- src/stdlib_io.fypp | 31 ++++++++- src/stdlib_io_disp.fypp | 125 ++++++++++++++++++++++++++++++++++ src/tests/io/CMakeLists.txt | 1 + src/tests/io/Makefile.manual | 3 +- src/tests/io/test_io_disp.f90 | 24 +++++++ 8 files changed, 284 insertions(+), 5 deletions(-) create mode 100644 src/stdlib_io_disp.fypp create mode 100644 src/tests/io/test_io_disp.f90 diff --git a/doc/specs/stdlib_io.md b/doc/specs/stdlib_io.md index 40cb2b426..3f44f6476 100644 --- a/doc/specs/stdlib_io.md +++ b/doc/specs/stdlib_io.md @@ -131,3 +131,98 @@ program demo_savetxt call savetxt('example.dat', x) end program demo_savetxt ``` + +## `disp` - quickly display your data to the screen (or the default output location) + +### Status + +Experimental + +### Description +Quickly display strings, scalars and low-dimensional arrays to the screen (or the default output location). + +### Syntax + +For 3D arrays: +`call [[stdlib_io(module):disp(interface)]](value, dim [, string])` +For null: +`call [[stdlib_io(module):disp(interface)]]()` +For others: +`call [[stdlib_io(module):disp(interface)]](value [, string])` + +### Arguments + +`value`: Shall be any type of scalar or (<= 3)D `array`. + +`dim`: Shall be a scalar of type `integer` with a value: 1, 2 or 3. + +`string`: Shall be a scalar of type `character` with any length(Usually used to mark data information). + +### Output + +The result is to print your data `value` and comments `string` on the screen (or the default output location). + +### Example + +```fortran +program demo_io_disp + use, non_intrinsic :: stdlib_io, only: disp + implicit none + real :: r(2, 3) + complex :: c(2, 3), c_3d(2, 3, 2) + integer :: i(2, 3) + logical :: l(2, 3) + + r = 1.; c = 1.; c_3d = 2.; i = 1; l = .true. + r(1, 1) = (1.e-11, 1.0e-4) + c(2, 2) = 10.e5 + c_3d(1,3,1) = (1000, 0.001) + call disp('string', 'disp(string):') + call disp('It is a note.') + call disp() + + call disp(r, 'disp(r):') + call disp(c, 'disp(c):') + call disp(i, 'disp(i):') + call disp(l, 'disp(l):') + + call disp(c_3d, 3, 'disp(c_3d, 3):') + call disp(c_3d, 2, 'disp(c_3d, 2):') +end program demo_io_disp +``` +**Result:** +```fortran + disp(string): + string + It is a note. + + disp(r): + 0.1000E-10 1.000 1.000 + 1.000 1.000 1.000 + disp(c): + (1.000,0.000) (1.000,0.000) (1.000,0.000) + (1.000,0.000) (0.1000E+07,0.000) (1.000,0.000) + disp(i): + 1 1 1 + 1 1 1 + disp(l): + T T T + T T T + disp(c_3d, 3): + Slice (:,:,1): + (2.000,0.000) (2.000,0.000) (1000.,0.1000E-02) + (2.000,0.000) (2.000,0.000) (2.000,0.000) + Slice (:,:,2): + (2.000,0.000) (2.000,0.000) (2.000,0.000) + (2.000,0.000) (2.000,0.000) (2.000,0.000) + disp(c_3d, 2): + Slice (:,1,:): + (2.000,0.000) (2.000,0.000) + (2.000,0.000) (2.000,0.000) + Slice (:,2,:): + (2.000,0.000) (2.000,0.000) + (2.000,0.000) (2.000,0.000) + Slice (:,3,:): + (1000.,0.1000E-02) (2.000,0.000) + (2.000,0.000) (2.000,0.000) +``` diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 88bf89c56..77aed09b1 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -7,6 +7,7 @@ set(fppFiles stdlib_bitsets_64.fypp stdlib_bitsets_large.fypp stdlib_io.fypp + stdlib_io_disp.fypp stdlib_linalg.fypp stdlib_linalg_diag.fypp stdlib_optval.fypp diff --git a/src/Makefile.manual b/src/Makefile.manual index c10eddccb..1a1d40811 100644 --- a/src/Makefile.manual +++ b/src/Makefile.manual @@ -27,7 +27,8 @@ SRCFYPP =\ stdlib_stats_distribution_PRNG.fypp \ stdlib_string_type.fypp \ stdlib_strings.fypp \ - stdlib_strings_format_string.fypp + stdlib_strings_format_string.fypp \ + stdlib_io_disp.fypp SRC = f18estop.f90 \ stdlib_error.f90 \ @@ -69,7 +70,8 @@ stdlib_error.o: stdlib_optval.o stdlib_io.o: \ stdlib_error.o \ stdlib_optval.o \ - stdlib_kinds.o + stdlib_kinds.o \ + stdlib_ascii.o stdlib_linalg.o: \ stdlib_kinds.o stdlib_linalg_diag.o: \ @@ -134,3 +136,6 @@ stdlib_strings.o: stdlib_ascii.o \ stdlib_kinds.o stdlib_math.o: stdlib_kinds.o stdlib_strings_format_string.o: stdlib_strings.o +stdlib_io_disp.o: stdlib_error.o \ + stdlib_strings.o \ + stdlib_io.o diff --git a/src/stdlib_io.fypp b/src/stdlib_io.fypp index dcacaa644..dd6cc3d85 100644 --- a/src/stdlib_io.fypp +++ b/src/stdlib_io.fypp @@ -7,18 +7,45 @@ module stdlib_io !! ([Specification](../page/specs/stdlib_io.html)) use stdlib_kinds, only: sp, dp, qp, & - int8, int16, int32, int64 + int8, int16, int32, int64, lk, c_bool use stdlib_error, only: error_stop use stdlib_optval, only: optval use stdlib_ascii, only: is_blank implicit none private ! Public API - public :: loadtxt, savetxt, open + public :: loadtxt, savetxt, open, disp ! Private API that is exposed so that we can test it in tests public :: parse_mode + interface disp + !! + #:set DISP_KINDS_TYPES = REAL_KINDS_TYPES + INT_KINDS_TYPES & + & + CMPLX_KINDS_TYPES + LOG_KINDS_TYPES + #:set DISP_RANKS = range(0, 4) + #:for kind, type in DISP_KINDS_TYPES + #:for rank in DISP_RANKS + #:if rank != 3 + impure module subroutine disp_${rank}$_${type[0]}$${kind}$(val, string) + ${type}$, intent(in) :: val${ranksuffix(rank)}$ + character(len=*), intent(in), optional :: string + end subroutine disp_${rank}$_${type[0]}$${kind}$ + #:else + impure module subroutine disp_${rank}$_${type[0]}$${kind}$(val, dim, string) + ${type}$, intent(in) :: val${ranksuffix(rank)}$ + integer, intent(in) :: dim + character(len=*), intent(in), optional :: string + end subroutine disp_${rank}$_${type[0]}$${kind}$ + #:endif + #:endfor + #:endfor + impure module subroutine disp_str(val, string) + character(len=*), intent(in), optional :: val + character(len=*), intent(in), optional :: string + end subroutine disp_str + end interface disp + interface loadtxt !! version: experimental !! diff --git a/src/stdlib_io_disp.fypp b/src/stdlib_io_disp.fypp new file mode 100644 index 000000000..66d9694cb --- /dev/null +++ b/src/stdlib_io_disp.fypp @@ -0,0 +1,125 @@ +#:include "common.fypp" +#:set RIL_KINDS_TYPES = REAL_KINDS_TYPES + INT_KINDS_TYPES + LOG_KINDS_TYPES + +submodule (stdlib_io) stdlib_io_disp + + use, non_intrinsic :: stdlib_strings, only: format_string + implicit none + character(len=*), parameter :: fmt_r = '(*(g11.4, 1x))' + character(len=*), parameter :: fmt_c = '(*(g23.4, 1x))' + +contains + + #:for kind, type in RIL_KINDS_TYPES + module procedure disp_0_${type[0]}$${kind}$ + if(present(string)) print *, trim(string) + print fmt_r, val + end procedure disp_0_${type[0]}$${kind}$ + + module procedure disp_1_${type[0]}$${kind}$ + integer :: i, m + m = size(val) + if(present(string)) print *, trim(string) + print fmt_r, (val(i), i=1,m) + end procedure disp_1_${type[0]}$${kind}$ + + module procedure disp_2_${type[0]}$${kind}$ + integer :: i, j, m, n + m = size(val, 1) + n = size(val, 2) + if(present(string)) print *, trim(string) + do i = 1, m + print fmt_r, (val(i,j), j=1, n) + end do + end procedure disp_2_${type[0]}$${kind}$ + + module procedure disp_3_${type[0]}$${kind}$ + integer :: i, dim1, dim2, dim3 + dim1 = size(val, 1) + dim2 = size(val, 2) + dim3 = size(val, 3) + if(present(string)) print *, trim(string) + if(dim == 1) then + do i = 1, dim1 + print *, 'Slice ('//format_string(i)//',:,:):' + call disp_2_${type[0]}$${kind}$(val(i, :, :)) + end do + elseif(dim == 2) then + do i = 1, dim2 + print *, 'Slice (:,'//format_string(i)//',:):' + call disp_2_${type[0]}$${kind}$(val(:, i, :)) + end do + elseif (dim == 3) then + do i = 1, dim3 + print *, 'Slice (:,:,'//format_string(i)//'):' + call disp_2_${type[0]}$${kind}$(val(:, :, i)) + end do + else + call error_stop('Error(disp): wrong dimension') + end if + end procedure disp_3_${type[0]}$${kind}$ + #:endfor + + #:for kind, type in CMPLX_KINDS_TYPES + module procedure disp_0_${type[0]}$${kind}$ + if(present(string)) print *, trim(string) + print fmt_c, format_string(cmplx(real(val), & + aimag(val)), '(g11,4)') + end procedure disp_0_${type[0]}$${kind}$ + + module procedure disp_1_${type[0]}$${kind}$ + integer :: i, m + m = size(val) + if(present(string)) print *, trim(string) + print fmt_c, (format_string(cmplx(real(val(i)), & + aimag(val(i))), '(g11.4)'), i=1, m) + end procedure disp_1_${type[0]}$${kind}$ + + module procedure disp_2_${type[0]}$${kind}$ + integer :: i, j, m, n + m = size(val, 1) + n = size(val, 2) + if(present(string)) print *, trim(string) + do i = 1, m + print fmt_c, (format_string(cmplx(real(val(i, j)), & + aimag(val(i, j))), '(g11.4)'), j=1, n) + end do + end procedure disp_2_${type[0]}$${kind}$ + + module procedure disp_3_${type[0]}$${kind}$ + integer :: i, dim1, dim2, dim3 + dim1 = size(val, 1) + dim2 = size(val, 2) + dim3 = size(val, 3) + if(present(string)) print *, trim(string) + if(dim == 1) then + do i = 1, dim1 + print *, 'Slice ('//format_string(i)//',:,:):' + call disp_2_${type[0]}$${kind}$(val(i, :, :)) + end do + elseif(dim == 2) then + do i = 1, dim2 + print *, 'Slice (:,'//format_string(i)//',:):' + call disp_2_${type[0]}$${kind}$(val(:, i, :)) + end do + elseif (dim == 3) then + do i = 1, dim3 + print *, 'Slice (:,:,'//format_string(i)//'):' + call disp_2_${type[0]}$${kind}$(val(:, :, i)) + end do + else + call error_stop('Error(disp): wrong dimension') + end if + end procedure disp_3_${type[0]}$${kind}$ + #:endfor + + module procedure disp_str + if(present(string)) print *, trim(string) + if(present(val)) then + print *, trim(val) + else + print *, '' + end if + end procedure disp_str + +end submodule stdlib_io_disp \ No newline at end of file diff --git a/src/tests/io/CMakeLists.txt b/src/tests/io/CMakeLists.txt index 68388a5e5..97c97757b 100644 --- a/src/tests/io/CMakeLists.txt +++ b/src/tests/io/CMakeLists.txt @@ -8,3 +8,4 @@ set_tests_properties(savetxt_qp PROPERTIES LABELS quadruple_precision) ADDTEST(open) ADDTEST(parse_mode) +ADDTEST(io_disp) diff --git a/src/tests/io/Makefile.manual b/src/tests/io/Makefile.manual index 3bbce9db7..3ec21eacb 100644 --- a/src/tests/io/Makefile.manual +++ b/src/tests/io/Makefile.manual @@ -3,7 +3,8 @@ PROGS_SRC = test_loadtxt.f90 \ test_loadtxt_qp.f90 \ test_savetxt_qp.f90 \ test_parse_mode.f90 \ - test_open.f90 + test_open.f90 \ + test_io_disp.f90 CLEAN_FILES = tmp.dat tmp_qp.dat io_open.dat io_open.stream diff --git a/src/tests/io/test_io_disp.f90 b/src/tests/io/test_io_disp.f90 new file mode 100644 index 000000000..bb6abc362 --- /dev/null +++ b/src/tests/io/test_io_disp.f90 @@ -0,0 +1,24 @@ +program test_io_disp + use, non_intrinsic :: stdlib_io, only: disp + implicit none + real :: r(2, 3) + complex :: c(2, 3), c_3d(2, 3, 2) + integer :: i(2, 3) + logical :: l(2, 3) + + r = 1.; c = 1.; c_3d = 2.; i = 1; l = .true. + r(1, 1) = (1.e-11, 1.0e-4) + c(2, 2) = 10.e5 + c_3d(1,3,1) = (1000, 0.001) + call disp('string', 'disp(string):') + call disp('It is a note.') + call disp() + + call disp(r, 'disp(r):') + call disp(c, 'disp(c):') + call disp(i, 'disp(i):') + call disp(l, 'disp(l):') + + call disp(c_3d, 3, 'disp(c_3d, 3):') + call disp(c_3d, 2, 'disp(c_3d, 2):') +end program test_io_disp \ No newline at end of file From df88c550cd26c474e885ae2810e5ec8e31554ef9 Mon Sep 17 00:00:00 2001 From: zoziha13 <1325686572@qq.com> Date: Mon, 28 Jun 2021 00:18:50 +0800 Subject: [PATCH 02/14] Fix stdlib_io_disp routines. --- - stdlib_io.fypp 1. add disp interface comments 2. remove `impure` label - stdlib_io_disp.fypp 1. remove `non_intrinsic` label 2. update some `format_string` to `to_string` 3. update `fmt_r` & `fmt_c` 4. add some routine comments 5. update the writing of some statements - update test_io_disp.f90 - notes 1. make passed 2. cmake passed --- src/stdlib_io.fypp | 9 ++++--- src/stdlib_io_disp.fypp | 46 +++++++++++++++++++---------------- src/tests/io/test_io_disp.f90 | 8 +++--- 3 files changed, 36 insertions(+), 27 deletions(-) diff --git a/src/stdlib_io.fypp b/src/stdlib_io.fypp index dd6cc3d85..1f40dbd0b 100644 --- a/src/stdlib_io.fypp +++ b/src/stdlib_io.fypp @@ -20,19 +20,22 @@ module stdlib_io public :: parse_mode interface disp + !! version: experimental !! + !! Quickly display strings, scalars and low-dimensional arrays to the default output_unit + !! ([Specification](../page/specs/stdlib_io.html#description)) #:set DISP_KINDS_TYPES = REAL_KINDS_TYPES + INT_KINDS_TYPES & & + CMPLX_KINDS_TYPES + LOG_KINDS_TYPES #:set DISP_RANKS = range(0, 4) #:for kind, type in DISP_KINDS_TYPES #:for rank in DISP_RANKS #:if rank != 3 - impure module subroutine disp_${rank}$_${type[0]}$${kind}$(val, string) + module subroutine disp_${rank}$_${type[0]}$${kind}$(val, string) ${type}$, intent(in) :: val${ranksuffix(rank)}$ character(len=*), intent(in), optional :: string end subroutine disp_${rank}$_${type[0]}$${kind}$ #:else - impure module subroutine disp_${rank}$_${type[0]}$${kind}$(val, dim, string) + module subroutine disp_${rank}$_${type[0]}$${kind}$(val, dim, string) ${type}$, intent(in) :: val${ranksuffix(rank)}$ integer, intent(in) :: dim character(len=*), intent(in), optional :: string @@ -40,7 +43,7 @@ module stdlib_io #:endif #:endfor #:endfor - impure module subroutine disp_str(val, string) + module subroutine disp_str(val, string) character(len=*), intent(in), optional :: val character(len=*), intent(in), optional :: string end subroutine disp_str diff --git a/src/stdlib_io_disp.fypp b/src/stdlib_io_disp.fypp index 66d9694cb..aa4b8e96d 100644 --- a/src/stdlib_io_disp.fypp +++ b/src/stdlib_io_disp.fypp @@ -3,37 +3,39 @@ submodule (stdlib_io) stdlib_io_disp - use, non_intrinsic :: stdlib_strings, only: format_string + use stdlib_ascii, only: to_string + use stdlib_strings, only: format_string implicit none - character(len=*), parameter :: fmt_r = '(*(g11.4, 1x))' - character(len=*), parameter :: fmt_c = '(*(g23.4, 1x))' + character(len=*), parameter :: fmt_r = '(*(g12.4, 1x))' + character(len=*), parameter :: fmt_c = '(*(g25.0, 1x))' contains #:for kind, type in RIL_KINDS_TYPES module procedure disp_0_${type[0]}$${kind}$ + !! Disp ${type}$ variable to default output_unit if(present(string)) print *, trim(string) print fmt_r, val end procedure disp_0_${type[0]}$${kind}$ module procedure disp_1_${type[0]}$${kind}$ - integer :: i, m - m = size(val) + !! Disp ${type}$ vector variable to default output_unit if(present(string)) print *, trim(string) - print fmt_r, (val(i), i=1,m) + print fmt_r, val(:) end procedure disp_1_${type[0]}$${kind}$ module procedure disp_2_${type[0]}$${kind}$ - integer :: i, j, m, n + !! Disp ${type}$ 2D array variable to default output_unit + integer :: i, m m = size(val, 1) - n = size(val, 2) if(present(string)) print *, trim(string) do i = 1, m - print fmt_r, (val(i,j), j=1, n) + print fmt_r, val(i,:) end do end procedure disp_2_${type[0]}$${kind}$ module procedure disp_3_${type[0]}$${kind}$ + !! Disp ${type}$ 3D array variable to default output_unit integer :: i, dim1, dim2, dim3 dim1 = size(val, 1) dim2 = size(val, 2) @@ -41,17 +43,17 @@ contains if(present(string)) print *, trim(string) if(dim == 1) then do i = 1, dim1 - print *, 'Slice ('//format_string(i)//',:,:):' + print *, 'Slice ('//to_string(i)//',:,:):' call disp_2_${type[0]}$${kind}$(val(i, :, :)) end do elseif(dim == 2) then do i = 1, dim2 - print *, 'Slice (:,'//format_string(i)//',:):' + print *, 'Slice (:,'//to_string(i)//',:):' call disp_2_${type[0]}$${kind}$(val(:, i, :)) end do elseif (dim == 3) then do i = 1, dim3 - print *, 'Slice (:,:,'//format_string(i)//'):' + print *, 'Slice (:,:,'//to_string(i)//'):' call disp_2_${type[0]}$${kind}$(val(:, :, i)) end do else @@ -62,31 +64,32 @@ contains #:for kind, type in CMPLX_KINDS_TYPES module procedure disp_0_${type[0]}$${kind}$ + !! Disp ${type}$ variable to default output_unit if(present(string)) print *, trim(string) - print fmt_c, format_string(cmplx(real(val), & - aimag(val)), '(g11,4)') + print fmt_c, format_string(val, '(g0.4)') end procedure disp_0_${type[0]}$${kind}$ module procedure disp_1_${type[0]}$${kind}$ + !! Disp ${type}$ vector variable to default output_unit integer :: i, m m = size(val) if(present(string)) print *, trim(string) - print fmt_c, (format_string(cmplx(real(val(i)), & - aimag(val(i))), '(g11.4)'), i=1, m) + print fmt_c, (format_string(val(i), '(g0.4)'), i=1, m) end procedure disp_1_${type[0]}$${kind}$ module procedure disp_2_${type[0]}$${kind}$ + !! Disp ${type}$ 2D array variable to default output_unit integer :: i, j, m, n m = size(val, 1) n = size(val, 2) if(present(string)) print *, trim(string) do i = 1, m - print fmt_c, (format_string(cmplx(real(val(i, j)), & - aimag(val(i, j))), '(g11.4)'), j=1, n) + print fmt_c, (format_string(val(i, j), '(g0.4)'), j=1, n) end do end procedure disp_2_${type[0]}$${kind}$ module procedure disp_3_${type[0]}$${kind}$ + !! Disp ${type}$ 3D array variable to default output_unit integer :: i, dim1, dim2, dim3 dim1 = size(val, 1) dim2 = size(val, 2) @@ -94,17 +97,17 @@ contains if(present(string)) print *, trim(string) if(dim == 1) then do i = 1, dim1 - print *, 'Slice ('//format_string(i)//',:,:):' + print *, 'Slice ('//to_string(i)//',:,:):' call disp_2_${type[0]}$${kind}$(val(i, :, :)) end do elseif(dim == 2) then do i = 1, dim2 - print *, 'Slice (:,'//format_string(i)//',:):' + print *, 'Slice (:,'//to_string(i)//',:):' call disp_2_${type[0]}$${kind}$(val(:, i, :)) end do elseif (dim == 3) then do i = 1, dim3 - print *, 'Slice (:,:,'//format_string(i)//'):' + print *, 'Slice (:,:,'//to_string(i)//'):' call disp_2_${type[0]}$${kind}$(val(:, :, i)) end do else @@ -114,6 +117,7 @@ contains #:endfor module procedure disp_str + !! Disp character variable to default output_unit if(present(string)) print *, trim(string) if(present(val)) then print *, trim(val) diff --git a/src/tests/io/test_io_disp.f90 b/src/tests/io/test_io_disp.f90 index bb6abc362..6bb7ccfec 100644 --- a/src/tests/io/test_io_disp.f90 +++ b/src/tests/io/test_io_disp.f90 @@ -1,15 +1,17 @@ program test_io_disp use, non_intrinsic :: stdlib_io, only: disp implicit none - real :: r(2, 3) + real(8) :: r(2, 3) complex :: c(2, 3), c_3d(2, 3, 2) integer :: i(2, 3) logical :: l(2, 3) r = 1.; c = 1.; c_3d = 2.; i = 1; l = .true. - r(1, 1) = (1.e-11, 1.0e-4) - c(2, 2) = 10.e5 + r(1, 1) = -1.e-11 + r(1, 2) = -1.e10 + c(2, 2) = (-1.e10,-1.e10) c_3d(1,3,1) = (1000, 0.001) + c_3d(1,3,2) = (1.e4, 100.) call disp('string', 'disp(string):') call disp('It is a note.') call disp() From cb4cecc9cda33902227ef96ef1921dabeb87988f Mon Sep 17 00:00:00 2001 From: zoziha13 <1325686572@qq.com> Date: Tue, 6 Jul 2021 11:18:55 +0800 Subject: [PATCH 03/14] Update `format_to_string` things; Update `disp` docs; Adopt `select case` block; Adopt the `fypp` inline rank writing; Rename `disp` input arg: val -> value. --- doc/specs/stdlib_io.md | 99 +++++++++++++++++++++++------------------ src/Makefile.manual | 6 +-- src/stdlib_io.fypp | 21 +++------ src/stdlib_io_disp.fypp | 79 ++++++++++++++++---------------- 4 files changed, 105 insertions(+), 100 deletions(-) diff --git a/doc/specs/stdlib_io.md b/doc/specs/stdlib_io.md index 3f44f6476..8c2c486c1 100644 --- a/doc/specs/stdlib_io.md +++ b/doc/specs/stdlib_io.md @@ -132,62 +132,81 @@ program demo_savetxt end program demo_savetxt ``` -## `disp` - quickly display your data to the screen (or the default output location) +## `disp` - display your data to the screen (or the default `output_unit`) ### Status Experimental ### Description -Quickly display strings, scalars and low-dimensional arrays to the screen (or the default output location). +Display any type of scalar or `array` with up to 3 dimensions to the screen (or the default `output_unit`). + +Make good use of similar to the following usage, can help you understand the data information in the `array`. +```fortran +call disp( A(i, j, 2, :, :) [, string] ) !! `i, j, ...` can be determined by `do` loop. +``` + +Generally, except for `complex` type, any other type of scalar or single element of the `array` will be printed out with a width of 12 characters and a space separator. +For `complex` type, scalar or single element of the `array` will be printed out with a width of 25 characters and a space separator. ### Syntax -For 3D arrays: -`call [[stdlib_io(module):disp(interface)]](value, dim [, string])` +General API: +`call [[stdlib_io(module):disp(interface)]](value [, string])` + +Except, for 3D arrays: +`call [[stdlib_io(module):disp(interface)]](value, dim [, string])` + For null: `call [[stdlib_io(module):disp(interface)]]()` -For others: -`call [[stdlib_io(module):disp(interface)]](value [, string])` ### Arguments -`value`: Shall be any type of scalar or (<= 3)D `array`. +`value`: Shall be any type of scalar or `array` with up to 3 dimensions. + This is an `intent(in)` argument. `dim`: Shall be a scalar of type `integer` with a value: 1, 2 or 3. + This is an `intent(in)` argument. -`string`: Shall be a scalar of type `character` with any length(Usually used to mark data information). +`string`: Shall be a scalar of type `character` with any length (usually used to comment data information). + This is an `intent(in)` and `optional` argument. ### Output -The result is to print your data `value` and comments `string` on the screen (or the default output location). +The result is to print `string` and `value` on the screen (or the default `output_unit`) in this order. ### Example ```fortran program demo_io_disp - use, non_intrinsic :: stdlib_io, only: disp + + use :: stdlib_io, only: disp implicit none - real :: r(2, 3) + real(8) :: r(2, 3) complex :: c(2, 3), c_3d(2, 3, 2) integer :: i(2, 3) logical :: l(2, 3) r = 1.; c = 1.; c_3d = 2.; i = 1; l = .true. - r(1, 1) = (1.e-11, 1.0e-4) - c(2, 2) = 10.e5 + r(1, 1) = -1.e-11 + r(1, 2) = -1.e10 + c(2, 2) = (-1.e10,-1.e10) c_3d(1,3,1) = (1000, 0.001) - call disp('string', 'disp(string):') - call disp('It is a note.') - call disp() + c_3d(1,3,2) = (1.e4, 100.) + + call disp('string', 'disp(string):') + call disp('It is a note.') + call disp() + + call disp(r, 'disp(r):') + call disp(c, 'disp(c):') + call disp(i(1,:), 'disp(i):') + call disp(l(:,2), 'disp(l):') - call disp(r, 'disp(r):') - call disp(c, 'disp(c):') - call disp(i, 'disp(i):') - call disp(l, 'disp(l):') + call disp(c_3d, 3, 'disp(c_3d, 3):') - call disp(c_3d, 3, 'disp(c_3d, 3):') - call disp(c_3d, 2, 'disp(c_3d, 2):') + call disp(c_3d(1,:,:), 'disp(c_3d(1,:,:)):') + end program demo_io_disp ``` **Result:** @@ -197,32 +216,24 @@ end program demo_io_disp It is a note. disp(r): - 0.1000E-10 1.000 1.000 - 1.000 1.000 1.000 + -0.1000E-10 -0.1000E+11 1.000 + 1.000 1.000 1.000 disp(c): - (1.000,0.000) (1.000,0.000) (1.000,0.000) - (1.000,0.000) (0.1000E+07,0.000) (1.000,0.000) + (1.000,0.000) (1.000,0.000) (1.000,0.000) + (1.000,0.000) (-0.1000E+11,-0.1000E+11) (1.000,0.000) disp(i): - 1 1 1 - 1 1 1 + 1 1 1 disp(l): - T T T - T T T + T T disp(c_3d, 3): Slice (:,:,1): - (2.000,0.000) (2.000,0.000) (1000.,0.1000E-02) - (2.000,0.000) (2.000,0.000) (2.000,0.000) + (2.000,0.000) (2.000,0.000) (1000.,0.1000E-2) + (2.000,0.000) (2.000,0.000) (2.000,0.000) Slice (:,:,2): - (2.000,0.000) (2.000,0.000) (2.000,0.000) - (2.000,0.000) (2.000,0.000) (2.000,0.000) - disp(c_3d, 2): - Slice (:,1,:): - (2.000,0.000) (2.000,0.000) - (2.000,0.000) (2.000,0.000) - Slice (:,2,:): - (2.000,0.000) (2.000,0.000) - (2.000,0.000) (2.000,0.000) - Slice (:,3,:): - (1000.,0.1000E-02) (2.000,0.000) - (2.000,0.000) (2.000,0.000) + (2.000,0.000) (2.000,0.000) (0.1000E+5,100.0) + (2.000,0.000) (2.000,0.000) (2.000,0.000) + disp(c_3d(1,:,:)): + (2.000,0.000) (2.000,0.000) + (2.000,0.000) (2.000,0.000) + (1000.,0.1000E-2) (0.1000E+5,100.0) ``` diff --git a/src/Makefile.manual b/src/Makefile.manual index d22ef1f06..52836fa7a 100644 --- a/src/Makefile.manual +++ b/src/Makefile.manual @@ -28,7 +28,7 @@ SRCFYPP =\ stdlib_stats_distribution_PRNG.fypp \ stdlib_string_type.fypp \ stdlib_strings.fypp \ - stdlib_strings_format_to_string.fypp \ + stdlib_string_format_to_string.fypp \ stdlib_io_disp.fypp SRC = f18estop.f90 \ @@ -136,13 +136,13 @@ stdlib_stats_var.o: \ stdlib_kinds.o \ stdlib_stats.o stdlib_stats_distribution_PRNG.o: \ - stdlib_kinds.o \ + stdlib_kinds.o \ stdlib_error.o stdlib_string_type.o: stdlib_ascii.o \ stdlib_kinds.o stdlib_strings.o: stdlib_ascii.o \ stdlib_string_type.o \ - stdlib_optval.o \ + stdlib_optval.o \ stdlib_kinds.o stdlib_math.o: stdlib_kinds.o stdlib_string_format_to_string.o: stdlib_strings.o diff --git a/src/stdlib_io.fypp b/src/stdlib_io.fypp index 1f40dbd0b..002b7b021 100644 --- a/src/stdlib_io.fypp +++ b/src/stdlib_io.fypp @@ -22,29 +22,22 @@ module stdlib_io interface disp !! version: experimental !! - !! Quickly display strings, scalars and low-dimensional arrays to the default output_unit - !! ([Specification](../page/specs/stdlib_io.html#description)) + !! Display any type of scalar and `array` with up to 3 dimensions to the default `output_unit` + !! ([Specification](../page/specs/stdlib_io.html#description_4)) #:set DISP_KINDS_TYPES = REAL_KINDS_TYPES + INT_KINDS_TYPES & & + CMPLX_KINDS_TYPES + LOG_KINDS_TYPES #:set DISP_RANKS = range(0, 4) #:for kind, type in DISP_KINDS_TYPES #:for rank in DISP_RANKS - #:if rank != 3 - module subroutine disp_${rank}$_${type[0]}$${kind}$(val, string) - ${type}$, intent(in) :: val${ranksuffix(rank)}$ - character(len=*), intent(in), optional :: string - end subroutine disp_${rank}$_${type[0]}$${kind}$ - #:else - module subroutine disp_${rank}$_${type[0]}$${kind}$(val, dim, string) - ${type}$, intent(in) :: val${ranksuffix(rank)}$ - integer, intent(in) :: dim + module subroutine disp_${rank}$_${type[0]}$${kind}$(value, #{if rank == 3}#dim, #{endif}#string) + ${type}$, intent(in) :: value${ranksuffix(rank)}$ + #{if rank == 3}#integer, intent(in) :: dim#{endif}# character(len=*), intent(in), optional :: string end subroutine disp_${rank}$_${type[0]}$${kind}$ - #:endif #:endfor #:endfor - module subroutine disp_str(val, string) - character(len=*), intent(in), optional :: val + module subroutine disp_str(value, string) + character(len=*), intent(in), optional :: value character(len=*), intent(in), optional :: string end subroutine disp_str end interface disp diff --git a/src/stdlib_io_disp.fypp b/src/stdlib_io_disp.fypp index aa4b8e96d..9a3aa617d 100644 --- a/src/stdlib_io_disp.fypp +++ b/src/stdlib_io_disp.fypp @@ -4,7 +4,7 @@ submodule (stdlib_io) stdlib_io_disp use stdlib_ascii, only: to_string - use stdlib_strings, only: format_string + use stdlib_strings, only: format_to_string implicit none character(len=*), parameter :: fmt_r = '(*(g12.4, 1x))' character(len=*), parameter :: fmt_c = '(*(g25.0, 1x))' @@ -13,102 +13,103 @@ contains #:for kind, type in RIL_KINDS_TYPES module procedure disp_0_${type[0]}$${kind}$ - !! Disp ${type}$ variable to default output_unit + !! Display a ${type}$ variable to the default `output_unit` if(present(string)) print *, trim(string) - print fmt_r, val + print fmt_r, value end procedure disp_0_${type[0]}$${kind}$ module procedure disp_1_${type[0]}$${kind}$ - !! Disp ${type}$ vector variable to default output_unit + !! Display a ${type}$ vector variable to the default `output_unit` if(present(string)) print *, trim(string) - print fmt_r, val(:) + print fmt_r, value(:) end procedure disp_1_${type[0]}$${kind}$ module procedure disp_2_${type[0]}$${kind}$ - !! Disp ${type}$ 2D array variable to default output_unit + !! Display a ${type}$ 2D array variable to the default `output_unit` integer :: i, m - m = size(val, 1) + m = size(value, 1) if(present(string)) print *, trim(string) do i = 1, m - print fmt_r, val(i,:) + print fmt_r, value(i,:) end do end procedure disp_2_${type[0]}$${kind}$ module procedure disp_3_${type[0]}$${kind}$ - !! Disp ${type}$ 3D array variable to default output_unit + !! Display a ${type}$ 3D array variable to the default `output_unit` integer :: i, dim1, dim2, dim3 - dim1 = size(val, 1) - dim2 = size(val, 2) - dim3 = size(val, 3) + dim1 = size(value, 1) + dim2 = size(value, 2) + dim3 = size(value, 3) if(present(string)) print *, trim(string) - if(dim == 1) then + select case(dim) + case(1) do i = 1, dim1 print *, 'Slice ('//to_string(i)//',:,:):' - call disp_2_${type[0]}$${kind}$(val(i, :, :)) + call disp_2_${type[0]}$${kind}$(value(i, :, :)) end do - elseif(dim == 2) then + case(2) do i = 1, dim2 print *, 'Slice (:,'//to_string(i)//',:):' - call disp_2_${type[0]}$${kind}$(val(:, i, :)) + call disp_2_${type[0]}$${kind}$(value(:, i, :)) end do - elseif (dim == 3) then + case(3) do i = 1, dim3 print *, 'Slice (:,:,'//to_string(i)//'):' - call disp_2_${type[0]}$${kind}$(val(:, :, i)) + call disp_2_${type[0]}$${kind}$(value(:, :, i)) end do - else + case default call error_stop('Error(disp): wrong dimension') - end if + end select end procedure disp_3_${type[0]}$${kind}$ #:endfor #:for kind, type in CMPLX_KINDS_TYPES module procedure disp_0_${type[0]}$${kind}$ - !! Disp ${type}$ variable to default output_unit + !! Display a ${type}$ variable to the default `output_unit` if(present(string)) print *, trim(string) - print fmt_c, format_string(val, '(g0.4)') + print fmt_c, format_to_string(value, '(g0.4)') end procedure disp_0_${type[0]}$${kind}$ module procedure disp_1_${type[0]}$${kind}$ - !! Disp ${type}$ vector variable to default output_unit + !! Display a ${type}$ vector variable to the default `output_unit` integer :: i, m - m = size(val) + m = size(value) if(present(string)) print *, trim(string) - print fmt_c, (format_string(val(i), '(g0.4)'), i=1, m) + print fmt_c, (format_to_string(value(i), '(g0.4)'), i=1, m) end procedure disp_1_${type[0]}$${kind}$ module procedure disp_2_${type[0]}$${kind}$ - !! Disp ${type}$ 2D array variable to default output_unit + !! Display a ${type}$ 2D array variable to the default `output_unit` integer :: i, j, m, n - m = size(val, 1) - n = size(val, 2) + m = size(value, 1) + n = size(value, 2) if(present(string)) print *, trim(string) do i = 1, m - print fmt_c, (format_string(val(i, j), '(g0.4)'), j=1, n) + print fmt_c, (format_to_string(value(i, j), '(g0.4)'), j=1, n) end do end procedure disp_2_${type[0]}$${kind}$ module procedure disp_3_${type[0]}$${kind}$ - !! Disp ${type}$ 3D array variable to default output_unit + !! Display a ${type}$ 3D array variable to the default `output_unit` integer :: i, dim1, dim2, dim3 - dim1 = size(val, 1) - dim2 = size(val, 2) - dim3 = size(val, 3) + dim1 = size(value, 1) + dim2 = size(value, 2) + dim3 = size(value, 3) if(present(string)) print *, trim(string) if(dim == 1) then do i = 1, dim1 print *, 'Slice ('//to_string(i)//',:,:):' - call disp_2_${type[0]}$${kind}$(val(i, :, :)) + call disp_2_${type[0]}$${kind}$(value(i, :, :)) end do elseif(dim == 2) then do i = 1, dim2 print *, 'Slice (:,'//to_string(i)//',:):' - call disp_2_${type[0]}$${kind}$(val(:, i, :)) + call disp_2_${type[0]}$${kind}$(value(:, i, :)) end do elseif (dim == 3) then do i = 1, dim3 print *, 'Slice (:,:,'//to_string(i)//'):' - call disp_2_${type[0]}$${kind}$(val(:, :, i)) + call disp_2_${type[0]}$${kind}$(value(:, :, i)) end do else call error_stop('Error(disp): wrong dimension') @@ -117,10 +118,10 @@ contains #:endfor module procedure disp_str - !! Disp character variable to default output_unit + !! Display a character variable to the default `output_unit` if(present(string)) print *, trim(string) - if(present(val)) then - print *, trim(val) + if(present(value)) then + print *, trim(value) else print *, '' end if From 3b0f0bc9a9e43765af100a1f2e53a1b7d8a9485f Mon Sep 17 00:00:00 2001 From: zoziha13 <1325686572@qq.com> Date: Wed, 7 Jul 2021 17:49:13 +0800 Subject: [PATCH 04/14] Update `disp`: add optional `unit` and `brief`. --- doc/specs/stdlib_io.md | 84 +++++++------- src/stdlib_io.fypp | 19 ++-- src/stdlib_io_disp.fypp | 199 +++++++++++++++++++--------------- src/tests/io/test_io_disp.f90 | 26 +++-- 4 files changed, 185 insertions(+), 143 deletions(-) diff --git a/doc/specs/stdlib_io.md b/doc/specs/stdlib_io.md index 8c2c486c1..e77c776d3 100644 --- a/doc/specs/stdlib_io.md +++ b/doc/specs/stdlib_io.md @@ -132,18 +132,18 @@ program demo_savetxt end program demo_savetxt ``` -## `disp` - display your data to the screen (or the default `output_unit`) +## `disp` - display your data to the screen (or an other output unit) ### Status Experimental ### Description -Display any type of scalar or `array` with up to 3 dimensions to the screen (or the default `output_unit`). +Display any type of scalar, vector or matrix. Make good use of similar to the following usage, can help you understand the data information in the `array`. ```fortran -call disp( A(i, j, 2, :, :) [, string] ) !! `i, j, ...` can be determined by `do` loop. +call disp( A(i, j, 2, :, :) [, unit, header, brief] ) !! `i, j, ...` can be determined by `do` loop. ``` Generally, except for `complex` type, any other type of scalar or single element of the `array` will be printed out with a width of 12 characters and a space separator. @@ -152,40 +152,41 @@ For `complex` type, scalar or single element of the `array` will be printed out ### Syntax General API: -`call [[stdlib_io(module):disp(interface)]](value [, string])` - -Except, for 3D arrays: -`call [[stdlib_io(module):disp(interface)]](value, dim [, string])` +`call [[stdlib_io(module):disp(interface)]](value [, unit, header, brief])` For null: `call [[stdlib_io(module):disp(interface)]]()` ### Arguments -`value`: Shall be any type of scalar or `array` with up to 3 dimensions. +`value`: Shall be any type of scalar, vector or matrix. This is an `intent(in)` argument. -`dim`: Shall be a scalar of type `integer` with a value: 1, 2 or 3. - This is an `intent(in)` argument. +`unit`: Shall be an `integer` scalar link to an IO stream. + This is an `intent(in)` and `optional` argument. + +`header`: Shall be a scalar of type `character` with any length (usually used to comment data information). + This is an `intent(in)` and `optional` argument. -`string`: Shall be a scalar of type `character` with any length (usually used to comment data information). +`brief`: Shall be an `logical` scalar, controling an abridged version of the `value` object is printed. This is an `intent(in)` and `optional` argument. ### Output -The result is to print `string` and `value` on the screen (or the default `output_unit`) in this order. +The result is to print `header` and `value` on the screen (or an other output unit) in this order. +If `value` is a `array` type, the dimension length information of the `array` will also be output. ### Example ```fortran -program demo_io_disp - +program test_io_disp + use :: stdlib_io, only: disp implicit none real(8) :: r(2, 3) - complex :: c(2, 3), c_3d(2, 3, 2) + complex :: c(2, 3), c_3d(2, 100, 20) integer :: i(2, 3) - logical :: l(2, 3) + logical :: l(10, 10) r = 1.; c = 1.; c_3d = 2.; i = 1; l = .true. r(1, 1) = -1.e-11 @@ -193,47 +194,54 @@ program demo_io_disp c(2, 2) = (-1.e10,-1.e10) c_3d(1,3,1) = (1000, 0.001) c_3d(1,3,2) = (1.e4, 100.) - - call disp('string', 'disp(string):') + call disp('string', header='disp(string):') call disp('It is a note.') call disp() - call disp(r, 'disp(r):') - call disp(c, 'disp(c):') - call disp(i(1,:), 'disp(i):') - call disp(l(:,2), 'disp(l):') + call disp(r, header='disp(r):') + call disp(c, header='disp(c):') + call disp(i, header='disp(i):') + call disp(l, header='disp(l):', brief=.true.) - call disp(c_3d, 3, 'disp(c_3d, 3):') + call disp(c_3d(:,:,3), header='disp(c_3d, 3):', brief=.true.) + call disp(c_3d(2,:,:), header='disp(c_3d, 2):', brief=.true.) - call disp(c_3d(1,:,:), 'disp(c_3d(1,:,:)):') - -end program demo_io_disp +end program test_io_disp ``` **Result:** ```fortran - disp(string): +disp(string): string It is a note. disp(r): + [matrix size: 2×3] -0.1000E-10 -0.1000E+11 1.000 1.000 1.000 1.000 disp(c): + [matrix size: 2×3] (1.000,0.000) (1.000,0.000) (1.000,0.000) (1.000,0.000) (-0.1000E+11,-0.1000E+11) (1.000,0.000) disp(i): + [matrix size: 2×3] + 1 1 1 1 1 1 disp(l): - T T + [matrix size: 10×10] + T T T ... T + T T T ... T + T T T ... T + : : : : : + T T T ... T disp(c_3d, 3): - Slice (:,:,1): - (2.000,0.000) (2.000,0.000) (1000.,0.1000E-2) - (2.000,0.000) (2.000,0.000) (2.000,0.000) - Slice (:,:,2): - (2.000,0.000) (2.000,0.000) (0.1000E+5,100.0) - (2.000,0.000) (2.000,0.000) (2.000,0.000) - disp(c_3d(1,:,:)): - (2.000,0.000) (2.000,0.000) - (2.000,0.000) (2.000,0.000) - (1000.,0.1000E-2) (0.1000E+5,100.0) + [matrix size: 2×100] + (2.000,0.000) (2.000,0.000) (2.000,0.000) ... (2.000,0.000) + (2.000,0.000) (2.000,0.000) (2.000,0.000) ... (2.000,0.000) + disp(c_3d, 2): + [matrix size: 100×20] + (2.000,0.000) (2.000,0.000) (2.000,0.000) ... (2.000,0.000) + (2.000,0.000) (2.000,0.000) (2.000,0.000) ... (2.000,0.000) + (2.000,0.000) (2.000,0.000) (2.000,0.000) ... (2.000,0.000) + : : : : : + (2.000,0.000) (2.000,0.000) (2.000,0.000) ... (2.000,0.000) ``` diff --git a/src/stdlib_io.fypp b/src/stdlib_io.fypp index 002b7b021..e94fdcc48 100644 --- a/src/stdlib_io.fypp +++ b/src/stdlib_io.fypp @@ -22,23 +22,26 @@ module stdlib_io interface disp !! version: experimental !! - !! Display any type of scalar and `array` with up to 3 dimensions to the default `output_unit` - !! ([Specification](../page/specs/stdlib_io.html#description_4)) + !! Display any type of scalar, vector and matrix. + !! ([Specification](../page/specs/stdlib_io.html)) #:set DISP_KINDS_TYPES = REAL_KINDS_TYPES + INT_KINDS_TYPES & & + CMPLX_KINDS_TYPES + LOG_KINDS_TYPES - #:set DISP_RANKS = range(0, 4) + #:set DISP_RANKS = range(0, 3) #:for kind, type in DISP_KINDS_TYPES #:for rank in DISP_RANKS - module subroutine disp_${rank}$_${type[0]}$${kind}$(value, #{if rank == 3}#dim, #{endif}#string) + module subroutine disp_${rank}$_${type[0]}$${kind}$(value, unit, header, brief) ${type}$, intent(in) :: value${ranksuffix(rank)}$ - #{if rank == 3}#integer, intent(in) :: dim#{endif}# - character(len=*), intent(in), optional :: string + integer, intent(in), optional :: unit + character(len=*), intent(in), optional :: header + logical, intent(in), optional :: brief end subroutine disp_${rank}$_${type[0]}$${kind}$ #:endfor #:endfor - module subroutine disp_str(value, string) + module subroutine disp_str(value, unit, header, brief) character(len=*), intent(in), optional :: value - character(len=*), intent(in), optional :: string + integer, intent(in), optional :: unit + character(len=*), intent(in), optional :: header + logical, intent(in), optional :: brief end subroutine disp_str end interface disp diff --git a/src/stdlib_io_disp.fypp b/src/stdlib_io_disp.fypp index 9a3aa617d..027d29677 100644 --- a/src/stdlib_io_disp.fypp +++ b/src/stdlib_io_disp.fypp @@ -5,6 +5,7 @@ submodule (stdlib_io) stdlib_io_disp use stdlib_ascii, only: to_string use stdlib_strings, only: format_to_string + use, intrinsic :: iso_fortran_env, only: output_unit implicit none character(len=*), parameter :: fmt_r = '(*(g12.4, 1x))' character(len=*), parameter :: fmt_c = '(*(g25.0, 1x))' @@ -13,118 +14,146 @@ contains #:for kind, type in RIL_KINDS_TYPES module procedure disp_0_${type[0]}$${kind}$ - !! Display a ${type}$ variable to the default `output_unit` - if(present(string)) print *, trim(string) - print fmt_r, value + !! Display a/an ${type}$ scalar. + integer :: unit_ + unit_ = merge(unit, output_unit, present(unit)) + if(present(header)) write(unit_, *) header + write(unit_, fmt_r) value end procedure disp_0_${type[0]}$${kind}$ module procedure disp_1_${type[0]}$${kind}$ - !! Display a ${type}$ vector variable to the default `output_unit` - if(present(string)) print *, trim(string) - print fmt_r, value(:) + !! Display a/an ${type}$ vector. + integer :: unit_ + logical :: brief_ + integer :: m + unit_ = merge(unit, output_unit, present(unit)) + brief_ = merge(brief, .false., present(brief)) + m = size(value, 1) + if(present(header)) write(unit_, *) header + write(unit_, *) '[vector size: '//to_string(m)//']' + if(brief_ .and. m > 5) then + write(unit_, fmt_r) value(1:3), '...', value(m) + else + write(unit_, fmt_r) value(:) + end if end procedure disp_1_${type[0]}$${kind}$ module procedure disp_2_${type[0]}$${kind}$ - !! Display a ${type}$ 2D array variable to the default `output_unit` - integer :: i, m + !! Display a/an ${type}$ matrix. + integer :: unit_ + logical :: brief_ + character(1) :: colon(5) + integer :: i, m, n + unit_ = merge(unit, output_unit, present(unit)) + brief_ = merge(brief, .false., present(brief)) m = size(value, 1) - if(present(string)) print *, trim(string) - do i = 1, m - print fmt_r, value(i,:) - end do - end procedure disp_2_${type[0]}$${kind}$ - - module procedure disp_3_${type[0]}$${kind}$ - !! Display a ${type}$ 3D array variable to the default `output_unit` - integer :: i, dim1, dim2, dim3 - dim1 = size(value, 1) - dim2 = size(value, 2) - dim3 = size(value, 3) - if(present(string)) print *, trim(string) - select case(dim) - case(1) - do i = 1, dim1 - print *, 'Slice ('//to_string(i)//',:,:):' - call disp_2_${type[0]}$${kind}$(value(i, :, :)) - end do - case(2) - do i = 1, dim2 - print *, 'Slice (:,'//to_string(i)//',:):' - call disp_2_${type[0]}$${kind}$(value(:, i, :)) - end do - case(3) - do i = 1, dim3 - print *, 'Slice (:,:,'//to_string(i)//'):' - call disp_2_${type[0]}$${kind}$(value(:, :, i)) + n = size(value, 2) + if(present(header)) write(unit_, *) header + write(unit_, *) '[matrix size: '//to_string(m)//'×'//to_string(n)//']' + if(brief_ .and. (m > 5 .or. n > 5)) then + if(m > 5 .and. n > 5) then + do i = 1, 3 + write(unit_, fmt_r) value(i,1:3), '...', value(i,n) + end do + write(unit_, fmt_r) ':', ':', ':', ':', ':' + write(unit_, fmt_r) value(m,1:3), '...', value(m,n) + elseif(m > 5 .and. n <= 5) then + do i = 1, 3 + write(unit_, fmt_r) value(i,:) + end do + colon(1:n) = ':' + write(unit_, fmt_r) colon(1:n) + write(unit_, fmt_r) value(m,:) + elseif(m <= 5 .and. n > 5) then + do i = 1, m + write(unit_, fmt_r) value(i,1:3), '...', value(i,n) + end do + end if + else + do i = 1, m + write(unit_, fmt_r) value(i,:) end do - case default - call error_stop('Error(disp): wrong dimension') - end select - end procedure disp_3_${type[0]}$${kind}$ + end if + end procedure disp_2_${type[0]}$${kind}$ #:endfor #:for kind, type in CMPLX_KINDS_TYPES module procedure disp_0_${type[0]}$${kind}$ - !! Display a ${type}$ variable to the default `output_unit` - if(present(string)) print *, trim(string) - print fmt_c, format_to_string(value, '(g0.4)') + !! Display a ${type}$ scalar. + integer :: unit_ + unit_ = merge(unit, output_unit, present(unit)) + if(present(header)) write(unit_, *) header + write(unit_, fmt_c) format_to_string(value, '(g0.4)') end procedure disp_0_${type[0]}$${kind}$ module procedure disp_1_${type[0]}$${kind}$ - !! Display a ${type}$ vector variable to the default `output_unit` + !! Display a ${type}$ vector. + integer :: unit_ + logical :: brief_ integer :: i, m - m = size(value) - if(present(string)) print *, trim(string) - print fmt_c, (format_to_string(value(i), '(g0.4)'), i=1, m) + unit_ = merge(unit, output_unit, present(unit)) + brief_ = merge(brief, .false., present(brief)) + m = size(value, 1) + if(present(header)) write(unit_, *) header + write(unit_, *) '[vector size: '//to_string(m)//']' + if(brief_ .and. m > 5) then + write(unit_, fmt_c) (format_to_string(value(i), '(g0.4)'), i=1, 3), & + '...', format_to_string(value(m), '(g0.4)') + else + write(unit_, fmt_c) (format_to_string(value(i), '(g0.4)'), i=1, m) + end if end procedure disp_1_${type[0]}$${kind}$ module procedure disp_2_${type[0]}$${kind}$ - !! Display a ${type}$ 2D array variable to the default `output_unit` + !! Display a ${type}$ matrix. + integer :: unit_ + logical :: brief_ + character(1) :: colon(5) integer :: i, j, m, n + unit_ = merge(unit, output_unit, present(unit)) + brief_ = merge(brief, .false., present(brief)) m = size(value, 1) n = size(value, 2) - if(present(string)) print *, trim(string) - do i = 1, m - print fmt_c, (format_to_string(value(i, j), '(g0.4)'), j=1, n) - end do - end procedure disp_2_${type[0]}$${kind}$ - - module procedure disp_3_${type[0]}$${kind}$ - !! Display a ${type}$ 3D array variable to the default `output_unit` - integer :: i, dim1, dim2, dim3 - dim1 = size(value, 1) - dim2 = size(value, 2) - dim3 = size(value, 3) - if(present(string)) print *, trim(string) - if(dim == 1) then - do i = 1, dim1 - print *, 'Slice ('//to_string(i)//',:,:):' - call disp_2_${type[0]}$${kind}$(value(i, :, :)) - end do - elseif(dim == 2) then - do i = 1, dim2 - print *, 'Slice (:,'//to_string(i)//',:):' - call disp_2_${type[0]}$${kind}$(value(:, i, :)) - end do - elseif (dim == 3) then - do i = 1, dim3 - print *, 'Slice (:,:,'//to_string(i)//'):' - call disp_2_${type[0]}$${kind}$(value(:, :, i)) - end do + if(present(header)) write(unit_, *) header + write(unit_, *) '[matrix size: '//to_string(m)//'×'//to_string(n)//']' + if(brief_ .and. (m > 5 .or. n > 5)) then + if(m > 5 .and. n > 5) then + do i = 1, 3 + write(unit_, fmt_c) (format_to_string(value(i,j), '(g0.4)'), j=1, 3), & + '...', format_to_string(value(i,n), '(g0.4)') + end do + write(unit_, fmt_c) ':', ':', ':', ':', ':' + write(unit_, fmt_c) (format_to_string(value(m,j), '(g0.4)'), j=1, 3), & + '...', format_to_string(value(m,n), '(g0.4)') + elseif(m > 5 .and. n <= 5) then + do i = 1, 3 + write(unit_, fmt_c) (format_to_string(value(i,j), '(g0.4)'), j=1, n) + end do + colon(1:n) = ':' + write(unit_, fmt_c) colon(1:n) + write(unit_, fmt_c) (format_to_string(value(m,j), '(g0.4)'), j=1, n) + elseif(m <= 5 .and. n > 5) then + do i = 1, m + write(unit_, fmt_c) (format_to_string(value(m,j), '(g0.4)'), j=1, 3), & + '...', format_to_string(value(m,n), '(g0.4)') + end do + end if else - call error_stop('Error(disp): wrong dimension') + do i = 1, m + write(unit_, fmt_c) (format_to_string(value(i,j), '(g0.4)'), j=1, n) + end do end if - end procedure disp_3_${type[0]}$${kind}$ + end procedure disp_2_${type[0]}$${kind}$ #:endfor module procedure disp_str - !! Display a character variable to the default `output_unit` - if(present(string)) print *, trim(string) - if(present(value)) then - print *, trim(value) - else - print *, '' - end if + !! Display a `character` scalar. + character(:), allocatable :: value_ + integer :: unit_ + value_ = optval(value, '') + unit_ = merge(unit, output_unit, present(unit)) + if(present(header)) write(unit_, *) header + write(unit_, *) value_ end procedure disp_str end submodule stdlib_io_disp \ No newline at end of file diff --git a/src/tests/io/test_io_disp.f90 b/src/tests/io/test_io_disp.f90 index 6bb7ccfec..c17284fc6 100644 --- a/src/tests/io/test_io_disp.f90 +++ b/src/tests/io/test_io_disp.f90 @@ -1,10 +1,11 @@ program test_io_disp - use, non_intrinsic :: stdlib_io, only: disp + + use :: stdlib_io, only: disp implicit none real(8) :: r(2, 3) - complex :: c(2, 3), c_3d(2, 3, 2) + complex :: c(2, 3), c_3d(2, 100, 20) integer :: i(2, 3) - logical :: l(2, 3) + logical :: l(10, 10) r = 1.; c = 1.; c_3d = 2.; i = 1; l = .true. r(1, 1) = -1.e-11 @@ -12,15 +13,16 @@ program test_io_disp c(2, 2) = (-1.e10,-1.e10) c_3d(1,3,1) = (1000, 0.001) c_3d(1,3,2) = (1.e4, 100.) - call disp('string', 'disp(string):') - call disp('It is a note.') - call disp() + call disp('string', header='disp(string):') + call disp('It is a note.') + call disp() - call disp(r, 'disp(r):') - call disp(c, 'disp(c):') - call disp(i, 'disp(i):') - call disp(l, 'disp(l):') + call disp(r, header='disp(r):') + call disp(c, header='disp(c):') + call disp(i, header='disp(i):') + call disp(l, header='disp(l):', brief=.true.) + + call disp(c_3d(:,:,3), header='disp(c_3d, 3):', brief=.true.) + call disp(c_3d(2,:,:), header='disp(c_3d, 2):', brief=.true.) - call disp(c_3d, 3, 'disp(c_3d, 3):') - call disp(c_3d, 2, 'disp(c_3d, 2):') end program test_io_disp \ No newline at end of file From 652aad849ec552fc44dd693356f711b682ee7d32 Mon Sep 17 00:00:00 2001 From: zoziha13 <1325686572@qq.com> Date: Wed, 7 Jul 2021 17:51:56 +0800 Subject: [PATCH 05/14] an other -> another --- doc/specs/stdlib_io.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/specs/stdlib_io.md b/doc/specs/stdlib_io.md index e77c776d3..e1c61fd18 100644 --- a/doc/specs/stdlib_io.md +++ b/doc/specs/stdlib_io.md @@ -132,7 +132,7 @@ program demo_savetxt end program demo_savetxt ``` -## `disp` - display your data to the screen (or an other output unit) +## `disp` - display your data to the screen (or another output unit) ### Status @@ -173,7 +173,7 @@ For null: ### Output -The result is to print `header` and `value` on the screen (or an other output unit) in this order. +The result is to print `header` and `value` on the screen (or another output unit) in this order. If `value` is a `array` type, the dimension length information of the `array` will also be output. ### Example From f10333d7f0953ceabb3419bafe01f20cb05bde89 Mon Sep 17 00:00:00 2001 From: zoziha13 <1325686572@qq.com> Date: Sat, 10 Jul 2021 13:48:47 +0800 Subject: [PATCH 06/14] Add a valid `test_io_disp.f90` --- doc/specs/stdlib_io.md | 18 +- src/stdlib_io_disp.fypp | 27 +-- src/tests/io/test_io_disp.f90 | 404 +++++++++++++++++++++++++++++++--- 3 files changed, 402 insertions(+), 47 deletions(-) diff --git a/doc/specs/stdlib_io.md b/doc/specs/stdlib_io.md index e1c61fd18..4bea7d810 100644 --- a/doc/specs/stdlib_io.md +++ b/doc/specs/stdlib_io.md @@ -143,7 +143,7 @@ Display any type of scalar, vector or matrix. Make good use of similar to the following usage, can help you understand the data information in the `array`. ```fortran -call disp( A(i, j, 2, :, :) [, unit, header, brief] ) !! `i, j, ...` can be determined by `do` loop. +call disp( A(i, j, 2, :, 1:10) [, unit, header, brief] ) !! `i, j, ...` can be determined by `do` loop. ``` Generally, except for `complex` type, any other type of scalar or single element of the `array` will be printed out with a width of 12 characters and a space separator. @@ -174,7 +174,7 @@ For null: ### Output The result is to print `header` and `value` on the screen (or another output unit) in this order. -If `value` is a `array` type, the dimension length information of the `array` will also be output. +If `value` is a `array` type, the dimension length information of the `array` will also be outputed. ### Example @@ -199,18 +199,19 @@ program test_io_disp call disp() call disp(r, header='disp(r):') + call disp(r(1,:), header='disp(r(1,:))') call disp(c, header='disp(c):') call disp(i, header='disp(i):') call disp(l, header='disp(l):', brief=.true.) - call disp(c_3d(:,:,3), header='disp(c_3d, 3):', brief=.true.) - call disp(c_3d(2,:,:), header='disp(c_3d, 2):', brief=.true.) + call disp(c_3d(:,:,3), header='disp(c_3d(:,:,3)):', brief=.true.) + call disp(c_3d(2,:,:), header='disp(c_3d(2,:,:)):', brief=.true.) end program test_io_disp ``` **Result:** ```fortran -disp(string): + disp(string): string It is a note. @@ -218,6 +219,9 @@ disp(string): [matrix size: 2×3] -0.1000E-10 -0.1000E+11 1.000 1.000 1.000 1.000 + disp(r(1,:)) + [vector size: 3] + -0.1000E-10 -0.1000E+11 1.000 disp(c): [matrix size: 2×3] (1.000,0.000) (1.000,0.000) (1.000,0.000) @@ -233,11 +237,11 @@ disp(string): T T T ... T : : : : : T T T ... T - disp(c_3d, 3): + disp(c_3d(:,:,3)): [matrix size: 2×100] (2.000,0.000) (2.000,0.000) (2.000,0.000) ... (2.000,0.000) (2.000,0.000) (2.000,0.000) (2.000,0.000) ... (2.000,0.000) - disp(c_3d, 2): + disp(c_3d(2,:,:)): [matrix size: 100×20] (2.000,0.000) (2.000,0.000) (2.000,0.000) ... (2.000,0.000) (2.000,0.000) (2.000,0.000) (2.000,0.000) ... (2.000,0.000) diff --git a/src/stdlib_io_disp.fypp b/src/stdlib_io_disp.fypp index 027d29677..e6ccf3871 100644 --- a/src/stdlib_io_disp.fypp +++ b/src/stdlib_io_disp.fypp @@ -9,6 +9,7 @@ submodule (stdlib_io) stdlib_io_disp implicit none character(len=*), parameter :: fmt_r = '(*(g12.4, 1x))' character(len=*), parameter :: fmt_c = '(*(g25.0, 1x))' + character(len=*), parameter :: format_ = '(g0.4)' contains @@ -83,7 +84,7 @@ contains integer :: unit_ unit_ = merge(unit, output_unit, present(unit)) if(present(header)) write(unit_, *) header - write(unit_, fmt_c) format_to_string(value, '(g0.4)') + write(unit_, fmt_c) format_to_string(value, format_) end procedure disp_0_${type[0]}$${kind}$ module procedure disp_1_${type[0]}$${kind}$ @@ -97,10 +98,10 @@ contains if(present(header)) write(unit_, *) header write(unit_, *) '[vector size: '//to_string(m)//']' if(brief_ .and. m > 5) then - write(unit_, fmt_c) (format_to_string(value(i), '(g0.4)'), i=1, 3), & - '...', format_to_string(value(m), '(g0.4)') + write(unit_, fmt_c) (format_to_string(value(i), format_), i=1, 3), & + '...', format_to_string(value(m), format_) else - write(unit_, fmt_c) (format_to_string(value(i), '(g0.4)'), i=1, m) + write(unit_, fmt_c) (format_to_string(value(i), format_), i=1, m) end if end procedure disp_1_${type[0]}$${kind}$ @@ -119,28 +120,28 @@ contains if(brief_ .and. (m > 5 .or. n > 5)) then if(m > 5 .and. n > 5) then do i = 1, 3 - write(unit_, fmt_c) (format_to_string(value(i,j), '(g0.4)'), j=1, 3), & - '...', format_to_string(value(i,n), '(g0.4)') + write(unit_, fmt_c) (format_to_string(value(i,j), format_), j=1, 3), & + '...', format_to_string(value(i,n), format_) end do write(unit_, fmt_c) ':', ':', ':', ':', ':' - write(unit_, fmt_c) (format_to_string(value(m,j), '(g0.4)'), j=1, 3), & - '...', format_to_string(value(m,n), '(g0.4)') + write(unit_, fmt_c) (format_to_string(value(m,j), format_), j=1, 3), & + '...', format_to_string(value(m,n), format_) elseif(m > 5 .and. n <= 5) then do i = 1, 3 - write(unit_, fmt_c) (format_to_string(value(i,j), '(g0.4)'), j=1, n) + write(unit_, fmt_c) (format_to_string(value(i,j), format_), j=1, n) end do colon(1:n) = ':' write(unit_, fmt_c) colon(1:n) - write(unit_, fmt_c) (format_to_string(value(m,j), '(g0.4)'), j=1, n) + write(unit_, fmt_c) (format_to_string(value(m,j), format_), j=1, n) elseif(m <= 5 .and. n > 5) then do i = 1, m - write(unit_, fmt_c) (format_to_string(value(m,j), '(g0.4)'), j=1, 3), & - '...', format_to_string(value(m,n), '(g0.4)') + write(unit_, fmt_c) (format_to_string(value(m,j), format_), j=1, 3), & + '...', format_to_string(value(m,n), format_) end do end if else do i = 1, m - write(unit_, fmt_c) (format_to_string(value(i,j), '(g0.4)'), j=1, n) + write(unit_, fmt_c) (format_to_string(value(i,j), format_), j=1, n) end do end if end procedure disp_2_${type[0]}$${kind}$ diff --git a/src/tests/io/test_io_disp.f90 b/src/tests/io/test_io_disp.f90 index c17284fc6..c65be16dd 100644 --- a/src/tests/io/test_io_disp.f90 +++ b/src/tests/io/test_io_disp.f90 @@ -1,28 +1,378 @@ -program test_io_disp - - use :: stdlib_io, only: disp +module test_io_disp + + use stdlib_strings, only: starts_with + use stdlib_error, only: check + use stdlib_io, only: disp, open implicit none - real(8) :: r(2, 3) - complex :: c(2, 3), c_3d(2, 100, 20) - integer :: i(2, 3) - logical :: l(10, 10) - - r = 1.; c = 1.; c_3d = 2.; i = 1; l = .true. - r(1, 1) = -1.e-11 - r(1, 2) = -1.e10 - c(2, 2) = (-1.e10,-1.e10) - c_3d(1,3,1) = (1000, 0.001) - c_3d(1,3,2) = (1.e4, 100.) - call disp('string', header='disp(string):') - call disp('It is a note.') - call disp() - - call disp(r, header='disp(r):') - call disp(c, header='disp(c):') - call disp(i, header='disp(i):') - call disp(l, header='disp(l):', brief=.true.) - - call disp(c_3d(:,:,3), header='disp(c_3d, 3):', brief=.true.) - call disp(c_3d(2,:,:), header='disp(c_3d, 2):', brief=.true.) - -end program test_io_disp \ No newline at end of file + + integer :: unit + character(*), parameter :: filenanme = "./test_io_disp.tmp" + character(len=512) :: string + +contains + + subroutine check_formatter(actual, expected, description, partial) + character(len=*), intent(in) :: actual, expected, description + logical, intent(in), optional :: partial + logical :: stat + character(len=:), allocatable :: msg + + if (merge(partial, .false., present(partial))) then + stat = starts_with(actual, expected) + else + stat = actual == expected + end if + + if (.not. stat) then + msg = description//new_line("a")// & + & "Expected: '"//expected//"' but got '"//actual//"'" + else + print '(" - ", a, /, " Result: ''", a, "''")', description, actual + end if + + call check(stat, msg) + + end subroutine check_formatter + + subroutine test_io_disp_complex + complex :: c(6,6) = (1.0, 1.0) + ! unit = open(filenanme, 'w+t') + open(newunit=unit, file=filenanme) + call disp(c(1,1), header='Test_io_disp_complex_scalar (brief) : ', brief=.true.) + call disp(c(1,1), unit=unit, header='Test_io_disp_complex_scalar (brief) : ', brief=.true.) + + call disp(c(1,:), header='Test_io_disp_complex_vector (brief) : ', brief=.true.) + call disp(c(1,:), unit=unit, header='Test_io_disp_complex_vector (brief) : ', brief=.true.) + + call disp(c(:,1), header='Test_io_disp_complex_vector : ', brief=.false.) + call disp(c(:,1), unit=unit, header='Test_io_disp_complex_vector : ', brief=.false.) + + call disp(c(1:2,1:2), header='Test_io_disp_complex_matrix : ', brief=.false.) + call disp(c(1:2,1:2), unit=unit, header='Test_io_disp_complex_matrix : ', brief=.false.) + + call disp(c(:,:), header='Test_io_disp_complex_matrix (brief) : ', brief=.true.) + call disp(c(:,:), unit=unit, header='Test_io_disp_complex_matrix (brief) : ', brief=.true.) + + !! Checks + rewind(unit) + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), 'Test_io_disp_complex_scalar (brief) :', 'Header') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), '(1.000,1.000)', 'Value') + + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), 'Test_io_disp_complex_vector (brief) :', 'Header') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), '[vector size: 6]', 'Vector Info') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), & + '(1.000,1.000) (1.000,1.000) (1.000,1.000) & + & ... (1.000,1.000)', 'Brief Vector') + + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), 'Test_io_disp_complex_vector :', 'Header') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), '[vector size: 6]', 'Vector Info') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), & + '(1.000,1.000) (1.000,1.000) (1.000,1.000) & + & (1.000,1.000) (1.000,1.000) (1.000,1.000)', 'Brief Vector') + + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), 'Test_io_disp_complex_matrix :', 'Header') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), '[matrix size: 2×2]', 'Matrix Info') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), & + '(1.000,1.000) (1.000,1.000)', 'Matrix Vector 1') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), & + '(1.000,1.000) (1.000,1.000)', 'Matrix Vector 2') + + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), 'Test_io_disp_complex_matrix (brief) :', 'Header') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), '[matrix size: 6×6]', 'Matrix Info') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), & + '(1.000,1.000) (1.000,1.000) (1.000,1.000) & + & ... (1.000,1.000)', 'Matrix Vector 1') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), & + '(1.000,1.000) (1.000,1.000) (1.000,1.000) & + & ... (1.000,1.000)', 'Matrix Vector 2') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), & + '(1.000,1.000) (1.000,1.000) (1.000,1.000) & + & ... (1.000,1.000)', 'Matrix Vector 3') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), & + ': : : & + & : :', 'Matrix Vector ..') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), & + '(1.000,1.000) (1.000,1.000) (1.000,1.000) & + & ... (1.000,1.000)', 'Matrix Vector Size(Matrix, 1)') + close(unit) + + end subroutine test_io_disp_complex + + subroutine test_io_disp_real + + real :: r(6,6) = 1.0 + ! unit = open(filenanme, 'w+t') + open(newunit=unit, file=filenanme) + call disp(r(1,1), header='Test_io_disp_real_scalar (brief) : ', brief=.true.) + call disp(r(1,1), unit=unit, header='Test_io_disp_real_scalar (brief) : ', brief=.true.) + + call disp(r(1,:), header='Test_io_disp_real_vector (brief) : ', brief=.true.) + call disp(r(1,:), unit=unit, header='Test_io_disp_real_vector (brief) : ', brief=.true.) + + call disp(r(:,1), header='Test_io_disp_real_vector : ', brief=.false.) + call disp(r(:,1), unit=unit, header='Test_io_disp_real_vector : ', brief=.false.) + + call disp(r(1:2,1:2), header='Test_io_disp_real_matrix : ', brief=.false.) + call disp(r(1:2,1:2), unit=unit, header='Test_io_disp_real_matrix : ', brief=.false.) + + call disp(r(:,:), header='Test_io_disp_real_matrix (brief) : ', brief=.true.) + call disp(r(:,:), unit=unit, header='Test_io_disp_real_matrix (brief) : ', brief=.true.) + + !! Checks + rewind(unit) + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), 'Test_io_disp_real_scalar (brief) :', 'Header') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), '1.000', 'Value') + + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), 'Test_io_disp_real_vector (brief) :', 'Header') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), '[vector size: 6]', 'Vector Info') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), & + '1.000 1.000 1.000 ... 1.000', 'Brief Vector') + + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), 'Test_io_disp_real_vector :', 'Header') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), '[vector size: 6]', 'Vector Info') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), & + '1.000 1.000 1.000 1.000 1.000 1.000', 'Brief Vector') + + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), 'Test_io_disp_real_matrix :', 'Header') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), '[matrix size: 2×2]', 'Matrix Info') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), & + '1.000 1.000', 'Matrix Vector 1') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), & + '1.000 1.000', 'Matrix Vector 2') + + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), 'Test_io_disp_real_matrix (brief) :', 'Header') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), '[matrix size: 6×6]', 'Matrix Info') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), & + '1.000 1.000 1.000 ... 1.000', 'Matrix Vector 1') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), & + '1.000 1.000 1.000 ... 1.000', 'Matrix Vector 2') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), & + '1.000 1.000 1.000 ... 1.000', 'Matrix Vector 3') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), & + ': : : : :', 'Matrix Vector ..') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), & + '1.000 1.000 1.000 ... 1.000', 'Matrix Vector Size(Matrix, 1)') + close(unit) + + end subroutine test_io_disp_real + + subroutine test_io_disp_integer + + integer :: i(6,6) = 1 + ! unit = open(filenanme, 'w+t') + open(newunit=unit, file=filenanme) + call disp(i(1,1), header='Test_io_disp_integer_scalar (brief) : ', brief=.true.) + call disp(i(1,1), unit=unit, header='Test_io_disp_integer_scalar (brief) : ', brief=.true.) + + call disp(i(1,:), header='Test_io_disp_integer_vector (brief) : ', brief=.true.) + call disp(i(1,:), unit=unit, header='Test_io_disp_integer_vector (brief) : ', brief=.true.) + + call disp(i(:,1), header='Test_io_disp_integer_vector : ', brief=.false.) + call disp(i(:,1), unit=unit, header='Test_io_disp_integer_vector : ', brief=.false.) + + call disp(i(1:2,1:2), header='Test_io_disp_integer_matrix : ', brief=.false.) + call disp(i(1:2,1:2), unit=unit, header='Test_io_disp_integer_matrix : ', brief=.false.) + + call disp(i(:,:), header='Test_io_disp_integer_matrix (brief) : ', brief=.true.) + call disp(i(:,:), unit=unit, header='Test_io_disp_integer_matrix (brief) : ', brief=.true.) + + !! Checks + rewind(unit) + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), 'Test_io_disp_integer_scalar (brief) :', 'Header') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), '1', 'Value') + + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), 'Test_io_disp_integer_vector (brief) :', 'Header') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), '[vector size: 6]', 'Vector Info') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), & + '1 1 1 ... 1', 'Brief Vector') + + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), 'Test_io_disp_integer_vector :', 'Header') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), '[vector size: 6]', 'Vector Info') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), & + '1 1 1 1 1 1', 'Brief Vector') + + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), 'Test_io_disp_integer_matrix :', 'Header') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), '[matrix size: 2×2]', 'Matrix Info') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), & + '1 1', 'Matrix Vector 1') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), & + '1 1', 'Matrix Vector 2') + + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), 'Test_io_disp_integer_matrix (brief) :', 'Header') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), '[matrix size: 6×6]', 'Matrix Info') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), & + '1 1 1 ... 1', 'Matrix Vector 1') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), & + '1 1 1 ... 1', 'Matrix Vector 2') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), & + '1 1 1 ... 1', 'Matrix Vector 3') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), & + ': : : : :', 'Matrix Vector ..') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), & + '1 1 1 ... 1', 'Matrix Vector Size(Matrix, 1)') + close(unit) + + end subroutine test_io_disp_integer + + subroutine test_io_disp_logical + + logical :: l(6,6) = .true. + ! unit = open(filenanme, 'w+t') + open(newunit=unit, file=filenanme) + call disp(l(1,1), header='Test_io_disp_logical_scalar (brief) : ', brief=.true.) + call disp(l(1,1), unit=unit, header='Test_io_disp_logical_scalar (brief) : ', brief=.true.) + + call disp(l(1,:), header='Test_io_disp_logical_vector (brief) : ', brief=.true.) + call disp(l(1,:), unit=unit, header='Test_io_disp_logical_vector (brief) : ', brief=.true.) + + call disp(l(:,1), header='Test_io_disp_logical_vector : ', brief=.false.) + call disp(l(:,1), unit=unit, header='Test_io_disp_logical_vector : ', brief=.false.) + + call disp(l(1:2,1:2), header='Test_io_disp_logical_matrix : ', brief=.false.) + call disp(l(1:2,1:2), unit=unit, header='Test_io_disp_logical_matrix : ', brief=.false.) + + call disp(l(:,:), header='Test_io_disp_logical_matrix (brief) : ', brief=.true.) + call disp(l(:,:), unit=unit, header='Test_io_disp_logical_matrix (brief) : ', brief=.true.) + + !! Checks + rewind(unit) + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), 'Test_io_disp_logical_scalar (brief) :', 'Header') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), 'T', 'Value') + + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), 'Test_io_disp_logical_vector (brief) :', 'Header') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), '[vector size: 6]', 'Vector Info') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), & + 'T T T ... T', 'Brief Vector') + + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), 'Test_io_disp_logical_vector :', 'Header') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), '[vector size: 6]', 'Vector Info') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), & + 'T T T T T T', 'Brief Vector') + + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), 'Test_io_disp_logical_matrix :', 'Header') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), '[matrix size: 2×2]', 'Matrix Info') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), & + 'T T', 'Matrix Vector 1') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), & + 'T T', 'Matrix Vector 2') + + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), 'Test_io_disp_logical_matrix (brief) :', 'Header') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), '[matrix size: 6×6]', 'Matrix Info') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), & + 'T T T ... T', 'Matrix Vector 1') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), & + 'T T T ... T', 'Matrix Vector 2') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), & + 'T T T ... T', 'Matrix Vector 3') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), & + ': : : : :', 'Matrix Vector ..') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), & + 'T T T ... T', 'Matrix Vector Size(Matrix, 1)') + close(unit) + + end subroutine test_io_disp_logical + + subroutine test_io_disp_string + + character(*), parameter :: str = 'It is a string.' + ! unit = open(filenanme, 'w+t') + open(newunit=unit, file=filenanme) + call disp(str, header='Test_io_disp_string_scalar (brief) : ', brief=.true.) + call disp(str, unit=unit, header='Test_io_disp_string_scalar (brief) : ', brief=.true.) + + !! Checks + rewind(unit) + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), 'Test_io_disp_string_scalar (brief) :', 'Header') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), 'It is a string.', 'Value') + close(unit) + + end subroutine test_io_disp_string + +end module test_io_disp + +program tester + use test_io_disp + call test_io_disp_complex + call test_io_disp_real + call test_io_disp_integer + call test_io_disp_logical + call test_io_disp_string +end program tester From 4e94891b758a95abe7a57e076e725860533c4988 Mon Sep 17 00:00:00 2001 From: zoziha13 <1325686572@qq.com> Date: Mon, 12 Jul 2021 00:10:59 +0800 Subject: [PATCH 07/14] Correct spelling errors --- doc/specs/stdlib_io.md | 4 ++-- src/stdlib_io.fypp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/specs/stdlib_io.md b/doc/specs/stdlib_io.md index 4bea7d810..8ecf49c3e 100644 --- a/doc/specs/stdlib_io.md +++ b/doc/specs/stdlib_io.md @@ -168,13 +168,13 @@ For null: `header`: Shall be a scalar of type `character` with any length (usually used to comment data information). This is an `intent(in)` and `optional` argument. -`brief`: Shall be an `logical` scalar, controling an abridged version of the `value` object is printed. +`brief`: Shall be an `logical` scalar, controlling an abridged version of the `value` object is printed. This is an `intent(in)` and `optional` argument. ### Output The result is to print `header` and `value` on the screen (or another output unit) in this order. -If `value` is a `array` type, the dimension length information of the `array` will also be outputed. +If `value` is a `array` type, the dimension length information of the `array` will also be outputted. ### Example diff --git a/src/stdlib_io.fypp b/src/stdlib_io.fypp index e94fdcc48..a3a38bb59 100644 --- a/src/stdlib_io.fypp +++ b/src/stdlib_io.fypp @@ -23,7 +23,7 @@ module stdlib_io !! version: experimental !! !! Display any type of scalar, vector and matrix. - !! ([Specification](../page/specs/stdlib_io.html)) + !! ([Specification](../page/specs/stdlib_io.html#disp-display-your-data-to-the-screen-or-another-output-unit)) #:set DISP_KINDS_TYPES = REAL_KINDS_TYPES + INT_KINDS_TYPES & & + CMPLX_KINDS_TYPES + LOG_KINDS_TYPES #:set DISP_RANKS = range(0, 3) From 328ea755155bff5848fdb0e67345cb437035d776 Mon Sep 17 00:00:00 2001 From: zoziha13 <1325686572@qq.com> Date: Mon, 12 Jul 2021 00:11:48 +0800 Subject: [PATCH 08/14] Add a valid `test_io_disp.f90` --- doc/specs/stdlib_io.md | 18 +- src/stdlib_io_disp.fypp | 27 +-- src/tests/io/test_io_disp.f90 | 404 +++++++++++++++++++++++++++++++--- 3 files changed, 402 insertions(+), 47 deletions(-) diff --git a/doc/specs/stdlib_io.md b/doc/specs/stdlib_io.md index e1c61fd18..4bea7d810 100644 --- a/doc/specs/stdlib_io.md +++ b/doc/specs/stdlib_io.md @@ -143,7 +143,7 @@ Display any type of scalar, vector or matrix. Make good use of similar to the following usage, can help you understand the data information in the `array`. ```fortran -call disp( A(i, j, 2, :, :) [, unit, header, brief] ) !! `i, j, ...` can be determined by `do` loop. +call disp( A(i, j, 2, :, 1:10) [, unit, header, brief] ) !! `i, j, ...` can be determined by `do` loop. ``` Generally, except for `complex` type, any other type of scalar or single element of the `array` will be printed out with a width of 12 characters and a space separator. @@ -174,7 +174,7 @@ For null: ### Output The result is to print `header` and `value` on the screen (or another output unit) in this order. -If `value` is a `array` type, the dimension length information of the `array` will also be output. +If `value` is a `array` type, the dimension length information of the `array` will also be outputed. ### Example @@ -199,18 +199,19 @@ program test_io_disp call disp() call disp(r, header='disp(r):') + call disp(r(1,:), header='disp(r(1,:))') call disp(c, header='disp(c):') call disp(i, header='disp(i):') call disp(l, header='disp(l):', brief=.true.) - call disp(c_3d(:,:,3), header='disp(c_3d, 3):', brief=.true.) - call disp(c_3d(2,:,:), header='disp(c_3d, 2):', brief=.true.) + call disp(c_3d(:,:,3), header='disp(c_3d(:,:,3)):', brief=.true.) + call disp(c_3d(2,:,:), header='disp(c_3d(2,:,:)):', brief=.true.) end program test_io_disp ``` **Result:** ```fortran -disp(string): + disp(string): string It is a note. @@ -218,6 +219,9 @@ disp(string): [matrix size: 2×3] -0.1000E-10 -0.1000E+11 1.000 1.000 1.000 1.000 + disp(r(1,:)) + [vector size: 3] + -0.1000E-10 -0.1000E+11 1.000 disp(c): [matrix size: 2×3] (1.000,0.000) (1.000,0.000) (1.000,0.000) @@ -233,11 +237,11 @@ disp(string): T T T ... T : : : : : T T T ... T - disp(c_3d, 3): + disp(c_3d(:,:,3)): [matrix size: 2×100] (2.000,0.000) (2.000,0.000) (2.000,0.000) ... (2.000,0.000) (2.000,0.000) (2.000,0.000) (2.000,0.000) ... (2.000,0.000) - disp(c_3d, 2): + disp(c_3d(2,:,:)): [matrix size: 100×20] (2.000,0.000) (2.000,0.000) (2.000,0.000) ... (2.000,0.000) (2.000,0.000) (2.000,0.000) (2.000,0.000) ... (2.000,0.000) diff --git a/src/stdlib_io_disp.fypp b/src/stdlib_io_disp.fypp index 027d29677..e6ccf3871 100644 --- a/src/stdlib_io_disp.fypp +++ b/src/stdlib_io_disp.fypp @@ -9,6 +9,7 @@ submodule (stdlib_io) stdlib_io_disp implicit none character(len=*), parameter :: fmt_r = '(*(g12.4, 1x))' character(len=*), parameter :: fmt_c = '(*(g25.0, 1x))' + character(len=*), parameter :: format_ = '(g0.4)' contains @@ -83,7 +84,7 @@ contains integer :: unit_ unit_ = merge(unit, output_unit, present(unit)) if(present(header)) write(unit_, *) header - write(unit_, fmt_c) format_to_string(value, '(g0.4)') + write(unit_, fmt_c) format_to_string(value, format_) end procedure disp_0_${type[0]}$${kind}$ module procedure disp_1_${type[0]}$${kind}$ @@ -97,10 +98,10 @@ contains if(present(header)) write(unit_, *) header write(unit_, *) '[vector size: '//to_string(m)//']' if(brief_ .and. m > 5) then - write(unit_, fmt_c) (format_to_string(value(i), '(g0.4)'), i=1, 3), & - '...', format_to_string(value(m), '(g0.4)') + write(unit_, fmt_c) (format_to_string(value(i), format_), i=1, 3), & + '...', format_to_string(value(m), format_) else - write(unit_, fmt_c) (format_to_string(value(i), '(g0.4)'), i=1, m) + write(unit_, fmt_c) (format_to_string(value(i), format_), i=1, m) end if end procedure disp_1_${type[0]}$${kind}$ @@ -119,28 +120,28 @@ contains if(brief_ .and. (m > 5 .or. n > 5)) then if(m > 5 .and. n > 5) then do i = 1, 3 - write(unit_, fmt_c) (format_to_string(value(i,j), '(g0.4)'), j=1, 3), & - '...', format_to_string(value(i,n), '(g0.4)') + write(unit_, fmt_c) (format_to_string(value(i,j), format_), j=1, 3), & + '...', format_to_string(value(i,n), format_) end do write(unit_, fmt_c) ':', ':', ':', ':', ':' - write(unit_, fmt_c) (format_to_string(value(m,j), '(g0.4)'), j=1, 3), & - '...', format_to_string(value(m,n), '(g0.4)') + write(unit_, fmt_c) (format_to_string(value(m,j), format_), j=1, 3), & + '...', format_to_string(value(m,n), format_) elseif(m > 5 .and. n <= 5) then do i = 1, 3 - write(unit_, fmt_c) (format_to_string(value(i,j), '(g0.4)'), j=1, n) + write(unit_, fmt_c) (format_to_string(value(i,j), format_), j=1, n) end do colon(1:n) = ':' write(unit_, fmt_c) colon(1:n) - write(unit_, fmt_c) (format_to_string(value(m,j), '(g0.4)'), j=1, n) + write(unit_, fmt_c) (format_to_string(value(m,j), format_), j=1, n) elseif(m <= 5 .and. n > 5) then do i = 1, m - write(unit_, fmt_c) (format_to_string(value(m,j), '(g0.4)'), j=1, 3), & - '...', format_to_string(value(m,n), '(g0.4)') + write(unit_, fmt_c) (format_to_string(value(m,j), format_), j=1, 3), & + '...', format_to_string(value(m,n), format_) end do end if else do i = 1, m - write(unit_, fmt_c) (format_to_string(value(i,j), '(g0.4)'), j=1, n) + write(unit_, fmt_c) (format_to_string(value(i,j), format_), j=1, n) end do end if end procedure disp_2_${type[0]}$${kind}$ diff --git a/src/tests/io/test_io_disp.f90 b/src/tests/io/test_io_disp.f90 index c17284fc6..c65be16dd 100644 --- a/src/tests/io/test_io_disp.f90 +++ b/src/tests/io/test_io_disp.f90 @@ -1,28 +1,378 @@ -program test_io_disp - - use :: stdlib_io, only: disp +module test_io_disp + + use stdlib_strings, only: starts_with + use stdlib_error, only: check + use stdlib_io, only: disp, open implicit none - real(8) :: r(2, 3) - complex :: c(2, 3), c_3d(2, 100, 20) - integer :: i(2, 3) - logical :: l(10, 10) - - r = 1.; c = 1.; c_3d = 2.; i = 1; l = .true. - r(1, 1) = -1.e-11 - r(1, 2) = -1.e10 - c(2, 2) = (-1.e10,-1.e10) - c_3d(1,3,1) = (1000, 0.001) - c_3d(1,3,2) = (1.e4, 100.) - call disp('string', header='disp(string):') - call disp('It is a note.') - call disp() - - call disp(r, header='disp(r):') - call disp(c, header='disp(c):') - call disp(i, header='disp(i):') - call disp(l, header='disp(l):', brief=.true.) - - call disp(c_3d(:,:,3), header='disp(c_3d, 3):', brief=.true.) - call disp(c_3d(2,:,:), header='disp(c_3d, 2):', brief=.true.) - -end program test_io_disp \ No newline at end of file + + integer :: unit + character(*), parameter :: filenanme = "./test_io_disp.tmp" + character(len=512) :: string + +contains + + subroutine check_formatter(actual, expected, description, partial) + character(len=*), intent(in) :: actual, expected, description + logical, intent(in), optional :: partial + logical :: stat + character(len=:), allocatable :: msg + + if (merge(partial, .false., present(partial))) then + stat = starts_with(actual, expected) + else + stat = actual == expected + end if + + if (.not. stat) then + msg = description//new_line("a")// & + & "Expected: '"//expected//"' but got '"//actual//"'" + else + print '(" - ", a, /, " Result: ''", a, "''")', description, actual + end if + + call check(stat, msg) + + end subroutine check_formatter + + subroutine test_io_disp_complex + complex :: c(6,6) = (1.0, 1.0) + ! unit = open(filenanme, 'w+t') + open(newunit=unit, file=filenanme) + call disp(c(1,1), header='Test_io_disp_complex_scalar (brief) : ', brief=.true.) + call disp(c(1,1), unit=unit, header='Test_io_disp_complex_scalar (brief) : ', brief=.true.) + + call disp(c(1,:), header='Test_io_disp_complex_vector (brief) : ', brief=.true.) + call disp(c(1,:), unit=unit, header='Test_io_disp_complex_vector (brief) : ', brief=.true.) + + call disp(c(:,1), header='Test_io_disp_complex_vector : ', brief=.false.) + call disp(c(:,1), unit=unit, header='Test_io_disp_complex_vector : ', brief=.false.) + + call disp(c(1:2,1:2), header='Test_io_disp_complex_matrix : ', brief=.false.) + call disp(c(1:2,1:2), unit=unit, header='Test_io_disp_complex_matrix : ', brief=.false.) + + call disp(c(:,:), header='Test_io_disp_complex_matrix (brief) : ', brief=.true.) + call disp(c(:,:), unit=unit, header='Test_io_disp_complex_matrix (brief) : ', brief=.true.) + + !! Checks + rewind(unit) + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), 'Test_io_disp_complex_scalar (brief) :', 'Header') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), '(1.000,1.000)', 'Value') + + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), 'Test_io_disp_complex_vector (brief) :', 'Header') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), '[vector size: 6]', 'Vector Info') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), & + '(1.000,1.000) (1.000,1.000) (1.000,1.000) & + & ... (1.000,1.000)', 'Brief Vector') + + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), 'Test_io_disp_complex_vector :', 'Header') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), '[vector size: 6]', 'Vector Info') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), & + '(1.000,1.000) (1.000,1.000) (1.000,1.000) & + & (1.000,1.000) (1.000,1.000) (1.000,1.000)', 'Brief Vector') + + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), 'Test_io_disp_complex_matrix :', 'Header') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), '[matrix size: 2×2]', 'Matrix Info') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), & + '(1.000,1.000) (1.000,1.000)', 'Matrix Vector 1') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), & + '(1.000,1.000) (1.000,1.000)', 'Matrix Vector 2') + + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), 'Test_io_disp_complex_matrix (brief) :', 'Header') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), '[matrix size: 6×6]', 'Matrix Info') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), & + '(1.000,1.000) (1.000,1.000) (1.000,1.000) & + & ... (1.000,1.000)', 'Matrix Vector 1') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), & + '(1.000,1.000) (1.000,1.000) (1.000,1.000) & + & ... (1.000,1.000)', 'Matrix Vector 2') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), & + '(1.000,1.000) (1.000,1.000) (1.000,1.000) & + & ... (1.000,1.000)', 'Matrix Vector 3') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), & + ': : : & + & : :', 'Matrix Vector ..') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), & + '(1.000,1.000) (1.000,1.000) (1.000,1.000) & + & ... (1.000,1.000)', 'Matrix Vector Size(Matrix, 1)') + close(unit) + + end subroutine test_io_disp_complex + + subroutine test_io_disp_real + + real :: r(6,6) = 1.0 + ! unit = open(filenanme, 'w+t') + open(newunit=unit, file=filenanme) + call disp(r(1,1), header='Test_io_disp_real_scalar (brief) : ', brief=.true.) + call disp(r(1,1), unit=unit, header='Test_io_disp_real_scalar (brief) : ', brief=.true.) + + call disp(r(1,:), header='Test_io_disp_real_vector (brief) : ', brief=.true.) + call disp(r(1,:), unit=unit, header='Test_io_disp_real_vector (brief) : ', brief=.true.) + + call disp(r(:,1), header='Test_io_disp_real_vector : ', brief=.false.) + call disp(r(:,1), unit=unit, header='Test_io_disp_real_vector : ', brief=.false.) + + call disp(r(1:2,1:2), header='Test_io_disp_real_matrix : ', brief=.false.) + call disp(r(1:2,1:2), unit=unit, header='Test_io_disp_real_matrix : ', brief=.false.) + + call disp(r(:,:), header='Test_io_disp_real_matrix (brief) : ', brief=.true.) + call disp(r(:,:), unit=unit, header='Test_io_disp_real_matrix (brief) : ', brief=.true.) + + !! Checks + rewind(unit) + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), 'Test_io_disp_real_scalar (brief) :', 'Header') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), '1.000', 'Value') + + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), 'Test_io_disp_real_vector (brief) :', 'Header') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), '[vector size: 6]', 'Vector Info') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), & + '1.000 1.000 1.000 ... 1.000', 'Brief Vector') + + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), 'Test_io_disp_real_vector :', 'Header') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), '[vector size: 6]', 'Vector Info') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), & + '1.000 1.000 1.000 1.000 1.000 1.000', 'Brief Vector') + + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), 'Test_io_disp_real_matrix :', 'Header') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), '[matrix size: 2×2]', 'Matrix Info') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), & + '1.000 1.000', 'Matrix Vector 1') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), & + '1.000 1.000', 'Matrix Vector 2') + + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), 'Test_io_disp_real_matrix (brief) :', 'Header') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), '[matrix size: 6×6]', 'Matrix Info') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), & + '1.000 1.000 1.000 ... 1.000', 'Matrix Vector 1') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), & + '1.000 1.000 1.000 ... 1.000', 'Matrix Vector 2') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), & + '1.000 1.000 1.000 ... 1.000', 'Matrix Vector 3') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), & + ': : : : :', 'Matrix Vector ..') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), & + '1.000 1.000 1.000 ... 1.000', 'Matrix Vector Size(Matrix, 1)') + close(unit) + + end subroutine test_io_disp_real + + subroutine test_io_disp_integer + + integer :: i(6,6) = 1 + ! unit = open(filenanme, 'w+t') + open(newunit=unit, file=filenanme) + call disp(i(1,1), header='Test_io_disp_integer_scalar (brief) : ', brief=.true.) + call disp(i(1,1), unit=unit, header='Test_io_disp_integer_scalar (brief) : ', brief=.true.) + + call disp(i(1,:), header='Test_io_disp_integer_vector (brief) : ', brief=.true.) + call disp(i(1,:), unit=unit, header='Test_io_disp_integer_vector (brief) : ', brief=.true.) + + call disp(i(:,1), header='Test_io_disp_integer_vector : ', brief=.false.) + call disp(i(:,1), unit=unit, header='Test_io_disp_integer_vector : ', brief=.false.) + + call disp(i(1:2,1:2), header='Test_io_disp_integer_matrix : ', brief=.false.) + call disp(i(1:2,1:2), unit=unit, header='Test_io_disp_integer_matrix : ', brief=.false.) + + call disp(i(:,:), header='Test_io_disp_integer_matrix (brief) : ', brief=.true.) + call disp(i(:,:), unit=unit, header='Test_io_disp_integer_matrix (brief) : ', brief=.true.) + + !! Checks + rewind(unit) + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), 'Test_io_disp_integer_scalar (brief) :', 'Header') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), '1', 'Value') + + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), 'Test_io_disp_integer_vector (brief) :', 'Header') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), '[vector size: 6]', 'Vector Info') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), & + '1 1 1 ... 1', 'Brief Vector') + + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), 'Test_io_disp_integer_vector :', 'Header') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), '[vector size: 6]', 'Vector Info') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), & + '1 1 1 1 1 1', 'Brief Vector') + + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), 'Test_io_disp_integer_matrix :', 'Header') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), '[matrix size: 2×2]', 'Matrix Info') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), & + '1 1', 'Matrix Vector 1') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), & + '1 1', 'Matrix Vector 2') + + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), 'Test_io_disp_integer_matrix (brief) :', 'Header') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), '[matrix size: 6×6]', 'Matrix Info') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), & + '1 1 1 ... 1', 'Matrix Vector 1') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), & + '1 1 1 ... 1', 'Matrix Vector 2') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), & + '1 1 1 ... 1', 'Matrix Vector 3') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), & + ': : : : :', 'Matrix Vector ..') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), & + '1 1 1 ... 1', 'Matrix Vector Size(Matrix, 1)') + close(unit) + + end subroutine test_io_disp_integer + + subroutine test_io_disp_logical + + logical :: l(6,6) = .true. + ! unit = open(filenanme, 'w+t') + open(newunit=unit, file=filenanme) + call disp(l(1,1), header='Test_io_disp_logical_scalar (brief) : ', brief=.true.) + call disp(l(1,1), unit=unit, header='Test_io_disp_logical_scalar (brief) : ', brief=.true.) + + call disp(l(1,:), header='Test_io_disp_logical_vector (brief) : ', brief=.true.) + call disp(l(1,:), unit=unit, header='Test_io_disp_logical_vector (brief) : ', brief=.true.) + + call disp(l(:,1), header='Test_io_disp_logical_vector : ', brief=.false.) + call disp(l(:,1), unit=unit, header='Test_io_disp_logical_vector : ', brief=.false.) + + call disp(l(1:2,1:2), header='Test_io_disp_logical_matrix : ', brief=.false.) + call disp(l(1:2,1:2), unit=unit, header='Test_io_disp_logical_matrix : ', brief=.false.) + + call disp(l(:,:), header='Test_io_disp_logical_matrix (brief) : ', brief=.true.) + call disp(l(:,:), unit=unit, header='Test_io_disp_logical_matrix (brief) : ', brief=.true.) + + !! Checks + rewind(unit) + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), 'Test_io_disp_logical_scalar (brief) :', 'Header') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), 'T', 'Value') + + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), 'Test_io_disp_logical_vector (brief) :', 'Header') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), '[vector size: 6]', 'Vector Info') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), & + 'T T T ... T', 'Brief Vector') + + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), 'Test_io_disp_logical_vector :', 'Header') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), '[vector size: 6]', 'Vector Info') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), & + 'T T T T T T', 'Brief Vector') + + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), 'Test_io_disp_logical_matrix :', 'Header') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), '[matrix size: 2×2]', 'Matrix Info') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), & + 'T T', 'Matrix Vector 1') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), & + 'T T', 'Matrix Vector 2') + + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), 'Test_io_disp_logical_matrix (brief) :', 'Header') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), '[matrix size: 6×6]', 'Matrix Info') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), & + 'T T T ... T', 'Matrix Vector 1') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), & + 'T T T ... T', 'Matrix Vector 2') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), & + 'T T T ... T', 'Matrix Vector 3') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), & + ': : : : :', 'Matrix Vector ..') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), & + 'T T T ... T', 'Matrix Vector Size(Matrix, 1)') + close(unit) + + end subroutine test_io_disp_logical + + subroutine test_io_disp_string + + character(*), parameter :: str = 'It is a string.' + ! unit = open(filenanme, 'w+t') + open(newunit=unit, file=filenanme) + call disp(str, header='Test_io_disp_string_scalar (brief) : ', brief=.true.) + call disp(str, unit=unit, header='Test_io_disp_string_scalar (brief) : ', brief=.true.) + + !! Checks + rewind(unit) + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), 'Test_io_disp_string_scalar (brief) :', 'Header') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), 'It is a string.', 'Value') + close(unit) + + end subroutine test_io_disp_string + +end module test_io_disp + +program tester + use test_io_disp + call test_io_disp_complex + call test_io_disp_real + call test_io_disp_integer + call test_io_disp_logical + call test_io_disp_string +end program tester From fce189c9644f245b319f4c970baf1d94c05d31f9 Mon Sep 17 00:00:00 2001 From: zoziha13 <1325686572@qq.com> Date: Mon, 12 Jul 2021 08:50:48 +0800 Subject: [PATCH 09/14] Add support for `string_type` type initially. --- src/stdlib_io.fypp | 11 +++++++-- src/stdlib_io_disp.fypp | 25 +++++++++++++++++-- src/tests/io/test_io_disp.f90 | 46 ++++++++++++++++++++++++----------- 3 files changed, 64 insertions(+), 18 deletions(-) diff --git a/src/stdlib_io.fypp b/src/stdlib_io.fypp index a3a38bb59..f89a904f2 100644 --- a/src/stdlib_io.fypp +++ b/src/stdlib_io.fypp @@ -37,12 +37,19 @@ module stdlib_io end subroutine disp_${rank}$_${type[0]}$${kind}$ #:endfor #:endfor - module subroutine disp_str(value, unit, header, brief) + module subroutine disp_character(value, unit, header, brief) character(len=*), intent(in), optional :: value integer, intent(in), optional :: unit character(len=*), intent(in), optional :: header logical, intent(in), optional :: brief - end subroutine disp_str + end subroutine disp_character + module subroutine disp_string_type(value, unit, header, brief) + use stdlib_string_type, only: string_type + type(string_type), intent(in) :: value + integer, intent(in), optional :: unit + character(len=*), intent(in), optional :: header + logical, intent(in), optional :: brief + end subroutine disp_string_type end interface disp interface loadtxt diff --git a/src/stdlib_io_disp.fypp b/src/stdlib_io_disp.fypp index e6ccf3871..ca90a3529 100644 --- a/src/stdlib_io_disp.fypp +++ b/src/stdlib_io_disp.fypp @@ -5,6 +5,7 @@ submodule (stdlib_io) stdlib_io_disp use stdlib_ascii, only: to_string use stdlib_strings, only: format_to_string + use stdlib_string_type, only: string_type, char use, intrinsic :: iso_fortran_env, only: output_unit implicit none character(len=*), parameter :: fmt_r = '(*(g12.4, 1x))' @@ -33,8 +34,10 @@ contains if(present(header)) write(unit_, *) header write(unit_, *) '[vector size: '//to_string(m)//']' if(brief_ .and. m > 5) then + !! Brief Print. write(unit_, fmt_r) value(1:3), '...', value(m) else + !! Full Print. write(unit_, fmt_r) value(:) end if end procedure disp_1_${type[0]}$${kind}$ @@ -49,9 +52,11 @@ contains brief_ = merge(brief, .false., present(brief)) m = size(value, 1) n = size(value, 2) + if(present(header)) write(unit_, *) header write(unit_, *) '[matrix size: '//to_string(m)//'×'//to_string(n)//']' if(brief_ .and. (m > 5 .or. n > 5)) then + !! Brief Print. if(m > 5 .and. n > 5) then do i = 1, 3 write(unit_, fmt_r) value(i,1:3), '...', value(i,n) @@ -71,6 +76,7 @@ contains end do end if else + !! Full Print. do i = 1, m write(unit_, fmt_r) value(i,:) end do @@ -95,12 +101,15 @@ contains unit_ = merge(unit, output_unit, present(unit)) brief_ = merge(brief, .false., present(brief)) m = size(value, 1) + if(present(header)) write(unit_, *) header write(unit_, *) '[vector size: '//to_string(m)//']' if(brief_ .and. m > 5) then + !! Brief Print. write(unit_, fmt_c) (format_to_string(value(i), format_), i=1, 3), & '...', format_to_string(value(m), format_) else + !! Full Print. write(unit_, fmt_c) (format_to_string(value(i), format_), i=1, m) end if end procedure disp_1_${type[0]}$${kind}$ @@ -115,9 +124,11 @@ contains brief_ = merge(brief, .false., present(brief)) m = size(value, 1) n = size(value, 2) + if(present(header)) write(unit_, *) header write(unit_, *) '[matrix size: '//to_string(m)//'×'//to_string(n)//']' if(brief_ .and. (m > 5 .or. n > 5)) then + !! Brief Print. if(m > 5 .and. n > 5) then do i = 1, 3 write(unit_, fmt_c) (format_to_string(value(i,j), format_), j=1, 3), & @@ -140,6 +151,7 @@ contains end do end if else + !! Full Print. do i = 1, m write(unit_, fmt_c) (format_to_string(value(i,j), format_), j=1, n) end do @@ -147,7 +159,7 @@ contains end procedure disp_2_${type[0]}$${kind}$ #:endfor - module procedure disp_str + module procedure disp_character !! Display a `character` scalar. character(:), allocatable :: value_ integer :: unit_ @@ -155,6 +167,15 @@ contains unit_ = merge(unit, output_unit, present(unit)) if(present(header)) write(unit_, *) header write(unit_, *) value_ - end procedure disp_str + end procedure disp_character + + module procedure disp_string_type + !! Display a `string_type` scalar + integer :: unit_ + unit_ = merge(unit, output_unit, present(unit)) + if(present(header)) write(unit_, *) header + write(unit_, *) char(value) + !!\TODO: Need to improve ? + end procedure disp_string_type end submodule stdlib_io_disp \ No newline at end of file diff --git a/src/tests/io/test_io_disp.f90 b/src/tests/io/test_io_disp.f90 index c65be16dd..93a79f3c4 100644 --- a/src/tests/io/test_io_disp.f90 +++ b/src/tests/io/test_io_disp.f90 @@ -6,7 +6,6 @@ module test_io_disp implicit none integer :: unit - character(*), parameter :: filenanme = "./test_io_disp.tmp" character(len=512) :: string contains @@ -37,7 +36,7 @@ end subroutine check_formatter subroutine test_io_disp_complex complex :: c(6,6) = (1.0, 1.0) ! unit = open(filenanme, 'w+t') - open(newunit=unit, file=filenanme) + open(newunit=unit, status='scratch') call disp(c(1,1), header='Test_io_disp_complex_scalar (brief) : ', brief=.true.) call disp(c(1,1), unit=unit, header='Test_io_disp_complex_scalar (brief) : ', brief=.true.) @@ -121,7 +120,7 @@ subroutine test_io_disp_real real :: r(6,6) = 1.0 ! unit = open(filenanme, 'w+t') - open(newunit=unit, file=filenanme) + open(newunit=unit, status='scratch') call disp(r(1,1), header='Test_io_disp_real_scalar (brief) : ', brief=.true.) call disp(r(1,1), unit=unit, header='Test_io_disp_real_scalar (brief) : ', brief=.true.) @@ -198,7 +197,7 @@ subroutine test_io_disp_integer integer :: i(6,6) = 1 ! unit = open(filenanme, 'w+t') - open(newunit=unit, file=filenanme) + open(newunit=unit, status='scratch') call disp(i(1,1), header='Test_io_disp_integer_scalar (brief) : ', brief=.true.) call disp(i(1,1), unit=unit, header='Test_io_disp_integer_scalar (brief) : ', brief=.true.) @@ -275,7 +274,7 @@ subroutine test_io_disp_logical logical :: l(6,6) = .true. ! unit = open(filenanme, 'w+t') - open(newunit=unit, file=filenanme) + open(newunit=unit, status='scratch') call disp(l(1,1), header='Test_io_disp_logical_scalar (brief) : ', brief=.true.) call disp(l(1,1), unit=unit, header='Test_io_disp_logical_scalar (brief) : ', brief=.true.) @@ -348,23 +347,41 @@ subroutine test_io_disp_logical end subroutine test_io_disp_logical - subroutine test_io_disp_string + subroutine test_io_disp_character - character(*), parameter :: str = 'It is a string.' + character(*), parameter :: str = 'It is a character.' ! unit = open(filenanme, 'w+t') - open(newunit=unit, file=filenanme) - call disp(str, header='Test_io_disp_string_scalar (brief) : ', brief=.true.) - call disp(str, unit=unit, header='Test_io_disp_string_scalar (brief) : ', brief=.true.) + open(newunit=unit, status='scratch') + call disp(str, header='Test_io_disp_character_scalar (brief) : ', brief=.true.) + call disp(str, unit=unit, header='Test_io_disp_character_scalar (brief) : ', brief=.true.) !! Checks rewind(unit) read(unit, '(A200)') string - call check_formatter(trim(adjustl(string)), 'Test_io_disp_string_scalar (brief) :', 'Header') + call check_formatter(trim(adjustl(string)), 'Test_io_disp_character_scalar (brief) :', 'Header') read(unit, '(A200)') string - call check_formatter(trim(adjustl(string)), 'It is a string.', 'Value') + call check_formatter(trim(adjustl(string)), 'It is a character.', 'Value') close(unit) - end subroutine test_io_disp_string + end subroutine test_io_disp_character + + subroutine test_io_disp_string_type + + character(*), parameter :: str = 'It is a string_type.' + ! unit = open(filenanme, 'w+t') + open(newunit=unit, status='scratch') + call disp(str, header='Test_io_disp_string_type_scalar (brief) : ', brief=.true.) + call disp(str, unit=unit, header='Test_io_disp_string_type_scalar (brief) : ', brief=.true.) + + !! Checks + rewind(unit) + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), 'Test_io_disp_string_type_scalar (brief) :', 'Header') + read(unit, '(A200)') string + call check_formatter(trim(adjustl(string)), 'It is a string_type.', 'Value') + close(unit) + + end subroutine test_io_disp_string_type end module test_io_disp @@ -374,5 +391,6 @@ program tester call test_io_disp_real call test_io_disp_integer call test_io_disp_logical - call test_io_disp_string + call test_io_disp_character + call test_io_disp_string_type end program tester From c6906f0375ef88d732eb3050b44b325c87f17acd Mon Sep 17 00:00:00 2001 From: zoziha13 <1325686572@qq.com> Date: Mon, 12 Jul 2021 08:58:28 +0800 Subject: [PATCH 10/14] Update src/Makefile.manual --- src/Makefile.manual | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Makefile.manual b/src/Makefile.manual index 52836fa7a..917d3211c 100644 --- a/src/Makefile.manual +++ b/src/Makefile.manual @@ -149,4 +149,5 @@ stdlib_string_format_to_string.o: stdlib_strings.o stdlib_linalg_outer_product.o: stdlib_linalg.o stdlib_io_disp.o: stdlib_error.o \ stdlib_strings.o \ + stdlib_string_type.o \ stdlib_io.o From 314f9b910d5039c946d72d3803b553b7cbcddcd9 Mon Sep 17 00:00:00 2001 From: zoziha13 <1325686572@qq.com> Date: Mon, 12 Jul 2021 09:04:17 +0800 Subject: [PATCH 11/14] Update src/Makefile.manual --- src/Makefile.manual | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Makefile.manual b/src/Makefile.manual index 917d3211c..30e4d25d1 100644 --- a/src/Makefile.manual +++ b/src/Makefile.manual @@ -78,7 +78,8 @@ stdlib_io.o: \ stdlib_error.o \ stdlib_optval.o \ stdlib_kinds.o \ - stdlib_ascii.o + stdlib_ascii.o \ + stdlib_string_type.o stdlib_linalg.o: \ stdlib_kinds.o stdlib_linalg_diag.o: \ @@ -150,4 +151,5 @@ stdlib_linalg_outer_product.o: stdlib_linalg.o stdlib_io_disp.o: stdlib_error.o \ stdlib_strings.o \ stdlib_string_type.o \ - stdlib_io.o + stdlib_io.o \ + stdlib_ascii.o From dfc20062a9bfaf3abc10b118c351272d1341510d Mon Sep 17 00:00:00 2001 From: zoziha13 <1325686572@qq.com> Date: Mon, 12 Jul 2021 09:15:52 +0800 Subject: [PATCH 12/14] Fix a bug in test_io_disp.f90 for `string_type` test. --- src/tests/io/test_io_disp.f90 | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/tests/io/test_io_disp.f90 b/src/tests/io/test_io_disp.f90 index 93a79f3c4..b9f077c39 100644 --- a/src/tests/io/test_io_disp.f90 +++ b/src/tests/io/test_io_disp.f90 @@ -1,6 +1,7 @@ module test_io_disp use stdlib_strings, only: starts_with + use stdlib_string_type, only: string_type, assignment(=) use stdlib_error, only: check use stdlib_io, only: disp, open implicit none @@ -367,8 +368,9 @@ end subroutine test_io_disp_character subroutine test_io_disp_string_type - character(*), parameter :: str = 'It is a string_type.' + type(string_type) :: str ! unit = open(filenanme, 'w+t') + str = 'It is a string_type.' open(newunit=unit, status='scratch') call disp(str, header='Test_io_disp_string_type_scalar (brief) : ', brief=.true.) call disp(str, unit=unit, header='Test_io_disp_string_type_scalar (brief) : ', brief=.true.) From 3c24a750016b333e46606e0622d753254ecc43d9 Mon Sep 17 00:00:00 2001 From: zoziha13 <1325686572@qq.com> Date: Wed, 14 Jul 2021 09:03:21 +0800 Subject: [PATCH 13/14] Update stdlib_io%disp.md --- doc/specs/stdlib_io.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/doc/specs/stdlib_io.md b/doc/specs/stdlib_io.md index 8ecf49c3e..3297f4be2 100644 --- a/doc/specs/stdlib_io.md +++ b/doc/specs/stdlib_io.md @@ -139,7 +139,8 @@ end program demo_savetxt Experimental ### Description -Display any type of scalar, vector or matrix. +Display any type (`logical, integer, real, complex, character, string_type`) of scalar, +and display some data type (`logical, integer, real, complex`) of vector or matrix. Make good use of similar to the following usage, can help you understand the data information in the `array`. ```fortran @@ -159,7 +160,7 @@ For null: ### Arguments -`value`: Shall be any type of scalar, vector or matrix. +`value`: Shall be any type of scalar, and some data type (`logical, integer, real, complex`) of vector or matrix. This is an `intent(in)` argument. `unit`: Shall be an `integer` scalar link to an IO stream. From 92fe853c9624d0bf0006aa0a0ffb0c2950adf9b6 Mon Sep 17 00:00:00 2001 From: zoziha13 <1325686572@qq.com> Date: Mon, 23 Aug 2021 09:46:34 +0800 Subject: [PATCH 14/14] Meger `to_string` to `disp`, update `disp` routines. --- doc/specs/stdlib_io.md | 56 +++++---- src/Makefile.manual | 9 +- src/stdlib_io.fypp | 28 ++--- src/stdlib_io_disp.fypp | 220 ++++++++++++++++++---------------- src/tests/io/test_io_disp.f90 | 30 +++-- 5 files changed, 186 insertions(+), 157 deletions(-) diff --git a/doc/specs/stdlib_io.md b/doc/specs/stdlib_io.md index b5dc4e356..89fd32e12 100644 --- a/doc/specs/stdlib_io.md +++ b/doc/specs/stdlib_io.md @@ -138,56 +138,65 @@ end program demo_savetxt Experimental +### Class + +Impure subroutine. + ### Description -Display any type (`logical, integer, real, complex, character, string_type`) of scalar, -and display some data type (`logical, integer, real, complex`) of vector or matrix. + +Display a `logical/integer/real/complex/character/string_type` scalar or `logical/integer/real/complex` and rank-1/rank-2 array to the screen or another output `unit`. + +#### More details Make good use of similar to the following usage, can help you understand the data information in the `array`. ```fortran -call disp( A(i, j, 2, :, 1:10) [, unit, header, brief] ) !! `i, j, ...` can be determined by `do` loop. +call disp( A(i, j, 2, :, 1:10) [, header, unit, brief] ) !! `i, j, ...` can be determined by `do` loop. ``` Generally, except for `complex` type, any other type of scalar or single element of the `array` will be printed out with a width of 12 characters and a space separator. For `complex` type, scalar or single element of the `array` will be printed out with a width of 25 characters and a space separator. In order to prevent users from accidentally passing large-length arrays to `disp`, causing unnecessary io blockage: -1. If the `brief` argument is not specified, `disp` will print **the brief array content with a length of 10*50 by default**. -2. Specify `brief=.true.`, `disp` will print **the brief array content with a length of 5*5**; -3. Specify `brief=.false.`, `disp` will print **all the contents of the array** (please print all the contents of the array as appropriate according to the actual situation to avoid unnecessary IO blockage and affect the reading experience) +1. If the `brief` argument is not specified, `disp` will print **the brief array content with a length of `10*50` by default**. +2. Specify `brief=.true.`, `disp` will print **the brief array content with a length of `5*5`**; +3. Specify `brief=.false.`, `disp` will print **`all` the contents of the array** (please print all the contents of the array as appropriate according to the actual situation to avoid unnecessary IO blockage and affect the reading experience) ### Syntax -General API: -`call [[stdlib_io(module):disp(interface)]](value [, unit, header, brief])` - -For null: -`call [[stdlib_io(module):disp(interface)]]()` +`call [[stdlib_io(module):disp(interface)]]([value, header, unit, brief])` ### Arguments -`value`: Shall be any type of scalar, and some data type (`logical, integer, real, complex`) of vector or matrix. - This is an `intent(in)` argument. +`value`: Shall be a `logical/integer/real/complex/string_type` scalar or `logical/integer/real/complex` and rank-1/rank-2 array. +This argument is `intent(in)` and `optional`. -`unit`: Shall be an `integer` scalar link to an IO stream. - This is an `intent(in)` and `optional` argument. +`header`: Shall be a `character(len=*)` scalar. +This argument is `intent(in)` and `optional`. +Usually used to comment data information. -`header`: Shall be a scalar of type `character` with any length (usually used to comment data information). - This is an `intent(in)` and `optional` argument. +`unit`: Shall be an `integer` scalar linked to an IO stream. +This argument is `intent(in)` and `optional`. +Indicates the output `unit`. -`brief`: Shall be an `logical` scalar, controlling an abridged version of the `value` object is printed. - This is an `intent(in)` and `optional` argument. +`brief`: Shall be a `logical` scalar. +This argument is `intent(in)` and `optional`. +Controls an abridged version of the `value` object is printed. ### Output -The result is to print `header` and `value` on the screen (or another output unit) in this order. -If `value` is a `array` type, the dimension length information of the `array` will also be outputted. +The result is to print `header` and `value` on the screen (or another output `unit`) in this order. +If `value` is a rank-1/rank-2 `array` type, the dimension length information of the `array` will also be outputted. + +If `disp` is not passed any arguments, a blank line is printed. + +If the `value` is present and of `real/complex` type, the data will retain four significant decimal places, like `(g0.4)`. ### Example ```fortran program test_io_disp - use :: stdlib_io, only: disp + use stdlib_io, only: disp implicit none real(8) :: r(2, 3) complex :: c(2, 3), c_3d(2, 100, 20) @@ -200,6 +209,7 @@ program test_io_disp c(2, 2) = (-1.e10,-1.e10) c_3d(1,3,1) = (1000, 0.001) c_3d(1,3,2) = (1.e4, 100.) + call disp('string', header='disp(string):') call disp('It is a note.') call disp() @@ -215,7 +225,7 @@ program test_io_disp end program test_io_disp ``` -**Result:** +**Results:** ```fortran disp(string): string diff --git a/src/Makefile.manual b/src/Makefile.manual index 3a3302c0d..3b55cc06f 100644 --- a/src/Makefile.manual +++ b/src/Makefile.manual @@ -79,13 +79,11 @@ stdlib_bitsets_large.o: stdlib_bitsets.o stdlib_error.o: stdlib_optval.o stdlib_specialfunctions.o: stdlib_kinds.o stdlib_specialfunctions_legendre.o: stdlib_kinds.o stdlib_specialfunctions.o -stdlib_io.o: - stdlib_ascii.o \ +stdlib_io.o: \ stdlib_error.o \ stdlib_optval.o \ stdlib_kinds.o \ stdlib_ascii.o \ - stdlib_error.o \ stdlib_string_type.o stdlib_linalg.o: \ stdlib_kinds.o @@ -168,8 +166,7 @@ stdlib_math_logspace.o: \ stdlib_math_arange.o: \ stdlib_math.o stdlib_linalg_outer_product.o: stdlib_linalg.o -stdlib_io_disp.o: stdlib_error.o \ +stdlib_io_disp.o: \ stdlib_strings.o \ stdlib_string_type.o \ - stdlib_io.o \ - stdlib_ascii.o + stdlib_io.o diff --git a/src/stdlib_io.fypp b/src/stdlib_io.fypp index f89a904f2..efc675f0a 100644 --- a/src/stdlib_io.fypp +++ b/src/stdlib_io.fypp @@ -11,6 +11,7 @@ module stdlib_io use stdlib_error, only: error_stop use stdlib_optval, only: optval use stdlib_ascii, only: is_blank + use stdlib_string_type, only: string_type implicit none private ! Public API @@ -19,35 +20,34 @@ module stdlib_io ! Private API that is exposed so that we can test it in tests public :: parse_mode + !> version: experimental + !> + !> Display a scalar, vector or matrix. + !> ([Specification](../page/specs/stdlib_io.html#disp-display-your-data-to-the-screen-or-another-output-unit)) interface disp - !! version: experimental - !! - !! Display any type of scalar, vector and matrix. - !! ([Specification](../page/specs/stdlib_io.html#disp-display-your-data-to-the-screen-or-another-output-unit)) #:set DISP_KINDS_TYPES = REAL_KINDS_TYPES + INT_KINDS_TYPES & & + CMPLX_KINDS_TYPES + LOG_KINDS_TYPES #:set DISP_RANKS = range(0, 3) - #:for kind, type in DISP_KINDS_TYPES + #:for k1, t1 in DISP_KINDS_TYPES #:for rank in DISP_RANKS - module subroutine disp_${rank}$_${type[0]}$${kind}$(value, unit, header, brief) - ${type}$, intent(in) :: value${ranksuffix(rank)}$ - integer, intent(in), optional :: unit + module subroutine disp_${rank}$_${t1[0]}$${k1}$(value, header, unit, brief) + ${t1}$, intent(in) :: value${ranksuffix(rank)}$ character(len=*), intent(in), optional :: header + integer, intent(in), optional :: unit logical, intent(in), optional :: brief - end subroutine disp_${rank}$_${type[0]}$${kind}$ + end subroutine disp_${rank}$_${t1[0]}$${k1}$ #:endfor #:endfor - module subroutine disp_character(value, unit, header, brief) + module subroutine disp_character(value, header, unit, brief) character(len=*), intent(in), optional :: value - integer, intent(in), optional :: unit character(len=*), intent(in), optional :: header + integer, intent(in), optional :: unit logical, intent(in), optional :: brief end subroutine disp_character - module subroutine disp_string_type(value, unit, header, brief) - use stdlib_string_type, only: string_type + module subroutine disp_string_type(value, header, unit, brief) type(string_type), intent(in) :: value - integer, intent(in), optional :: unit character(len=*), intent(in), optional :: header + integer, intent(in), optional :: unit logical, intent(in), optional :: brief end subroutine disp_string_type end interface disp diff --git a/src/stdlib_io_disp.fypp b/src/stdlib_io_disp.fypp index 6ca02f4e8..623d42808 100644 --- a/src/stdlib_io_disp.fypp +++ b/src/stdlib_io_disp.fypp @@ -3,15 +3,14 @@ submodule (stdlib_io) stdlib_io_disp - use stdlib_ascii, only: to_string - use stdlib_strings, only: format_to_string - use stdlib_string_type, only: string_type, char + use stdlib_strings, only: to_string + use stdlib_string_type, only: char use, intrinsic :: iso_fortran_env, only: output_unit implicit none character(len=*), parameter :: fmt_r = '(*(g12.4, 1x))' character(len=*), parameter :: fmt_c = '(*(g25.0, 1x))' - character(len=*), parameter :: format_ = '(g0.4)' + character(len=*), parameter :: format_ = 'g0.4' integer, parameter :: brief_col = 5 integer, parameter :: brief_row = 5 integer, parameter :: default_col = 10 @@ -19,178 +18,197 @@ submodule (stdlib_io) stdlib_io_disp contains - #:for kind, type in RIL_KINDS_TYPES - module procedure disp_0_${type[0]}$${kind}$ - !! Display a/an ${type}$ scalar. + #:for k1, t1 in RIL_KINDS_TYPES + !> Display a/an ${t1}$ scalar. + module procedure disp_0_${t1[0]}$${k1}$ integer :: unit_ - unit_ = merge(unit, output_unit, present(unit)) - if(present(header)) write(unit_, *) header + + unit_ = optval(unit, output_unit) + + if (present(header)) write(unit_, *) header write(unit_, fmt_r) value - end procedure disp_0_${type[0]}$${kind}$ - module procedure disp_1_${type[0]}$${kind}$ - !! Display a/an ${type}$ vector. + end procedure disp_0_${t1[0]}$${k1}$ + + !> Display a/an ${t1}$ vector. + module procedure disp_1_${t1[0]}$${k1}$ integer :: unit_ logical :: brief_ integer :: m, col - unit_ = merge(unit, output_unit, present(unit)) - brief_ = merge(brief, .true., present(brief)) - col = merge(brief_col, default_col, present(brief) .and. brief_) - m = size(value, 1) - - if(present(header)) write(unit_, *) header - write(unit_, *) '[vector size: '//to_string(m)//']' - if(brief_ .and. m > col) then - !! Brief Print. + + unit_ = optval(unit, output_unit) + brief_ = optval(brief, .true.) + col = merge(brief_col, default_col, present(brief) .and. brief_) + m = size(value, 1) + + if (present(header)) write(unit_, *) header + write(unit_, *) '[vector size: ' // to_string(m) // ']' + if (brief_ .and. m > col) then + !> Brief Print. write(unit_, fmt_r) value(1:col-2), '...', value(m) else - !! Full Print. + !> Full Print. write(unit_, fmt_r) value(:) end if - end procedure disp_1_${type[0]}$${kind}$ - module procedure disp_2_${type[0]}$${kind}$ - !! Display a/an ${type}$ matrix. + end procedure disp_1_${t1[0]}$${k1}$ + + !> Display a/an ${t1}$ matrix. + module procedure disp_2_${t1[0]}$${k1}$ integer :: unit_ logical :: brief_ integer :: i, m, n integer :: col, row - character(1) :: colon(default_col) - - unit_ = merge(unit, output_unit, present(unit)) - brief_ = merge(brief, .true., present(brief)) - col = merge(brief_col, default_col, present(brief) .and. brief_) - row = merge(brief_row, default_row, present(brief) .and. brief_) - m = size(value, 1) - n = size(value, 2) - - if(present(header)) write(unit_, *) header - write(unit_, *) '[matrix size: '//to_string(m)//'×'//to_string(n)//']' - if(brief_ .and. (m > col .or. n > row)) then - !! Brief Print. + character(len=1) :: colon(default_col) + + unit_ = optval(unit, output_unit) + brief_ = optval(brief, .true.) + col = merge(brief_col, default_col, present(brief) .and. brief_) + row = merge(brief_row, default_row, present(brief) .and. brief_) + m = size(value, 1) + n = size(value, 2) + + if (present(header)) write(unit_, *) header + write(unit_, *) '[matrix size: ' // to_string(m) // '×' // to_string(n) // ']' + if (brief_ .and. (m > col .or. n > row)) then + !> Brief Print. colon = ':' - if(m > col .and. n > row) then + if (m > col .and. n > row) then do i = 1, row-2 write(unit_, fmt_r) value(i,1:col-2), '...', value(i,n) end do write(unit_, fmt_r) colon(1:col) write(unit_, fmt_r) value(m,1:col-2), '...', value(m,n) - elseif(m > col .and. n <= row) then + elseif (m > col .and. n <= row) then do i = 1, 3 write(unit_, fmt_r) value(i,:) end do write(unit_, fmt_r) colon(1:n) write(unit_, fmt_r) value(m,:) - elseif(m <= col .and. n > row) then + elseif (m <= col .and. n > row) then do i = 1, m write(unit_, fmt_r) value(i,1:col-2), '...', value(i,n) end do end if else - !! Full Print. + !> Full Print. do i = 1, m write(unit_, fmt_r) value(i,:) end do end if - end procedure disp_2_${type[0]}$${kind}$ + + end procedure disp_2_${t1[0]}$${k1}$ #:endfor - #:for kind, type in CMPLX_KINDS_TYPES - module procedure disp_0_${type[0]}$${kind}$ - !! Display a ${type}$ scalar. + #:for k1, t1 in CMPLX_KINDS_TYPES + !> Display a ${t1}$ scalar. + module procedure disp_0_${t1[0]}$${k1}$ integer :: unit_ - unit_ = merge(unit, output_unit, present(unit)) - if(present(header)) write(unit_, *) header - write(unit_, fmt_c) format_to_string(value, format_) - end procedure disp_0_${type[0]}$${kind}$ - module procedure disp_1_${type[0]}$${kind}$ - !! Display a ${type}$ vector. + unit_ = optval(unit, output_unit) + + if (present(header)) write(unit_, *) header + write(unit_, fmt_c) to_string(value, format_) + + end procedure disp_0_${t1[0]}$${k1}$ + + !> Display a ${t1}$ vector. + module procedure disp_1_${t1[0]}$${k1}$ integer :: unit_ logical :: brief_ integer :: i, m, col - unit_ = merge(unit, output_unit, present(unit)) - brief_ = merge(brief, .true., present(brief)) - col = merge(brief_col, default_col, present(brief) .and. brief_) - m = size(value, 1) - - if(present(header)) write(unit_, *) header - write(unit_, *) '[vector size: '//to_string(m)//']' - if(brief_ .and. m > col) then - !! Brief Print. - write(unit_, fmt_c) (format_to_string(value(i), format_), i=1, col-2), & - '...', format_to_string(value(m), format_) + + unit_ = optval(unit, output_unit) + brief_ = optval(brief, .true.) + col = merge(brief_col, default_col, present(brief) .and. brief_) + m = size(value, 1) + + if (present(header)) write(unit_, *) header + write(unit_, *) '[vector size: ' // to_string(m) // ']' + if (brief_ .and. m > col) then + !> Brief Print. + write(unit_, fmt_c) (to_string(value(i), format_), i=1, col-2), & + '...', to_string(value(m), format_) else - !! Full Print. - write(unit_, fmt_c) (format_to_string(value(i), format_), i=1, m) + !> Full Print. + write(unit_, fmt_c) (to_string(value(i), format_), i=1, m) end if - end procedure disp_1_${type[0]}$${kind}$ - module procedure disp_2_${type[0]}$${kind}$ - !! Display a ${type}$ matrix. + end procedure disp_1_${t1[0]}$${k1}$ + + !> Display a ${t1}$ matrix. + module procedure disp_2_${t1[0]}$${k1}$ integer :: unit_ logical :: brief_ integer :: i, j, m, n integer :: col, row - character(1) :: colon(default_col) - unit_ = merge(unit, output_unit, present(unit)) - brief_ = merge(brief, .true., present(brief)) - col = merge(brief_col, default_col, present(brief) .and. brief_) - row = merge(brief_row, default_row, present(brief) .and. brief_) - m = size(value, 1) - n = size(value, 2) - - if(present(header)) write(unit_, *) header - write(unit_, *) '[matrix size: '//to_string(m)//'×'//to_string(n)//']' - if(brief_ .and. (m > col .or. n > row)) then - !! Brief Print. + character(len=1) :: colon(default_col) + + unit_ = optval(unit, output_unit) + brief_ = optval(brief, .true.) + col = merge(brief_col, default_col, present(brief) .and. brief_) + row = merge(brief_row, default_row, present(brief) .and. brief_) + m = size(value, 1) + n = size(value, 2) + + if (present(header)) write(unit_, *) header + write(unit_, *) '[matrix size: ' // to_string(m) // '×' // to_string(n) // ']' + if (brief_ .and. (m > col .or. n > row)) then + !> Brief Print. colon = ':' - if(m > col .and. n > row) then + if (m > col .and. n > row) then do i = 1, col-2 - write(unit_, fmt_c) (format_to_string(value(i,j), format_), j=1, col-2), & - '...', format_to_string(value(i,n), format_) + write(unit_, fmt_c) (to_string(value(i,j), format_), j=1, col-2), & + '...', to_string(value(i,n), format_) end do write(unit_, fmt_c) colon(1:col) - write(unit_, fmt_c) (format_to_string(value(m,j), format_), j=1, col-2), & - '...', format_to_string(value(m,n), format_) - elseif(m > col .and. n <= row) then + write(unit_, fmt_c) (to_string(value(m,j), format_), j=1, col-2), & + '...', to_string(value(m,n), format_) + elseif (m > col .and. n <= row) then do i = 1, col-2 - write(unit_, fmt_c) (format_to_string(value(i,j), format_), j=1, n) + write(unit_, fmt_c) (to_string(value(i,j), format_), j=1, n) end do write(unit_, fmt_c) colon(1:n) - write(unit_, fmt_c) (format_to_string(value(m,j), format_), j=1, n) - elseif(m <= col .and. n > row) then + write(unit_, fmt_c) (to_string(value(m,j), format_), j=1, n) + elseif (m <= col .and. n > row) then do i = 1, m - write(unit_, fmt_c) (format_to_string(value(m,j), format_), j=1, col-2), & - '...', format_to_string(value(m,n), format_) + write(unit_, fmt_c) (to_string(value(m,j), format_), j=1, col-2), & + '...', to_string(value(m,n), format_) end do end if else - !! Full Print. + !> Full Print. do i = 1, m - write(unit_, fmt_c) (format_to_string(value(i,j), format_), j=1, n) + write(unit_, fmt_c) (to_string(value(i,j), format_), j=1, n) end do end if - end procedure disp_2_${type[0]}$${kind}$ + + end procedure disp_2_${t1[0]}$${k1}$ #:endfor + !> Display a `character` scalar. module procedure disp_character - !! Display a `character` scalar. - character(:), allocatable :: value_ + character(len=:), allocatable :: value_ integer :: unit_ + value_ = optval(value, '') - unit_ = merge(unit, output_unit, present(unit)) - if(present(header)) write(unit_, *) header + unit_ = optval(unit, output_unit) + + if (present(header)) write(unit_, *) header write(unit_, *) value_ + end procedure disp_character + !> Display a `string_type` scalar module procedure disp_string_type - !! Display a `string_type` scalar integer :: unit_ - unit_ = merge(unit, output_unit, present(unit)) - if(present(header)) write(unit_, *) header + + unit_ = optval(unit, output_unit) + + if (present(header)) write(unit_, *) header write(unit_, *) char(value) !!\TODO: Need to improve ? + end procedure disp_string_type end submodule stdlib_io_disp \ No newline at end of file diff --git a/src/tests/io/test_io_disp.f90 b/src/tests/io/test_io_disp.f90 index a61e0fba9..ed4781ab5 100644 --- a/src/tests/io/test_io_disp.f90 +++ b/src/tests/io/test_io_disp.f90 @@ -4,10 +4,11 @@ module test_io_disp use stdlib_string_type, only: string_type, assignment(=) use stdlib_error, only: check use stdlib_io, only: disp + use stdlib_optval, only: optval implicit none integer :: unit - character(len=512) :: string + character(len=200) :: string contains @@ -17,7 +18,7 @@ subroutine check_formatter(actual, expected, description, partial) logical :: stat character(len=:), allocatable :: msg - if (merge(partial, .false., present(partial))) then + if (optval(partial, .false.)) then stat = starts_with(actual, expected) else stat = actual == expected @@ -36,7 +37,7 @@ end subroutine check_formatter subroutine test_io_disp_complex complex :: c(6,6) = (1.0, 1.0) - ! unit = open(filenanme, 'w+t') + open(newunit=unit, status='scratch') call disp(c(1,1), header='Test_io_disp_complex_scalar (brief) : ', brief=.true.) call disp(c(1,1), unit=unit, header='Test_io_disp_complex_scalar (brief) : ', brief=.true.) @@ -120,7 +121,7 @@ end subroutine test_io_disp_complex subroutine test_io_disp_real real :: r(6,6) = 1.0 - ! unit = open(filenanme, 'w+t') + open(newunit=unit, status='scratch') call disp(r(1,1), header='Test_io_disp_real_scalar (brief) : ', brief=.true.) call disp(r(1,1), unit=unit, header='Test_io_disp_real_scalar (brief) : ', brief=.true.) @@ -197,7 +198,7 @@ end subroutine test_io_disp_real subroutine test_io_disp_integer integer :: i(6,6) = 1 - ! unit = open(filenanme, 'w+t') + open(newunit=unit, status='scratch') call disp(i(1,1), header='Test_io_disp_integer_scalar (brief) : ', brief=.true.) call disp(i(1,1), unit=unit, header='Test_io_disp_integer_scalar (brief) : ', brief=.true.) @@ -369,7 +370,7 @@ end subroutine test_io_disp_character subroutine test_io_disp_string_type type(string_type) :: str - ! unit = open(filenanme, 'w+t') + str = 'It is a string_type.' open(newunit=unit, status='scratch') call disp(str, header='Test_io_disp_string_type_scalar (brief) : ', brief=.true.) @@ -388,8 +389,10 @@ end subroutine test_io_disp_string_type end module test_io_disp program tester + use test_io_disp - real(4) :: x(51,51) + ! real(4) :: x(51,51) + call test_io_disp_complex call test_io_disp_real call test_io_disp_integer @@ -397,10 +400,11 @@ program tester call test_io_disp_character call test_io_disp_string_type - !! Content that is difficult to test: The length of the dimension is too large - !! to print and check by a test program. - x = 0.0 - call disp(x, header="Test_io_disp_real_matrix (51×51)(default) : [10×50]") - call disp(x, header="Test_io_disp_real_matrix (51×51)(brief=.true.) : [5×5]", brief=.true.) - call disp(x, header="Test_io_disp_real_matrix (51×51)(brief=.false.) : [all]", brief=.false.) + !> Content that is difficult to test: The length of the dimension is too large + !> to print and check by a test program. + ! x = 0.0 + ! call disp(x, header="Test_io_disp_real_matrix (51×51)(default) : [10×50]") + ! call disp(x, header="Test_io_disp_real_matrix (51×51)(brief=.true.) : [5×5]", brief=.true.) + ! call disp(x, header="Test_io_disp_real_matrix (51×51)(brief=.false.) : [all]", brief=.false.) + end program tester