-
Notifications
You must be signed in to change notification settings - Fork 190
error_stop to stderr and optional returncode #53
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
submodule (stdlib_experimental_error) estop | ||
|
||
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 <character>" 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 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
submodule (stdlib_experimental_error) estop | ||
|
||
contains | ||
|
||
module procedure error_stop | ||
! Aborts the program with nonzero exit code | ||
! | ||
! The "stop <character>" 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 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,41 +1,34 @@ | ||
module stdlib_experimental_error | ||
use, intrinsic :: iso_fortran_env, only: stderr=>error_unit | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This does not need to be imported here, does it? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I tested this patch and it works: diff --git a/src/f08estop.f90 b/src/f08estop.f90
index d501978..17ea448 100644
--- a/src/f08estop.f90
+++ b/src/f08estop.f90
@@ -1,4 +1,5 @@
submodule (stdlib_experimental_error) estop
+use, intrinsic :: iso_fortran_env, only: stderr=>error_unit
contains
diff --git a/src/f18estop.f90 b/src/f18estop.f90
index ea83de7..6be7900 100644
--- a/src/f18estop.f90
+++ b/src/f18estop.f90
@@ -1,4 +1,5 @@
submodule (stdlib_experimental_error) estop
+use, intrinsic :: iso_fortran_env, only: stderr=>error_unit
contains
diff --git a/src/stdlib_experimental_error.f90 b/src/stdlib_experimental_error.f90
index 3d932d6..135722b 100644
--- a/src/stdlib_experimental_error.f90
+++ b/src/stdlib_experimental_error.f90
@@ -1,5 +1,4 @@
module stdlib_experimental_error
-use, intrinsic :: iso_fortran_env, only: stderr=>error_unit
implicit none
private There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. it's more of a deduplication issue. The scope of submodule is such that these submodules pickup There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ok, that's fine. I don't use submodules myself, so I don't know what the best way to use them is. I thought the idea is that the main module is sort of like a C++ There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. One could use module/submodule that way, but they are generally not used that way as the scoping rules are different than C++. I use submodules for almost every program for reasons including:
So submodule can be used like one step up from "just in time" compilation, I call it "build on run" since based on options say called from Python API, I can rebuild huge Fortran program based on options user specifies from Python (or directly in CMake) in seconds. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. submodule can also be used for build-time polymorphism, avoiding need for preprocessing and again shrinking memory use and build time by only building the required |
||
implicit none | ||
private | ||
|
||
interface ! f{08,18}estop.f90 | ||
module subroutine error_stop(msg, code) | ||
character(*), intent(in) :: msg | ||
integer, intent(in), optional :: code | ||
end subroutine error_stop | ||
end interface | ||
|
||
public :: assert, error_stop | ||
|
||
contains | ||
|
||
subroutine assert(condition) | ||
subroutine assert(condition, code) | ||
! If condition == .false., it aborts the program. | ||
! | ||
! Arguments | ||
! --------- | ||
! | ||
logical, intent(in) :: condition | ||
integer, intent(in), optional :: code | ||
! | ||
! Example | ||
! ------- | ||
! | ||
! call assert(a == 5) | ||
|
||
if (.not. condition) call error_stop("Assert failed.") | ||
end subroutine | ||
|
||
subroutine error_stop(msg) | ||
! Aborts the program with nonzero exit code | ||
! | ||
! The statement "stop msg" will return 0 exit code when compiled using | ||
! gfortran. error_stop() uses the statement "stop 1" which returns an exit code | ||
! 1 and a print statement to print the message. | ||
! | ||
! Example | ||
! ------- | ||
! | ||
! call error_stop("Invalid argument") | ||
|
||
character(len=*) :: msg ! Message to print on stdout | ||
print *, msg | ||
stop 1 | ||
if (.not. condition) call error_stop("Assert failed.", code) | ||
end subroutine | ||
|
||
end module |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,12 @@ | ||
add_subdirectory(ascii) | ||
add_subdirectory(loadtxt) | ||
|
||
add_executable(test_skip test_skip.f90) | ||
target_link_libraries(test_skip fortran_stdlib) | ||
add_test(NAME AlwaysSkip COMMAND $<TARGET_FILE:test_skip>) | ||
set_tests_properties(AlwaysSkip PROPERTIES SKIP_RETURN_CODE 77) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What is the purpose of this test? What is it testing? When I run
Which seems confusing. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's testing that I can pass arbitrary return codes. There's a de facto standard that 77 means to skip a test, so 77 was a convenient alternative to the oft-used returncode 1 that was tested in AlwaysFail |
||
|
||
add_executable(test_fail test_fail.f90) | ||
target_link_libraries(test_fail fortran_stdlib) | ||
add_test(NAME AlwaysFail COMMAND $<TARGET_FILE:test_fail>) | ||
set_tests_properties(AlwaysFail PROPERTIES WILL_FAIL true) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
program AlwaysFail | ||
|
||
use stdlib_experimental_error, only : assert | ||
implicit none | ||
|
||
call assert(.false.) | ||
|
||
end program |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
program AlwaysSkip | ||
|
||
use stdlib_experimental_error, only : assert | ||
implicit none | ||
|
||
call assert(.false., 77) | ||
|
||
end program |
Uh oh!
There was an error while loading. Please reload this page.