Skip to content

Commit 00870d9

Browse files
committed
Redefine kas_bug_assert() and tsk_trace_error() that use stderr #5
1 parent b2a29f1 commit 00870d9

9 files changed

Lines changed: 106 additions & 12 deletions

File tree

tskitr/R/RcppExports.R

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,14 @@ test_tsk_bug_assert_cpp <- function() {
99
invisible(.Call(`_tskitr_test_tsk_bug_assert_cpp`))
1010
}
1111

12+
test_tsk_trace_error_c <- function() {
13+
invisible(.Call(`_tskitr_test_tsk_trace_error_c`))
14+
}
15+
16+
test_tsk_trace_error_cpp <- function() {
17+
invisible(.Call(`_tskitr_test_tsk_trace_error_cpp`))
18+
}
19+
1220
#' Report the version of installed kastore C API
1321
#'
1422
#' @details The version is stored in the installed header \code{kastore.h}.

tskitr/inst/include/tskit/core.h

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
#ifndef TSKITR_TSKIT_CORE_H
2+
#define TSKITR_TSKIT_CORE_H
3+
14
// Shim header to use tskit C API in Rcpp code in an R session or an R package
25
#include <tskit/tskit/core.h>
36

@@ -27,3 +30,31 @@
2730
} \
2831
} while (0)
2932
#endif
33+
34+
// Redefinition of tsk_trace_error to avoid writing to stderr from tskit C API
35+
// (following R extensions manual recommendations).
36+
// While tsk_trace_error is called only in C API (atm) we provide both C and C++
37+
// macros for completeness.
38+
#undef tsk_trace_error
39+
#ifdef TSK_TRACE_ERRORS
40+
#ifdef __cplusplus
41+
static inline int _tskitr_trace_error_cpp(int err, int line, const char *file) {
42+
Rcpp::warning("tskit-trace-error: %d='%s' at line %d in %s\n", err,
43+
tsk_strerror(err), line, file);
44+
return err;
45+
}
46+
#define tsk_trace_error(err) \
47+
(_tskitr_trace_error_cpp((err), __LINE__, __FILE__))
48+
#else
49+
static inline int _tskitr_trace_error_c(int err, int line, const char *file) {
50+
Rf_warning("tskit-trace-error: %d='%s' at line %d in %s\n", err,
51+
tsk_strerror(err), line, file);
52+
return err;
53+
}
54+
#define tsk_trace_error(err) (_tskitr_trace_error_c((err), __LINE__, __FILE__))
55+
#endif
56+
#else
57+
#define tsk_trace_error(err) (err)
58+
#endif
59+
60+
#endif
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,18 @@
11
// Shim header to use tskit C API in Rcpp code in an R session or an R package
22
#include <tskit/tskit/kastore.h>
3+
4+
// Redefinition of kas_bug_assert to avoid aborting R sessions with tskit C API
5+
// (following R extensions manual recommendations).
6+
// Since kastore is only used by tskit C API we provide only C macros.
7+
#ifndef __cplusplus
8+
// Override kas_bug_assert to use R-style error handling in C code.
9+
#undef kas_bug_assert
10+
#include <R_ext/Error.h>
11+
#define kas_bug_assert(condition) \
12+
do { \
13+
if (!(condition)) { \
14+
Rf_error("Bug detected in %s at line %d. %s", __FILE__, __LINE__, \
15+
KAS_BUG_ASSERT_MESSAGE); \
16+
} \
17+
} while (0)
18+
#endif

tskitr/src/Makevars.in

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,11 @@ TSKIT_OBJECTS = $(TSKIT_SOURCES:.c=.o)
1717
# TSKITR_CPP_SOURCES = $(wildcard *.cpp) # wildcard is a GNU extension and not desired on CRAN
1818
TSKITR_CPP_SOURCES = \
1919
tskitr.cpp \
20-
test_tsk_bug_assert.cpp \
20+
test_tsk_abort_stderr.cpp \
2121
RcppExports.cpp
2222
# $(info TSKITR_CPP_SOURCES = $(TSKITR_CPP_SOURCES)) # for debugging, info is also a GNU extension
2323
TSKITR_C_SOURCES = \
24-
test_tsk_bug_assert_c.c
24+
test_tsk_abort_stderr_c.c
2525
# $(info TSKITR_C_SOURCES = $(TSKITR_C_SOURCES)) # for debugging, info is also a GNU extension
2626
TSKITR_OBJECTS = $(TSKITR_CPP_SOURCES:.cpp=.o) $(TSKITR_C_SOURCES:.c=.o)
2727
# $(info TSKITR_OBJECTS = $(TSKITR_OBJECTS)) # for debugging, info is also a GNU extension
@@ -41,12 +41,14 @@ PKG_CPPFLAGS = \
4141

4242
# Compiler flags
4343
PKG_CFLAGS = -DNDEBUG # to remove calls to assert() as per the R extensions manual
44+
# PKG_CFLAGS = -DNDEBUG -DTSK_TRACE_ERRORS
4445
# TODO: Should we port any flags from extern/tskit/c/meson.build to R build system? #6
4546
# https://github.com/HighlanderLab/tskitr/issues/6
4647
# See default flags used by clang (see below output from devtools::install())
4748
# clang -arch arm64 -I../inst/include -I../inst/include/tskit -I../inst/include/tskit/tskit -I/opt/homebrew/opt/gettext/include -falign-functions=64 -Wall -g -O2 -c tskit/convert.c -o tskit/convert.o
4849
# PKG_CFLAGS = -O2 -Wall
4950
# PKG_CXXFLAGS = -O2 -Wall
51+
# PKG_CXXFLAGS = -DTSK_TRACE_ERRORS
5052

5153
# Explicit compile rule for tskit C files
5254
tskit/%.o: tskit/%.c

tskitr/src/RcppExports.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,24 @@ BEGIN_RCPP
2828
return R_NilValue;
2929
END_RCPP
3030
}
31+
// test_tsk_trace_error_c
32+
void test_tsk_trace_error_c();
33+
RcppExport SEXP _tskitr_test_tsk_trace_error_c() {
34+
BEGIN_RCPP
35+
Rcpp::RNGScope rcpp_rngScope_gen;
36+
test_tsk_trace_error_c();
37+
return R_NilValue;
38+
END_RCPP
39+
}
40+
// test_tsk_trace_error_cpp
41+
void test_tsk_trace_error_cpp();
42+
RcppExport SEXP _tskitr_test_tsk_trace_error_cpp() {
43+
BEGIN_RCPP
44+
Rcpp::RNGScope rcpp_rngScope_gen;
45+
test_tsk_trace_error_cpp();
46+
return R_NilValue;
47+
END_RCPP
48+
}
3149
// kastore_version
3250
Rcpp::IntegerVector kastore_version();
3351
RcppExport SEXP _tskitr_kastore_version() {
@@ -230,6 +248,8 @@ END_RCPP
230248
static const R_CallMethodDef CallEntries[] = {
231249
{"_tskitr_test_tsk_bug_assert_c", (DL_FUNC) &_tskitr_test_tsk_bug_assert_c, 0},
232250
{"_tskitr_test_tsk_bug_assert_cpp", (DL_FUNC) &_tskitr_test_tsk_bug_assert_cpp, 0},
251+
{"_tskitr_test_tsk_trace_error_c", (DL_FUNC) &_tskitr_test_tsk_trace_error_c, 0},
252+
{"_tskitr_test_tsk_trace_error_cpp", (DL_FUNC) &_tskitr_test_tsk_trace_error_cpp, 0},
233253
{"_tskitr_kastore_version", (DL_FUNC) &_tskitr_kastore_version, 0},
234254
{"_tskitr_tskit_version", (DL_FUNC) &_tskitr_tskit_version, 0},
235255
{"_tskitr_ts_load", (DL_FUNC) &_tskitr_ts_load, 2},
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#include <Rcpp.h>
2+
#include <tskit/core.h>
3+
4+
extern "C" void tskitr_bug_assert_c(void);
5+
6+
// [[Rcpp::export]]
7+
void test_tsk_bug_assert_c() { tskitr_bug_assert_c(); }
8+
9+
// [[Rcpp::export]]
10+
void test_tsk_bug_assert_cpp() { tsk_bug_assert(0); }
11+
12+
extern "C" void tskitr_trace_error_c(void);
13+
14+
// [[Rcpp::export]]
15+
void test_tsk_trace_error_c() { tskitr_trace_error_c(); }
16+
17+
// [[Rcpp::export]]
18+
void test_tsk_trace_error_cpp() { tsk_trace_error(-1); }
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
#include <tskit/core.h>
22

33
void tskitr_bug_assert_c(void) { tsk_bug_assert(0); }
4+
5+
void tskitr_trace_error_c(void) { tsk_trace_error(-1); }

tskitr/src/test_tsk_bug_assert.cpp

Lines changed: 0 additions & 10 deletions
This file was deleted.

tskitr/tests/testthat/test_tskitr.R

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,10 @@ test_that("tsk_bug_assert() works", {
1616
expect_error(test_tsk_bug_assert_c())
1717
expect_error(test_tsk_bug_assert_cpp())
1818
})
19+
20+
test_that("tsk_trace_error() works", {
21+
t <- "You have to compile with -DTSK_TRACE_ERRORS to test theses - see src/Makevars.in"
22+
skip(t)
23+
expect_warning(test_tsk_trace_error_c())
24+
expect_warning(test_tsk_trace_error_cpp())
25+
})

0 commit comments

Comments
 (0)