1 #include "debug.h"
2 #include "utils.h"
3 #include <R.h>
4 #include <unistd.h>
5 #include <stdio.h>
6 #include <stdarg.h>
7
8 // For debug.h
9 #if defined(DEBUG_THREAD)
10 tct_thrd_t __main_thread__;
11 tct_thrd_t __background_thread__;
12 #endif
13
14
15 // It's not safe to call REprintf from the background thread but we need some
16 // way to output error messages. R CMD check does not it if the code uses the
17 // symbols stdout, stderr, and printf, so this function is a way to avoid
18 // those. It's to calling `fprintf(stderr, ...)`.
err_printf(const char * fmt,...)19 void err_printf(const char *fmt, ...) {
20 const size_t max_size = 4096;
21 char buf[max_size];
22
23 va_list args;
24 va_start(args, fmt);
25 int n = vsnprintf(buf, max_size, fmt, args);
26 va_end(args);
27
28 if (n == -1)
29 return;
30
31 ssize_t res = write(STDERR_FILENO, buf, n);
32 // This is here simply to avoid a warning about "ignoring return value" of
33 // the write(), on some compilers. (Seen with gcc 4.4.7 on RHEL 6)
34 res += 0;
35 }
36
37 // Set the default log level
38 LogLevel log_level_ = LOG_ERROR;
39
40
41 // Sets the current log level and returns previous value.
42 // [[Rcpp::export]]
log_level(std::string level)43 std::string log_level(std::string level) {
44 LogLevel old_level = log_level_;
45
46 if (level == "") {
47 // Do nothing
48 } else if (level == "OFF") {
49 log_level_ = LOG_OFF;
50 } else if (level == "ERROR") {
51 log_level_ = LOG_ERROR;
52 } else if (level == "WARN") {
53 log_level_ = LOG_WARN;
54 } else if (level == "INFO") {
55 log_level_ = LOG_INFO;
56 } else if (level == "DEBUG") {
57 log_level_ = LOG_DEBUG;
58 } else {
59 Rf_error("Unknown value for `level`");
60 }
61
62 switch(old_level) {
63 case LOG_OFF: return "OFF";
64 case LOG_ERROR: return "ERROR";
65 case LOG_WARN: return "WARN";
66 case LOG_INFO: return "INFO";
67 case LOG_DEBUG: return "DEBUG";
68 default: return "";
69 }
70 }
71
72 // Reports whether package was compiled with UBSAN
73 // [[Rcpp::export]]
using_ubsan()74 bool using_ubsan() {
75 #ifdef USING_UBSAN
76 return true;
77 #else
78 return false;
79 #endif
80 }
81