Skip to content

Commit e876d7e

Browse files
committed
Revert the bad revert "merged with ChangeLog and inst/NEWS.Rd""
1 parent 4c7aee3 commit e876d7e

File tree

7 files changed

+99
-4
lines changed

7 files changed

+99
-4
lines changed

.gitignore

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,6 @@
11
inst/lib
2-
2+
*.Rproj
3+
.Rproj.user
4+
src/*.o
5+
src/*.so
6+
src/*.dll

ChangeLog

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,16 @@
22

33
* inst/include/Rcpp/exceptions.h: Move stop() into Rcpp namespace
44

5+
2014-01-03 JJ Allaire <jj@rstudio.org>
6+
7+
* .gitignore: Added src/<object-files>, *.Rproj, and .Rproj.user
8+
* inst/include/Rcpp/Interrupt.h: New checkUserInterrupt function
9+
that provides a C++ friendly implementation of R_CheckUserInterrupt
10+
* inst/include/RcppCommon.h: Include Rcpp/Interrupts.h
11+
* inst/include/macros/macros.h: Check for interrupts in END_RCPP
12+
* src/attributes.cpp: Handle interrupted-error in attribute
13+
function envelope.
14+
515
2013-12-31 Dirk Eddelbuettel <edd@debian.org>
616

717
* vignettes/Rcpp.bib: Updated CRAN package references

inst/NEWS.Rd

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@
2121
and \code{NaN}.)
2222
\item Applied two bug fixes to Vector \code{sort()} and \code{RObject}
2323
definition spotted and corrected by Kevin Ushey
24+
definition spotted and correct by Kevin Ushey
25+
\item New \code{checkUserInterrupt()} function that provides a C++ friendly
26+
implementation of \code{R_CheckUserInterrupt}.
2427
}
2528
\item Changes in Rcpp documentation:
2629
\itemize{

inst/include/Rcpp/Interrupt.h

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
// -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; indent-tabs-mode: nil; -*-
2+
//
3+
// Interrupt.h: Rcpp R/C++ interface class library -- check for interrupts
4+
//
5+
// Copyright (C) 2009 - 2013 Dirk Eddelbuettel and Romain Francois
6+
//
7+
// This file is part of Rcpp.
8+
//
9+
// Rcpp is free software: you can redistribute it and/or modify it
10+
// under the terms of the GNU General Public License as published by
11+
// the Free Software Foundation, either version 2 of the License, or
12+
// (at your option) any later version.
13+
//
14+
// Rcpp is distributed in the hope that it will be useful, but
15+
// WITHOUT ANY WARRANTY; without even the implied warranty of
16+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17+
// GNU General Public License for more details.
18+
//
19+
// You should have received a copy of the GNU General Public License
20+
// along with Rcpp. If not, see <http://www.gnu.org/licenses/>.
21+
22+
#ifndef Rcpp_Interrupt_h
23+
#define Rcpp_Interrupt_h
24+
25+
#include <Rinterface.h>
26+
27+
namespace Rcpp {
28+
29+
// Internal functions used in the implementation of checkUserInterrupt
30+
namespace internal {
31+
32+
// Sentinel class for communicating interrupts to the top-level END_RCPP macro
33+
class InterruptedException {};
34+
35+
// Sentinel object of class "interrupted-error" which is used for
36+
// communicating interrupts accross module boundaries without an
37+
// exception (which would crash on windows). This is identical to
38+
// the existing "try-error" sentinel object used for communicating
39+
// errors accross module boundaries.
40+
inline SEXP interruptedError() {
41+
Rcpp::Shield<SEXP> interruptedError( Rf_mkString("") );
42+
Rf_setAttrib( interruptedError, R_ClassSymbol, Rf_mkString("interrupted-error") ) ;
43+
return interruptedError;
44+
}
45+
46+
} // namespace internal
47+
48+
// Helper function to check for interrupts. This is invoked within
49+
// R_ToplevelExec so it doesn't longjmp
50+
namespace {
51+
52+
inline void checkInterruptFn(void *dummy) {
53+
R_CheckUserInterrupt();
54+
}
55+
56+
} // anonymous namespace
57+
58+
// Check for interrupts and throw the sentinel exception if one is pending
59+
inline void checkUserInterrupt() {
60+
if (R_ToplevelExec(checkInterruptFn, NULL) == FALSE)
61+
throw internal::InterruptedException();
62+
}
63+
64+
} // namespace Rcpp
65+
66+
#endif

inst/include/Rcpp/macros/macros.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,15 +31,15 @@
3131
#endif
3232

3333
#ifndef VOID_END_RCPP
34-
#define VOID_END_RCPP } catch( std::exception& __ex__ ){ forward_exception_to_r( __ex__ ) ; } catch(...){ ::Rf_error( "c++ exception (unknown reason)" ) ; }
34+
#define VOID_END_RCPP } catch( Rcpp::internal::InterruptedException& __ex__ ) { Rf_jump_to_toplevel(); } catch( std::exception& __ex__ ){ forward_exception_to_r( __ex__ ) ; } catch(...){ ::Rf_error( "c++ exception (unknown reason)" ) ; }
3535
#endif
3636

3737
#ifndef END_RCPP
3838
#define END_RCPP VOID_END_RCPP return R_NilValue;
3939
#endif
4040

4141
#ifndef END_RCPP_RETURN_ERROR
42-
#define END_RCPP_RETURN_ERROR } catch( std::exception& __ex__ ){ return exception_to_try_error( __ex__ ) ; } catch(...){ return string_to_try_error( "c++ exception (unknown reason)" ) ; } return R_NilValue;
42+
#define END_RCPP_RETURN_ERROR } catch( Rcpp::internal::InterruptedException& __ex__ ) { return Rcpp::internal::interruptedError(); } catch( std::exception& __ex__ ){ return exception_to_try_error( __ex__ ) ; } catch(...){ return string_to_try_error( "c++ exception (unknown reason)" ) ; } return R_NilValue;
4343
#endif
4444

4545
#define Rcpp_error(MESSAGE) throw Rcpp::exception( MESSAGE, __FILE__, __LINE__ )

inst/include/RcppCommon.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,8 @@ namespace Rcpp{
139139

140140
#include <Rcpp/exceptions.h>
141141

142+
#include <Rcpp/Interrupt.h>
143+
142144
namespace Rcpp{
143145
template <typename T> class object ;
144146
class String ;

src/attributes.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1700,6 +1700,10 @@ namespace attributes {
17001700
ostr() << ");" << std::endl;
17011701
ostr() << " }" << std::endl;
17021702

1703+
ostr() << " if (__result.inherits(\"interrupted-error\"))"
1704+
<< std::endl
1705+
<< " throw Rcpp::internal::InterruptedException();"
1706+
<< std::endl;
17031707
ostr() << " if (__result.inherits(\"try-error\"))"
17041708
<< std::endl
17051709
<< " throw Rcpp::exception(as<std::string>("
@@ -2222,7 +2226,13 @@ namespace attributes {
22222226
}
22232227
ostr << "));" << std::endl;
22242228
ostr << " }" << std::endl;
2225-
ostr << " Rboolean __isError = Rf_inherits(__result, \"try-error\");"
2229+
ostr << " Rboolean __isInterrupt = Rf_inherits(__result, \"interrupted-error\");"
2230+
<< std::endl
2231+
<< " if (__isInterrupt) {" << std::endl
2232+
<< " UNPROTECT(1);" << std::endl
2233+
<< " Rcpp::internal::jumpToTop();" << std::endl
2234+
<< " }" << std::endl
2235+
<< " Rboolean __isError = Rf_inherits(__result, \"try-error\");"
22262236
<< std::endl
22272237
<< " if (__isError) {" << std::endl
22282238
<< " SEXP __msgSEXP = Rf_asChar(__result);" << std::endl

0 commit comments

Comments
 (0)