From e46d9ad40f4e705dd74806b4cc3628a2cd66b3c8 Mon Sep 17 00:00:00 2001 From: Michael Hirsch Date: Tue, 20 Jul 2021 23:49:33 -0400 Subject: [PATCH 1/4] error_stop: remove incorrect/obsolete code I originally authored this routine, which is updated for supported compilers. The logic selecting it in CMake was no longer relevant. --- CMakeLists.txt | 2 +- src/CMakeLists.txt | 8 +------- src/Makefile.manual | 4 +--- src/f08estop.f90 | 41 ---------------------------------------- src/f18estop.f90 | 29 ---------------------------- src/stdlib_error.f90 | 45 +++++++++++++++++++++++++++++++++----------- 6 files changed, 37 insertions(+), 92 deletions(-) delete mode 100644 src/f08estop.f90 delete mode 100644 src/f18estop.f90 diff --git a/CMakeLists.txt b/CMakeLists.txt index 72cf3a979..9446cfeb1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -46,7 +46,7 @@ include(CheckFortranSourceCompiles) include(CheckFortranSourceRuns) check_fortran_source_runs("i=0; error stop i; end" f18errorstop) check_fortran_source_compiles("real, allocatable :: array(:, :, :, :, :, :, :, :, :, :); end" f03rank SRC_EXT f90) -check_fortran_source_runs("use, intrinsic :: iso_fortran_env, only : real128; real(real128) :: x; x = x+1; end" f03real128) +# check_fortran_source_runs("use, intrinsic :: iso_fortran_env, only : real128; real(real128) :: x; x = x+1; end" f03real128) if(NOT DEFINED CMAKE_MAXIMUM_RANK) set(CMAKE_MAXIMUM_RANK 4 CACHE STRING "Maximum array rank for generated procedures") diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index c4f6d76e7..bc343a36c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -14,7 +14,7 @@ set(fppFiles stdlib_sorting.fypp stdlib_sorting_ord_sort.fypp stdlib_sorting_sort.fypp - stdlib_sorting_sort_index.fypp + stdlib_sorting_sort_index.fypp stdlib_stats.fypp stdlib_stats_corr.fypp stdlib_stats_cov.fypp @@ -69,12 +69,6 @@ target_include_directories(${PROJECT_NAME} PUBLIC $ ) -if(f18errorstop) - target_sources(${PROJECT_NAME} PRIVATE f18estop.f90) -else() - target_sources(${PROJECT_NAME} PRIVATE f08estop.f90) -endif() - add_subdirectory(tests) install(TARGETS ${PROJECT_NAME} diff --git a/src/Makefile.manual b/src/Makefile.manual index a12f81255..fed6a949d 100644 --- a/src/Makefile.manual +++ b/src/Makefile.manual @@ -31,8 +31,7 @@ SRCFYPP =\ stdlib_stats_distribution_PRNG.fypp \ stdlib_string_type.fypp -SRC = f18estop.f90 \ - stdlib_error.f90 \ +SRC = stdlib_error.f90 \ stdlib_specialfunctions.f90 \ stdlib_specialfunctions_legendre.f90 \ stdlib_io.f90 \ @@ -67,7 +66,6 @@ $(SRCGEN): %.f90: %.fypp common.fypp fypp $(FYPPFLAGS) $< $@ # Fortran module dependencies -f18estop.o: stdlib_error.o stdlib_ascii.o: stdlib_kinds.o stdlib_bitsets.o: stdlib_kinds.o stdlib_bitsets_64.o: stdlib_bitsets.o diff --git a/src/f08estop.f90 b/src/f08estop.f90 deleted file mode 100644 index 81c77f4a9..000000000 --- a/src/f08estop.f90 +++ /dev/null @@ -1,41 +0,0 @@ -submodule (stdlib_error) estop - -implicit none - -contains - -module procedure error_stop -! Aborts the program with nonzero exit code -! this is a fallback for Fortran 2008 error stop (e.g. Intel 19.1/2020 compiler) -! -! The "stop " statement generally has return code 0. -! To allow non-zero return code termination with character message, -! error_stop() uses the statement "error stop", which by default -! has exit code 1 and prints the message to stderr. -! An optional integer return code "code" may be specified. -! -! Example -! ------- -! -! call error_stop("Invalid argument") - -write(stderr,*) msg - -if(present(code)) then - select case (code) - case (1) - error stop 1 - case (2) - error stop 2 - case (77) - error stop 77 - case default - write(stderr,*) 'ERROR: code ',code,' was specified.' - error stop - end select -else - error stop -endif -end procedure - -end submodule diff --git a/src/f18estop.f90 b/src/f18estop.f90 deleted file mode 100644 index 59fd0c97f..000000000 --- a/src/f18estop.f90 +++ /dev/null @@ -1,29 +0,0 @@ -submodule (stdlib_error) estop - -implicit none - -contains - -module procedure error_stop -! Aborts the program with nonzero exit code -! -! The "stop " statement generally has return code 0. -! To allow non-zero return code termination with character message, -! error_stop() uses the statement "error stop", which by default -! has exit code 1 and prints the message to stderr. -! An optional integer return code "code" may be specified. -! -! Example -! ------- -! -! call error_stop("Invalid argument") - -if(present(code)) then - write(stderr,*) msg - error stop code -else - error stop msg -endif -end procedure - -end submodule estop diff --git a/src/stdlib_error.f90 b/src/stdlib_error.f90 index a44f29917..974df11fb 100644 --- a/src/stdlib_error.f90 +++ b/src/stdlib_error.f90 @@ -6,21 +6,44 @@ module stdlib_error implicit none private -interface ! f{08,18}estop.f90 - module subroutine error_stop(msg, code) - !! version: experimental - !! - !! Provides a call to `error stop` and allows the user to specify a code and message - !! ([Specification](..//page/specs/stdlib_error.html#description_1)) - character(*), intent(in) :: msg - integer, intent(in), optional :: code - end subroutine error_stop -end interface - public :: check, error_stop contains + +subroutine error_stop(msg, code) + !! version: experimental + !! + !! Provides a call to `error stop` and allows the user to specify a code and message + !! ([Specification](..//page/specs/stdlib_error.html#description_1)) + !! + !! Aborts the program with nonzero exit code. + !! The "stop " statement generally has return code 0. + !! To allow non-zero return code termination with character message, + !! error_stop() uses the statement "error stop", which by default + !! has exit code 1 and prints the message to stderr. + !! An optional integer return code "code" may be specified. + !! + !!##### Examples + !! + !!```fortran + !! call error_stop("Invalid argument") + !!``` + !!```fortran + !! call error_stop("Invalid argument", 123) + !!``` + + character(*), intent(in) :: msg + integer, intent(in), optional :: code + + if(.not.present(code)) error stop msg + + write(stderr, '(a)') msg + error stop code + +end subroutine error_stop + + subroutine check(condition, msg, code, warn) !! version: experimental !! From 106cf962d5d6566018ad6081c0d3b59fa43516c9 Mon Sep 17 00:00:00 2001 From: Michael Hirsch Date: Wed, 21 Jul 2021 00:26:46 -0400 Subject: [PATCH 2/4] error_stop: improve test by using a driver program --- src/tests/CMakeLists.txt | 17 +++++++---- ...est_always_skip.f90 => test_always_77.f90} | 2 +- src/tests/test_error_driver.f90 | 28 +++++++++++++++++++ 3 files changed, 41 insertions(+), 6 deletions(-) rename src/tests/{test_always_skip.f90 => test_always_77.f90} (77%) create mode 100644 src/tests/test_error_driver.f90 diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt index 7d2286fef..4a5a8d65d 100644 --- a/src/tests/CMakeLists.txt +++ b/src/tests/CMakeLists.txt @@ -1,6 +1,6 @@ macro(ADDTEST name) add_executable(test_${name} test_${name}.f90) - target_link_libraries(test_${name} ${PROJECT_NAME}) + target_link_libraries(test_${name} PRIVATE ${PROJECT_NAME}) add_test(NAME ${name} COMMAND $ ${CMAKE_CURRENT_BINARY_DIR} WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) @@ -19,7 +19,14 @@ add_subdirectory(system) add_subdirectory(quadrature) add_subdirectory(math) -ADDTEST(always_skip) -set_tests_properties(always_skip PROPERTIES SKIP_RETURN_CODE 77) -ADDTEST(always_fail) -set_tests_properties(always_fail PROPERTIES WILL_FAIL true) +add_executable(test_error_handling test_error_driver.f90) + +add_executable(test_always_77 test_always_77.f90) +target_link_libraries(test_always_77 PRIVATE ${PROJECT_NAME}) +add_test(NAME test_error_77 + COMMAND $ $ 77) + +add_executable(test_always_1 test_always_fail.f90) +target_link_libraries(test_always_1 PRIVATE ${PROJECT_NAME}) +add_test(NAME test_error_1 + COMMAND $ $ 1) diff --git a/src/tests/test_always_skip.f90 b/src/tests/test_always_77.f90 similarity index 77% rename from src/tests/test_always_skip.f90 rename to src/tests/test_always_77.f90 index 2d10c3daa..301f20195 100644 --- a/src/tests/test_always_skip.f90 +++ b/src/tests/test_always_77.f90 @@ -1,4 +1,4 @@ -program test_always_skip +program test_always_77 use stdlib_error, only: check implicit none diff --git a/src/tests/test_error_driver.f90 b/src/tests/test_error_driver.f90 new file mode 100644 index 000000000..91065f973 --- /dev/null +++ b/src/tests/test_error_driver.f90 @@ -0,0 +1,28 @@ +program test_driver +!! tests return codes from programs. +!! useful for checking "error stop" return codes. +!! +!! Arguments: +!! prog: program to run and catch return code + +implicit none + +integer :: ierr, ok_code, cmderr +character(1024) :: prog +character(3) :: ok, actual + +call get_command_argument(1, prog, status=ierr) +if(ierr/=0) error stop "please specify a program to catch return codes from" + +call get_command_argument(2, ok, status=ierr) +if(ierr/=0) error stop "please specify the expected return code" + +read(ok, '(i3)') ok_code + +call execute_command_line(trim(prog), exitstat=ierr, cmdstat=cmderr) +if(cmderr/=0) error stop "test_driver had problem running always-fail program" + +write(actual, '(i3)') ierr +if(ierr /= ok_code) error stop "expected return code "//ok//", got "//actual//" instead" + +end program From d73135edd223f396a03ea06b5fa493ec48a36240 Mon Sep 17 00:00:00 2001 From: Michael Hirsch Date: Wed, 21 Jul 2021 00:41:13 -0400 Subject: [PATCH 3/4] cmake: enable error stop validation for tests --- CMakeLists.txt | 6 +++++- src/tests/CMakeLists.txt | 12 ++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9446cfeb1..d90024b5b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -44,7 +44,11 @@ endif() # --- compiler feature checks include(CheckFortranSourceCompiles) include(CheckFortranSourceRuns) -check_fortran_source_runs("i=0; error stop i; end" f18errorstop) +check_fortran_source_runs("program test_error_stop +integer, parameter :: i=0 +error stop i +end program" +f18errorstop) check_fortran_source_compiles("real, allocatable :: array(:, :, :, :, :, :, :, :, :, :); end" f03rank SRC_EXT f90) # check_fortran_source_runs("use, intrinsic :: iso_fortran_env, only : real128; real(real128) :: x; x = x+1; end" f03real128) diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt index 4a5a8d65d..692fbfe6f 100644 --- a/src/tests/CMakeLists.txt +++ b/src/tests/CMakeLists.txt @@ -19,6 +19,13 @@ add_subdirectory(system) add_subdirectory(quadrature) add_subdirectory(math) +# some compilers have broken error stop return code handling +if(f18errorstop) + set(DISABLE_ESTOP_TESTS false) +else() + set(DISABLE_ESTOP_TESTS true) +endif() + add_executable(test_error_handling test_error_driver.f90) add_executable(test_always_77 test_always_77.f90) @@ -30,3 +37,8 @@ add_executable(test_always_1 test_always_fail.f90) target_link_libraries(test_always_1 PRIVATE ${PROJECT_NAME}) add_test(NAME test_error_1 COMMAND $ $ 1) + +set_tests_properties(test_error_77 test_error_1 PROPERTIES + TIMEOUT 5 + DISABLED ${DISABLE_ESTOP_TESTS} +) From 165276f98e606be7e7bbafc57cd9be64099a4df3 Mon Sep 17 00:00:00 2001 From: Michael Hirsch Date: Wed, 21 Jul 2021 22:26:17 -0400 Subject: [PATCH 4/4] ci:macos: update to oneAPI 2021.3 --- .github/workflows/CI.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 4781ddd22..f5ac2ff1c 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -101,7 +101,7 @@ jobs: fc: [ifort] env: MACOS_HPCKIT_URL: >- - https://registrationcenter-download.intel.com/akdlm/irc_nas/17398/m_HPCKit_p_2021.1.0.2681_offline.dmg + https://registrationcenter-download.intel.com/akdlm/irc_nas/17890/m_HPCKit_p_2021.3.0.3226_offline.dmg MACOS_FORTRAN_COMPONENTS: >- intel.oneapi.mac.ifort-compiler FC: ${{ matrix.fc }}