See More

// -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; indent-tabs-mode: nil; -*- // jedit: :folding=explicit: // // api.cpp: Rcpp R/C++ interface class library -- Rcpp api // // Copyright (C) 2012 - 2013 Dirk Eddelbuettel and Romain Francois // // This file is part of Rcpp. // // Rcpp is free software: you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 2 of the License, or // (at your option) any later version. // // Rcpp is distributed in the hope that it will be useful, but // WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with Rcpp. If not, see . #define COMPILING_RCPP #include using namespace Rcpp ; #include "internal.h" #include #ifdef RCPP_HAS_DEMANGLING #include #endif #if defined(__GNUC__) #if defined(WIN32) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__CYGWIN__) || defined(__sun) #else #include static std::string demangler_one( const char* input){ static std::string buffer ; buffer = input ; buffer.resize( buffer.find_last_of( '+' ) - 1 ) ; buffer.erase( buffer.begin(), buffer.begin() + buffer.find_last_of( ' ' ) + 1 ) ; return demangle( buffer) ; } #endif #endif namespace Rcpp { namespace internal{ namespace { unsigned long RNGScopeCounter = 0; } // [[Rcpp::register]] unsigned long enterRNGScope() { if (RNGScopeCounter == 0) GetRNGstate(); RNGScopeCounter++; return RNGScopeCounter ; } // [[Rcpp::register]] unsigned long exitRNGScope() { RNGScopeCounter--; if (RNGScopeCounter == 0) PutRNGstate(); return RNGScopeCounter ; } // [[Rcpp::register]] char* get_string_buffer(){ static char buffer[MAXELTSIZE]; return buffer ; } } // [[Rcpp::register]] const char * type2name(SEXP x) { switch (TYPEOF(x)) { case NILSXP: return "NILSXP"; case SYMSXP: return "SYMSXP"; case RAWSXP: return "RAWSXP"; case LISTSXP: return "LISTSXP"; case CLOSXP: return "CLOSXP"; case ENVSXP: return "ENVSXP"; case PROMSXP: return "PROMSXP"; case LANGSXP: return "LANGSXP"; case SPECIALSXP: return "SPECIALSXP"; case BUILTINSXP: return "BUILTINSXP"; case CHARSXP: return "CHARSXP"; case LGLSXP: return "LGLSXP"; case INTSXP: return "INTSXP"; case REALSXP: return "REALSXP"; case CPLXSXP: return "CPLXSXP"; case STRSXP: return "STRSXP"; case DOTSXP: return "DOTSXP"; case ANYSXP: return "ANYSXP"; case VECSXP: return "VECSXP"; case EXPRSXP: return "EXPRSXP"; case BCODESXP: return "BCODESXP"; case EXTPTRSXP: return "EXTPTRSXP"; case WEAKREFSXP: return "WEAKREFSXP"; case S4SXP: return "S4SXP"; default: return ""; } } } // namespace Rcpp // [[Rcpp::register]] std::string demangle( const std::string& name ){ #ifdef RCPP_HAS_DEMANGLING std::string real_class ; int status =-1 ; char *dem = 0; dem = abi::__cxa_demangle(name.c_str(), 0, 0, &status); if( status == 0 ){ real_class = dem ; free(dem); } else { real_class = name ; } return real_class ; #else return name ; #endif } // [[Rcpp::register]] const char* short_file_name(const char* file){ std::string f(file) ; size_t index = f.find("/include/") ; if( index != std::string::npos ){ f = f.substr( index + 9 ) ; } return f.c_str() ; } // [[Rcpp::internal]] SEXP as_character_externalptr(SEXP xp){ char buffer[20] ; snprintf( buffer, 20, "%p", (void*)EXTPTR_PTR(xp) ) ; return Rcpp::wrap( (const char*)buffer ) ; } // [[Rcpp::internal]] SEXP rcpp_capabilities(){ Shield cap( Rf_allocVector( LGLSXP, 11 ) ); Shield names( Rf_allocVector( STRSXP, 11 ) ); #ifdef HAS_VARIADIC_TEMPLATES LOGICAL(cap)[0] = TRUE ; #else LOGICAL(cap)[0] = FALSE ; #endif #ifdef HAS_CXX0X_INITIALIZER_LIST LOGICAL(cap)[1] = TRUE ; #else LOGICAL(cap)[1] = FALSE ; #endif /* exceptions are always supported */ LOGICAL(cap)[2] = TRUE ; #ifdef HAS_TR1_UNORDERED_MAP LOGICAL(cap)[3] = TRUE ; #else LOGICAL(cap)[3] = FALSE ; #endif #ifdef HAS_TR1_UNORDERED_SET LOGICAL(cap)[4] = TRUE ; #else LOGICAL(cap)[4] = FALSE ; #endif LOGICAL(cap)[5] = TRUE ; #ifdef RCPP_HAS_DEMANGLING LOGICAL(cap)[6] = TRUE ; #else LOGICAL(cap)[6] = FALSE ; #endif LOGICAL(cap)[7] = FALSE ; #ifdef RCPP_HAS_LONG_LONG_TYPES LOGICAL(cap)[8] = TRUE ; #else LOGICAL(cap)[8] = FALSE ; #endif #ifdef HAS_CXX0X_UNORDERED_MAP LOGICAL(cap)[9] = TRUE ; #else LOGICAL(cap)[9] = FALSE ; #endif #ifdef HAS_CXX0X_UNORDERED_SET LOGICAL(cap)[10] = TRUE ; #else LOGICAL(cap)[10] = FALSE ; #endif SET_STRING_ELT(names, 0, Rf_mkChar("variadic templates") ) ; SET_STRING_ELT(names, 1, Rf_mkChar("initializer lists") ) ; SET_STRING_ELT(names, 2, Rf_mkChar("exception handling") ) ; SET_STRING_ELT(names, 3, Rf_mkChar("tr1 unordered maps") ) ; SET_STRING_ELT(names, 4, Rf_mkChar("tr1 unordered sets") ) ; SET_STRING_ELT(names, 5, Rf_mkChar("Rcpp modules") ) ; SET_STRING_ELT(names, 6, Rf_mkChar("demangling") ) ; SET_STRING_ELT(names, 7, Rf_mkChar("classic api") ) ; SET_STRING_ELT(names, 8, Rf_mkChar("long long") ) ; SET_STRING_ELT(names, 9, Rf_mkChar("C++0x unordered maps") ) ; SET_STRING_ELT(names, 10, Rf_mkChar("C++0x unordered sets") ) ; Rf_setAttrib( cap, R_NamesSymbol, names ) ; return cap ; } // [[Rcpp::internal]] SEXP rcpp_can_use_cxx0x(){ #ifdef HAS_VARIADIC_TEMPLATES return Rf_ScalarLogical( TRUE ); #else return Rf_ScalarLogical( FALSE ); #endif } // [[Rcpp::register]] SEXP stack_trace( const char* file, int line ){ #if defined(__GNUC__) #if defined(WIN32) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__CYGWIN__) || defined(__sun) // Simpler version for Windows and *BSD List trace = List::create( _[ "file" ] = file, _[ "line" ] = line, _[ "stack" ] = "C++ stack not available on this system" ) ; trace.attr("class") = "Rcpp_stack_trace" ; return trace ; #else // ! (defined(WIN32) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__CYGWIN__) || defined(__sun) /* inspired from http://tombarta.wordpress.com/2008/08/01/c-stack-traces-with-gcc/ */ const size_t max_depth = 100; size_t stack_depth; void *stack_addrs[max_depth]; char **stack_strings; stack_depth = backtrace(stack_addrs, max_depth); stack_strings = backtrace_symbols(stack_addrs, stack_depth); std::string current_line ; CharacterVector res( stack_depth - 1) ; std::transform( stack_strings + 1, stack_strings + stack_depth, res.begin(), demangler_one ) ; free(stack_strings); // malloc()ed by backtrace_symbols List trace = List::create( _["file" ] = file, _["line" ] = line, _["stack"] = res ) ; trace.attr("class") = "Rcpp_stack_trace" ; return trace ; #endif #else /* !defined( __GNUC__ ) */ return R_NilValue ; #endif } // }}}