Skip to content

Commit dfce17f

Browse files
committed
patch CRAN notes about Catch called functions
1 parent 0f1bb7e commit dfce17f

5 files changed

Lines changed: 90 additions & 6 deletions

File tree

catch2-update/02-install.sh

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,5 +27,3 @@ fi
2727
echo "Catch2 v2.13.10 installed to inst/include/testthat/vendor/catch.hpp"
2828
echo ""
2929
echo "inst/include/testthat/testthat.h now uses catch.hpp instead of catch.h"
30-
echo "test compilation with: R CMD INSTALL --preclean ."
31-
echo "run tests with: Rscript -e 'testthat::test_local()'"

catch2-update/03-patch-r-compat.sh

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
#!/bin/sh
2+
3+
# Patch Catch2 to be compatible with R CMD check requirements
4+
# Fixes warnings about abort, sprintf, and srand
5+
6+
cd ~/Documents/testthat/
7+
8+
CATCH_FILE="inst/include/testthat/vendor/catch.hpp"
9+
10+
if [ ! -f "$CATCH_FILE" ]; then
11+
echo "ERROR: $CATCH_FILE not found. Run 02-install.sh first."
12+
exit 1
13+
fi
14+
15+
echo "Creating backup of catch.hpp..."
16+
cp "$CATCH_FILE" "$CATCH_FILE.backup"
17+
18+
echo "Patching Catch2 for R compatibility..."
19+
20+
# First, add R header includes after the initial header guard
21+
echo " - Adding R headers..."
22+
sed -i '/#define TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED/a\
23+
#ifdef __cplusplus\
24+
extern "C" {\
25+
#endif\
26+
#include <R_ext/Error.h>\
27+
#ifdef __cplusplus\
28+
}\
29+
#endif' "$CATCH_FILE"
30+
31+
# Fix 1: Replace std::abort() with Rf_error()
32+
# This uses R's native error mechanism instead of terminating the process
33+
echo " - Replacing abort() with Rf_error()..."
34+
sed -i 's/std::abort();/Rf_error("Fatal error in test framework");/g' "$CATCH_FILE"
35+
36+
# Fix 2: Replace std::sprintf() with std::snprintf() for safety
37+
# snprintf is safer and avoids R CMD check warnings
38+
echo " - Replacing sprintf() with snprintf()..."
39+
sed -i 's/std::sprintf(buffer, "%.3f", duration);/std::snprintf(buffer, sizeof(buffer), "%.3f", duration);/g' "$CATCH_FILE"
40+
41+
# Fix 3: Comment out std::srand() - R uses its own RNG
42+
# R packages should use R's RNG via GetRNGstate()/PutRNGstate()
43+
echo " - Commenting out srand()..."
44+
sed -i 's/std::srand(config.rngSeed());/\/\/ std::srand(config.rngSeed()); \/\/ Disabled for R compatibility/g' "$CATCH_FILE"
45+
46+
echo ""
47+
echo "Verifying patches..."
48+
echo ""
49+
50+
echo "1. Checking abort() was replaced:"
51+
if grep -q "std::abort()" "$CATCH_FILE"; then
52+
echo " WARNING: std::abort() still found!"
53+
else
54+
echo " No abort() calls found"
55+
fi
56+
57+
echo ""
58+
echo "2. Checking sprintf() was replaced:"
59+
if grep -q "std::sprintf(buffer" "$CATCH_FILE"; then
60+
echo " WARNING: std::sprintf() still found!"
61+
else
62+
echo " No sprintf() calls found"
63+
fi
64+
65+
echo ""
66+
echo "3. Checking srand() was commented out:"
67+
if grep -q "^[[:space:]]*std::srand(config.rngSeed());" "$CATCH_FILE"; then
68+
echo " WARNING: Uncommented std::srand() still found!"
69+
else
70+
echo " srand() has been disabled"
71+
fi
72+
73+
echo ""
74+
echo "Patch complete!"
75+
echo ""
76+
echo "To test: R CMD INSTALL --preclean . && R CMD check --as-cran ."
77+
echo ""
78+
echo "If you need to restore the original, run:"
79+
echo " mv $CATCH_FILE.backup $CATCH_FILE"
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ if [ $? -eq 0 ]; then
7474
echo " Package build successful"
7575
echo ""
7676
echo "======================================"
77-
echo "All tests passed!"
77+
echo "All tests passed!"
7878
echo "======================================"
7979
else
8080
echo " Package build failed"

inst/include/testthat/vendor/catch.h

Whitespace-only changes.

inst/include/testthat/vendor/catch.hpp

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,13 @@
1010
*/
1111
#ifndef TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED
1212
#define TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED
13+
#ifdef __cplusplus
14+
extern "C" {
15+
#endif
16+
#include <R_ext/Error.h>
17+
#ifdef __cplusplus
18+
}
19+
#endif
1320
// start catch.hpp
1421

1522

@@ -9021,7 +9028,7 @@ namespace detail {
90219028
assert( m_type != ResultBase::LogicError );
90229029
assert( m_type != ResultBase::RuntimeError );
90239030
if( m_type != ResultBase::Ok )
9024-
std::abort();
9031+
Rf_error("Fatal error in test framework");
90259032
}
90269033

90279034
std::string m_errorMessage; // Only populated if resultType is an error
@@ -13151,7 +13158,7 @@ namespace Catch {
1315113158

1315213159
void seedRng(IConfig const& config) {
1315313160
if (config.rngSeed() != 0) {
13154-
std::srand(config.rngSeed());
13161+
// std::srand(config.rngSeed()); // Disabled for R compatibility
1315513162
rng().seed(config.rngSeed());
1315613163
}
1315713164
}
@@ -15786,7 +15793,7 @@ namespace Catch {
1578615793
#ifdef _MSC_VER
1578715794
sprintf_s(buffer, "%.3f", duration);
1578815795
#else
15789-
std::sprintf(buffer, "%.3f", duration);
15796+
std::snprintf(buffer, sizeof(buffer), "%.3f", duration);
1579015797
#endif
1579115798
return std::string(buffer);
1579215799
}

0 commit comments

Comments
 (0)