RInside/0000755000176200001440000000000015002022042011572 5ustar liggesusersRInside/MD50000644000176200001440000002006515002022042012105 0ustar liggesusers665f8b2bf4209acded016e4776b8dfea *ChangeLog a1f0cb3e34b60cb940d998c781759cae *DESCRIPTION ff85fc8e8296eec31745e449f30212aa *NAMESPACE 646cfa9b1e162d9aabfa9438fa2b540a *R/RInsidePaths.R 4bcb62e5113ea661c4cfa4a88282a1a4 *R/RcppExports.R 221b942b14cc416f187593b9a662d970 *R/zzz.R 7ac43cd4cce6e9c99dbb510004c13500 *README.md 920df51c4d43025c78ea491ecff34c3d *cleanup a354953bc638adfe8fb1143a2428eb67 *cleanup.win 9f45209f2a66297cf48a6750cecffa57 *inst/NEWS.Rd 6721423fd66ead7a6fd303e6ec8b4d49 *inst/THANKS f80b0a9850ed5c911c690ec9f6520570 *inst/examples/armadillo/GNUmakefile 355f2e6af82135dac79496afd1ae57bc *inst/examples/armadillo/cmake/CMakeLists.txt bd5497b7c0899be80715c7a2e53042e7 *inst/examples/armadillo/cmake/WIN.readme.txt a85814fb53b3bbfb2fe7af0d15da33a1 *inst/examples/armadillo/rinside_arma0.cpp 80cfd5e8f32ecc65a49a99664e445522 *inst/examples/armadillo/rinside_arma1.cpp f03cea8870e038db337ff2f5c76ccdc1 *inst/examples/c_interface/GNUmakefile 664acc5243c404180453806f741778ab *inst/examples/c_interface/hello.c 76a5cd0380e523b7e8cdf02026358f1d *inst/examples/c_interface/hello.rb f8a15301960778d39a20f9e2a8f535a3 *inst/examples/c_interface/passdata.c 5d96d5c8f809fb142fa84dd9cafbf426 *inst/examples/c_interface/passdata.rb 04d75af950f45921fe54bbc6bdce3fff *inst/examples/eigen/GNUmakefile f7bcd4fdad18fac76e2584c4df6b3476 *inst/examples/eigen/cmake/CMakeLists.txt bd5497b7c0899be80715c7a2e53042e7 *inst/examples/eigen/cmake/WIN.readme.txt 6142a963def1a600cb89f036e7ed75e8 *inst/examples/eigen/rinside_eigen0.cpp 8d317f529403b100ea99fc208ed2efc5 *inst/examples/eigen/rinside_eigen1.cpp 9572105fa192851b7b5a2dfbb43f0e38 *inst/examples/mpi/GNUmakefile 543e0e1d7bd34c9408b5429ef850674f *inst/examples/mpi/cmake/CMakeLists.txt 6f2194e3e964422db524c24e3023206e *inst/examples/mpi/rinside_mpi_sample0.cpp 4ad324adeb8ff397d94587d3f911aafd *inst/examples/mpi/rinside_mpi_sample1.cpp 5ff649ec1e283dedd3d78991552fd4a1 *inst/examples/mpi/rinside_mpi_sample2.cpp f455f4fb464ada55e407db7fbac4d94f *inst/examples/mpi/rinside_mpi_sample3.cpp 98a5f3fb395b5c4789950fd44c018037 *inst/examples/mpi/rinside_mpi_sample4.cpp 51af0d9b54c7dc00a394cb7aaaa789d9 *inst/examples/qt/README 7f73a577ed7a8398adb09f32c8594a96 *inst/examples/qt/cmake/CMakeLists.txt 6f76c08d0b895f250b52d19cf85630ed *inst/examples/qt/main.cpp 173fe7bba20367c35f0378d1e2f3c278 *inst/examples/qt/qtdensity.cpp 5f7fbd7ce902c4b23d73d3816df1dd8b *inst/examples/qt/qtdensity.h 49f086d0d9a4521bda8b9f28c2c4e01b *inst/examples/qt/qtdensity.pro 72b08213ee496cf2ad16b03660e3df62 *inst/examples/sandboxed_server/GNUmakefile 24d7791efee79248cf00b9b1f91fec3e *inst/examples/sandboxed_server/README.md ee76b78f4ba19a94cf7444410bdf867f *inst/examples/sandboxed_server/client/callback_helper.h 84b60f1aa78679f87ca2a6a877b8306b *inst/examples/sandboxed_server/client/rinsideclient.cpp 268ab56a244f946604aa05c3b5c45ae9 *inst/examples/sandboxed_server/client/rinsideclient.h 0934459516cd0a9a0e3f483b050d2558 *inst/examples/sandboxed_server/common/binarystream.cpp 85aa98dc9d117afda48136f94124d844 *inst/examples/sandboxed_server/common/binarystream.h 346d6fbd0b1cee04dc7c1614c602b0cc *inst/examples/sandboxed_server/common/constants.h 73c52a33e93431ac45604ccc1d91cd8e *inst/examples/sandboxed_server/common/typeid.h 911b55c31ef3d36c45fc49101937b3f4 *inst/examples/sandboxed_server/datatypes/bar.cpp f80099b82496682ca4804dd9fa5f9610 *inst/examples/sandboxed_server/datatypes/bar.h 5c07e7924ffce8be1cbabe668853e48d *inst/examples/sandboxed_server/datatypes/bar_rcpp_wrapper_declarations.h 3c25043902ee9a9cbbd5ef55a4f667aa *inst/examples/sandboxed_server/datatypes/bar_rcpp_wrapper_definitions.h 330625ad4991a296d1d1fb5acb20212e *inst/examples/sandboxed_server/datatypes/foo.cpp ab2699f8c40fac20b8aeb3920efb026e *inst/examples/sandboxed_server/datatypes/foo.h ae9378659614ffc4680a13c99bd92aa8 *inst/examples/sandboxed_server/datatypes/foo_rcpp_wrapper_declarations.h 7f31051c1df73805ddba67055883ae13 *inst/examples/sandboxed_server/datatypes/foo_rcpp_wrapper_definitions.h 59bbecd246a56bf97236a4326cad57ed *inst/examples/sandboxed_server/example_client.cpp 4b564ae6caf5b4271828265e5c7cdbf0 *inst/examples/sandboxed_server/example_server.cpp 5443cb9f600e03b0069243ac456eaf4a *inst/examples/sandboxed_server/server/internalfunction_clone.h 9864204bed904f145d8fb65fb0b452a5 *inst/examples/sandboxed_server/server/rinside_callbacks.h 514aaa118aa669e53b538293bd3ae75c *inst/examples/sandboxed_server/server/rinsideserver.cpp bece4eb3d2002c32b9687cf34a32819d *inst/examples/sandboxed_server/server/rinsideserver.h 40f6afeff176eb8730957a234f111b8a *inst/examples/standard/GNUmakefile 896df6d28697d491146642d0a82f29bc *inst/examples/standard/Makefile.win 0069cfcbdad4da03a9cf29a45e51f175 *inst/examples/standard/cmake/CMakeLists.txt 7828adbb3a1488e1f70d46bb3dcc7095 *inst/examples/standard/rinside_callbacks0.cpp 5bd98afb4f97c897fb13bb153138e748 *inst/examples/standard/rinside_callbacks1.cpp 44dde685b66b4759f4aa48c13e50b4a7 *inst/examples/standard/rinside_interactive0.cpp 284cf376b2cdd3dbf859d3e59e08335d *inst/examples/standard/rinside_module_sample0.cpp 933de0f892c71f54c7159b34fee37827 *inst/examples/standard/rinside_sample0.cpp 2b71c28cbe922ae8b7c20b28ef5acc08 *inst/examples/standard/rinside_sample1.cpp 73fe2510f9e99dc412e1243453012dec *inst/examples/standard/rinside_sample10.cpp 93d40aaff9cf0af2e673b191cf39afcd *inst/examples/standard/rinside_sample11.cpp f6413f06d156ec79cafa74ecdeb5b42c *inst/examples/standard/rinside_sample12.cpp 5b8b89745e4f1993ac20efd00a1badb2 *inst/examples/standard/rinside_sample13.cpp c1d320aa52d092e02ddb654c475a7655 *inst/examples/standard/rinside_sample14.cpp 9b2acf2c6aa82e2283055ce761314198 *inst/examples/standard/rinside_sample15.cpp eee02a8f3f9546b4dd997c09d8d24dc1 *inst/examples/standard/rinside_sample16.cpp 0cafbc909570794bb7887b1f032250d5 *inst/examples/standard/rinside_sample17.cpp c4c629c2b0fde20be830bd8016f49e24 *inst/examples/standard/rinside_sample2.cpp 3a08885a9066ad1b5d233655ac65604a *inst/examples/standard/rinside_sample3.cpp 00bbc2e162652c972c3d4bec02f398f2 *inst/examples/standard/rinside_sample4.cpp b4ac171130a6dab397aa4a34f5c46524 *inst/examples/standard/rinside_sample5.cpp 8276394037ce104ddf3b780576c01a5f *inst/examples/standard/rinside_sample6.cpp d563809a8aa51678215fc5d71a7c3e7d *inst/examples/standard/rinside_sample7.cpp 169bdb51448e248cf9b699a3a7774298 *inst/examples/standard/rinside_sample8.cpp f25739b53eb3d69f4b9844d454cb15e3 *inst/examples/standard/rinside_sample9.cpp 4112d425e41dd37511639f409ca8d203 *inst/examples/standard/rinside_test0.cpp 78cca921b3470109786237e71d46b0e0 *inst/examples/standard/rinside_test1.cpp d5e3da4daebe74fdf2ce2b4c1d5dcc27 *inst/examples/standard/rinside_test2.cpp da7afc2eb974e6af3e8811fe2d8187fa *inst/examples/threads/GNUmakefile ed012740ba04d6aff8029f2da33c5b74 *inst/examples/threads/boostEx.cpp 644c8b47369ccf53f4518774c7ab83cc *inst/examples/wt/GNUmakefile e73ccdb6ea625d4d402ce5873c0fda06 *inst/examples/wt/cmake/CMakeLists.txt f67f11be2e2a9d671cb29e6b11e5ee7a *inst/examples/wt/wtdensity.cpp a3920c0503bf8a2239de4ec47528b214 *inst/examples/wt/wtdensity.css f55a104ad5550cb87d2464f793ebc4ed *inst/examples/wt/wtdensity.xml 2daa9e35371c74c52d7b80e7459778bc *inst/examples/wt/wtdensityPlain.cpp 17f884c08374bc6336b8b6abab8b4e65 *inst/include/Callbacks.h 654aa4c207899c8629037c15814ef58f *inst/include/MemBuf.h a07df2e44b20f51d8b8f3b5d3fb02e15 *inst/include/RInside.h 3d900e85e4cce41c9babc37609e3b34a *inst/include/RInsideCommon.h 193ebd47832d03c444c3f4d516915062 *inst/include/RInsideConfig.h 982d9441aa14c075bd8a61d045057de9 *inst/include/RInside_C.h 9bba313d3c86b9a8038d44704366bee2 *man/RInside-package.Rd 84256b19983c8a96adc9269b7b459315 *src/Makevars bfc3d61e790353312812f3caada0c950 *src/Makevars.win c47d49883a572ae1efcc3f075875f8af *src/MemBuf.cpp 57164185d0e02cf15d6b07df47636193 *src/RInside.cpp 0c66b3b9528f011fb699434ce5e66346 *src/RInside_C.cpp 6c018a81c82afd693e27d1d37af60287 *src/RcppExports.cpp 428c88042a47cfb57a7a84b3eff13703 *src/compiler.cpp d6e282694398aea01e7458f266691a17 *src/setenv/setenv.c e0953bcb1cf6e7732945551f24f7b207 *src/tools/RInsideAutoloads.r 1152b11227fe9345460ae45baf5acf76 *src/tools/RInsideEnvVars.r 595752b43220c0d19c9f2e2d755bb5c8 *src/tools/unix2dos.r RInside/R/0000755000176200001440000000000013632017612012011 5ustar liggesusersRInside/R/RcppExports.R0000644000176200001440000000031513632017612014424 0ustar liggesusers# Generated by using Rcpp::compileAttributes() -> do not edit by hand # Generator token: 10BE3573-1514-4C36-9D1C-5A225CD40393 showCompiler <- function() { invisible(.Call(`_RInside_showCompiler`)) } RInside/R/zzz.R0000644000176200001440000000010512257416630012772 0ustar liggesusers#.First.lib <- function(lib, pkg) { # cat("Loaded RInside.\n") #} RInside/R/RInsidePaths.R0000644000176200001440000000660313632015267014502 0ustar liggesusers ## Use R's internal knowledge of path settings to find the lib/ directory ## plus optinally an arch-specific directory on system building multi-arch RInsideLdPath <- function() { if (nzchar(.Platform$r_arch)) { ## eg amd64, ia64, mips system.file("lib",.Platform$r_arch,package="RInside") } else { system.file("lib",package="RInside") } } ## Provide linker flags -- i.e. -L/path/to/libRInside -- as well as an ## optional rpath call needed to tell the Linux dynamic linker about the ## location. This is not needed on OS X where we encode this as library ## built time (see src/Makevars) or Windows where we use a static library ## Updated Jan 2010: We now default to static linking but allow the use ## of rpath on Linux if static==FALSE has been chosen ## Note that this is probably being called from LdFlags() RInsideLdFlags <- function(static=TRUE) { rinsidedir <- RInsideLdPath() if (static) { # static is default on Windows and OS X flags <- paste(rinsidedir, "/libRInside.a", sep="") if (.Platform$OS.type=="windows") { flags <- shQuote(flags) } } else { # else for dynamic linking flags <- paste("-L", rinsidedir, " -lRInside", sep="") # baseline setting if ((.Platform$OS.type == "unix") && # on Linux, we can use rpath to encode path (length(grep("^linux",R.version$os)))) { flags <- paste(flags, " -Wl,-rpath,", rinsidedir, sep="") } } invisible(flags) } ## Provide compiler flags -- i.e. -I/path/to/RInside.h RInsideCxxFlags <- function() { path <- system.file( "include", package = "RInside" ) # if (.Platform$OS.type=="windows") { # path <- shQuote(path) # } sprintf('-I%s', path) } ## Shorter names, and call cat() directly CxxFlags <- function() { cat(RInsideCxxFlags()) } ## Provide compiler flags -- i.e. -I/path/to/RInsideC.h RInsideCFlags <- function() { path <- system.file( "include", package = "RInside" ) # if (.Platform$OS.type=="windows") { # path <- shQuote(path) # } sprintf('-I%s', path) } ## Shorter names, and call cat() directly CFlags <- function() { cat(RInsideCFlags()) } ## LdFlags defaults to static linking on the non-Linux platforms Windows and OS X LdFlags <- function(static=ifelse(length(grep("^linux",R.version$os))==0, TRUE, FALSE)) { cat(RInsideLdFlags(static=static)) } # ## Use R's internal knowledge of path settings to find the lib/ directory # ## plus optinally an arch-specific directory on system building multi-arch # RInsideLdPath <- function() { # Rcpp:::packageLibPath( package = "RInside" ) # } ## Provide linker flags -- i.e. -L/path/to/libRInside -- as well as an ## optional rpath call needed to tell the Linux dynamic linker about the ## location. This is not needed on OS X where we encode this as library ## built time (see src/Makevars) or Windows where we use a static library # RInsideLdFlags <- function(static=Rcpp:::staticLinking()) { # Rcpp:::packageLdFlags( "RInside", static ) # } ## Provide compiler flags -- i.e. -I/path/to/RInside.h # RInsideCxxFlags <- function() { # Rcpp:::includeFlag( package = "RInside" ) # } ## Shorter names, and call cat() directly # CxxFlags <- function() cat(RInsideCxxFlags()) # LdFlags <- function(static=Rcpp:::staticLinking()) cat(RInsideLdFlags(static)) RInside/cleanup.win0000644000176200001440000000027412257416630013766 0ustar liggesusers rm -vf src/*.o src/*.so inst/lib/*.h \ inst/lib/lib*.so inst/lib/lib*.a cd inst/examples/standard && make -f Makefile.win clean && cd - ## cd inst/examples/mpi && make clean && cd - RInside/cleanup0000755000176200001440000000057015002010355013155 0ustar liggesusers rm -vf src/*.o src/*.so inst/lib/*.h \ src/RInsideEnvVars.h src/RInsideAutoloads.h \ inst/lib/lib*.so inst/lib/lib*.a \ Librinside.a for d in standard mpi qt wt armadillo eigen threads do cd inst/examples/${d} test -f Makefile && make clean test -f GNUmakefile && make -f GNUmakefile clean rm -f *~ cd ../../.. done rm -rf inst/examples/qt/build RInside/src/0000755000176200001440000000000015002010346012365 5ustar liggesusersRInside/src/RcppExports.cpp0000644000176200001440000000124413632017273015400 0ustar liggesusers// Generated by using Rcpp::compileAttributes() -> do not edit by hand // Generator token: 10BE3573-1514-4C36-9D1C-5A225CD40393 #include "../inst/include/RInside.h" #include using namespace Rcpp; // showCompiler void showCompiler(); RcppExport SEXP _RInside_showCompiler() { BEGIN_RCPP Rcpp::RNGScope rcpp_rngScope_gen; showCompiler(); return R_NilValue; END_RCPP } static const R_CallMethodDef CallEntries[] = { {"_RInside_showCompiler", (DL_FUNC) &_RInside_showCompiler, 0}, {NULL, NULL, 0} }; RcppExport void R_init_RInside(DllInfo *dll) { R_registerRoutines(dll, NULL, CallEntries, NULL, NULL); R_useDynamicSymbols(dll, FALSE); } RInside/src/setenv/0000755000176200001440000000000013145553714013712 5ustar liggesusersRInside/src/setenv/setenv.c0000644000176200001440000000470413145553714015367 0ustar liggesusers// -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; indent-tabs-mode: nil; -*- // // RInside.cpp: R/C++ interface class library -- Easier R embedding into C++ // // Copyright (C) 2009 - 2010 Dirk Eddelbuettel and Richard Holbrey // Copyright (C) 2012 Dirk Eddelbuettel and Romain Francois // // This file is part of RInside. // // RInside 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. // // RInside 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 RInside. If not, see . #include #include #include // borrowed from Renviron.c extern "C" int setenv(const char *env_var, const char *env_val, int dummy) { char *buf, *value, *p, *q, *a, *b, quote='\0'; int inquote = 0; //make non-const copies a = (char *) malloc((strlen(env_var) + 1) * sizeof(char)); b = (char *) malloc((strlen(env_val) + 1) * sizeof(char)); if (!a || !b) { Rf_error("memory allocation failure in setenv"); } strcpy(a, env_var); strcpy(b, env_val); buf = (char *) malloc((strlen(a) + strlen(b) + 2) * sizeof(char)); if (!buf) { Rf_error("memory allocation failure in setenv"); } strcpy(buf, a); strcat(buf, "="); value = buf+strlen(buf); /* now process the value */ for(p = b, q = value; *p; p++) { /* remove quotes around sections, preserve \ inside quotes */ if(!inquote && (*p == '"' || *p == '\'')) { inquote = 1; quote = *p; continue; } if(inquote && *p == quote && *(p-1) != '\\') { inquote = 0; continue; } if(!inquote && *p == '\\') { if(*(p+1) == '\n') { p++; } else if(*(p+1) == '\\') { *q++ = '/'; p++; } else { *q++ = '/'; } continue; } if(inquote && *p == '\\' && *(p+1) == quote) continue; *q++ = *p; } *q = '\0'; //if (putenv(buf)) //warningcall(R_NilValue, _("problem in setting variable '%s' in Renviron"), a); return putenv(buf); /* no free here: storage remains in use */ } RInside/src/Makevars.win0000644000176200001440000000355213310442501014664 0ustar liggesusers## -*- mode: Makefile; tab-width: 8 -*- ## ## Copyright (C) 2010 - 2014 Dirk Eddelbuettel and Romain Francois ## ## This file is part of RInside. ## ## RInside 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. ## ## RInside 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 RInside. If not, see . USERLIBST = libRInside.a USERLIB = libRInside.dll #USERDIR = $(R_PACKAGE_DIR)/inst/lib$(R_ARCH) USERDIR = ../inst/lib$(R_ARCH) PKG_CPPFLAGS = -I. -I../inst/include/ PKG_LIBS = $(shell "${R_HOME}/bin${R_ARCH_BIN}/Rscript.exe" -e "Rcpp:::LdFlags()") RSCRIPT = "${R_HOME}/bin${R_ARCH_BIN}/Rscript.exe" all: headers $(SHLIB) userLibrary headers: RInsideAutoloads.h RInsideEnvVars.h RInsideAutoloads.h: $(RSCRIPT) tools/RInsideAutoloads.r > RInsideAutoloads.h RInsideEnvVars.h: $(RSCRIPT) tools/RInsideEnvVars.r > RInsideEnvVars.h RInside.cpp: headers userLibrary: $(USERLIBST) $(USERLIB) -@if test ! -e $(USERDIR); then mkdir -p $(USERDIR); fi cp $(USERLIB) $(USERDIR) $(USERLIBST): $(OBJECTS) -@if test ! -e $(USERDIR); then mkdir -p $(USERDIR); fi $(AR) qc $(USERLIBST) $^ @if test -n "$(RANLIB)"; then $(RANLIB) $(USERLIBST); fi cp $(USERLIBST) $(USERDIR) ls -lR $(USERDIR) $(USERLIB): $(OBJECTS) $(CXX) -Wl,--export-all-symbols -shared -o $(USERLIB) $^ $(ALL_LIBS) -lws2_32 .PHONY: all clean userLibrary headers clean: rm -f $(OBJECTS) $(SHLIB) $(USERLIBST) $(USERLIB) RInside/src/compiler.cpp0000644000176200001440000000055613632017712014724 0ustar liggesusers #include // [[Rcpp::export]] void showCompiler() { #if defined(__DATE__) const char *date = __DATE__; #else const char *date = ""; #endif #if defined(__VERSION__) const char *ver = __VERSION__; #else const char *ver = ""; #endif Rcpp::Rcout << "Compiled on " << date << " by compiler version " << ver << std::endl; } RInside/src/Makevars0000644000176200001440000000412714366461625014113 0ustar liggesusers## -*- mode: Makefile; tab-width: 8 -*- ## ## Copyright (C) 2010 - 2023 Dirk Eddelbuettel and Romain Francois ## ## This file is part of RInside. ## ## RInside 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. ## ## RInside 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 RInside. If not, see . USERLIB=libRInside$(DYLIB_EXT) USERLIBST=libRInside.a USERDIR=../inst/lib PKG_CPPFLAGS = -I. -I../inst/include/ PKG_LIBS = all: headers $(SHLIB) userLibrary headers: RInsideAutoloads.h RInsideEnvVars.h RInsideAutoloads.h: ${R_HOME}/bin/Rscript tools/RInsideAutoloads.r > RInsideAutoloads.h RInsideEnvVars.h: ${R_HOME}/bin/Rscript tools/RInsideEnvVars.r > RInsideEnvVars.h RInside.cpp: headers userLibrary: $(USERLIB) $(USERLIBST) -@if test ! -e $(USERDIR)$(R_ARCH); then mkdir -p $(USERDIR)$(R_ARCH); fi cp $(USERLIB) $(USERDIR)$(R_ARCH) cp $(USERLIBST) $(USERDIR)$(R_ARCH) rm $(USERLIB) $(USERLIBST) $(USERLIB): $(OBJECTS) $(SHLIB_CXXLD) -o $(USERLIB) $^ $(SHLIB_CXXLDFLAGS) $(LDFLAGS) $(ALL_LIBS) # if we are # - not on Window NT (a tip from data.table) # - on macOS aka Darwin which needs this # - the library is present (implying non-system library use) # then let us call install_name_tool @if [ "$(OS)" != "Windows_NT" ] && [ `uname -s` = 'Darwin' ] && test -e "/usr/bin/install_name_tool"; then /usr/bin/install_name_tool -add_rpath @loader_path/../lib$(R_ARCH) $(USERLIB); fi $(USERLIBST): $(OBJECTS) $(AR) qc $(USERLIBST) $^ @if test -n "$(RANLIB)"; then $(RANLIB) $(USERLIBST); fi .PHONY: all clean userLibrary headers clean: rm -f $(OBJECTS) $(SHLIB) $(USERLIB) $(USERLIBST) RInside/src/MemBuf.cpp0000644000176200001440000000274412257416630014272 0ustar liggesusers// -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; indent-tabs-mode: nil; -*- // // MemBuf.cpp: R/C++ interface class library -- Easier R embedding into C++ // // Copyright (C) 2009 Dirk Eddelbuettel // Copyright (C) 2010 - 2012 Dirk Eddelbuettel and Romain Francois // // This file is part of RInside. // // RInside 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. // // RInside 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 RInside. If not, see . #include #include #include #include extern bool verbose; extern const char *programName; MemBuf::~MemBuf() {} MemBuf::MemBuf(int sizebytes) : buffer() { buffer.reserve(sizebytes) ; } void MemBuf::resize() { // Use power of 2 resizing buffer.reserve( 2*buffer.capacity() ) ; } void MemBuf::rewind(){ buffer.clear() ; } void MemBuf::add(const std::string& buf){ int buflen = buf.size() ; while ( ( buflen + buffer.size() ) >= buffer.capacity() ) { resize(); } buffer += buf ; } RInside/src/tools/0000755000176200001440000000000014775734755013566 5ustar liggesusersRInside/src/tools/RInsideAutoloads.r0000755000176200001440000000161612257416630017147 0ustar liggesusers#!/usr/bin/r # # This owes a lot to autoloads.R in the littler sources dp <- getOption("defaultPackages") #dp <- dp[dp != 'datasets'] ## Rscript loads it too #dp <- dp[dp != 'methods'] ## Rscript (in R 2.6.1) doesn't load methods either # Count of default packages cat(" int packc = ",length(dp),";\n",sep='') # List of packages cat(" const char *pack[] = {\n",paste(' "',dp,'"',sep='',collapse=",\n"),"\n };\n", sep="") packobjc <- array(0,dim=length(dp)) packobj <- NULL for (i in 1:length(dp)){ obj = ls(paste("package:",dp[i],sep='')) packobjc[i] = length(obj) packobj = c(packobj,obj) } # List of counts of objects per package cat(" int packobjc[] = {\n ",paste(packobjc,sep='',collapse=",\n "),"\n };\n", sep="") # List of object names cat(" const char *packobj[] = {\n ",paste('"',packobj,'"',sep='',collapse=",\n "),"\n };\n", sep="") RInside/src/tools/RInsideEnvVars.r0000755000176200001440000000137714775734755016626 0ustar liggesusers#!/usr/bin/r -q # # This owes a lot to littler.R in the littler sources ExcludeVars <- c("R_SESSION_TMPDIR", "R_HISTFILE", "R_LIBRARY_DIR", "R_LIBS", "R_PACKAGE_DIR", "R_SESSION_INITIALIZED") IncludeVars <- Sys.getenv() IncludeVars <- IncludeVars[grep("^R_",names(IncludeVars),perl=TRUE)] if (.Platform$OS.type == "windows") { IncludeVars <- gsub("\\\\", "/", IncludeVars, perl=TRUE) IncludeVars <- gsub("\r", "", IncludeVars, fixed = TRUE) } cat(" const char *R_VARS[] = {\n") for (i in 1:length(IncludeVars)){ if (names(IncludeVars)[i] %in% ExcludeVars) next cat(' "', names(IncludeVars)[i], '", "', gsub('"', r"(\\")", IncludeVars[i], perl=TRUE), '",\n', sep='') } cat(" NULL\n };\n") RInside/src/tools/unix2dos.r0000644000176200001440000000050712257416630015504 0ustar liggesusers ## simple 0d 0a -> 0a converter to suppress a warning on Windows filename <- commandArgs(trailingOnly=TRUE)[1] if (!file.exists(filename)) q() con <- file(filename, "rb") bin <- readBin(con, raw(), 100000) bin <- bin[ which(bin != "0d") ] close(con) Sys.sleep(1) con <- file(filename, "wb") writeBin(bin, con) close(con) RInside/src/RInside.cpp0000644000176200001440000004131714366461044014455 0ustar liggesusers// -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; indent-tabs-mode: nil; -*- // // RInside.cpp: R/C++ interface class library -- Easier R embedding into C++ // // Copyright (C) 2009 Dirk Eddelbuettel // Copyright (C) 2010 - 2022 Dirk Eddelbuettel and Romain Francois // // This file is part of RInside. // // RInside 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. // // RInside 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 RInside. If not, see . #include #include #ifndef _WIN32 #define R_INTERFACE_PTRS #include #endif RInside* RInside::instance_m = 0 ; const char *programName = "RInside"; #ifdef _WIN32 // on Windows, we need to provide setenv which is in the file setenv.c here #include "setenv/setenv.c" extern int optind; #include char rHome[MAX_PATH+1]; #endif RInside::~RInside() { // now empty as MemBuf is internal R_dot_Last(); R_RunExitFinalizers(); R_CleanTempDir(); //Rf_KillAllDevices(); //#ifndef WIN32 //fpu_setup(FALSE); //#endif Rf_endEmbeddedR(0); instance_m = 0 ; delete global_env_m; } RInside::RInside(): global_env_m(NULL) #ifdef RINSIDE_CALLBACKS , callbacks(0) #endif { initialize(0, 0, false, false, false); } #ifdef _WIN32 #if R_VERSION >= R_Version(4,2,0) static int myReadConsole(const char *prompt, unsigned char *buf, int len, int addtohistory) { #else static int myReadConsole(const char *prompt, char *buf, int len, int addtohistory) { #endif fputs(prompt, stdout); fflush(stdout); if (fgets((char *)buf, len, stdin)) return 1; else return 0; } static void myWriteConsole(const char *buf, int len) { fwrite(buf, sizeof(char), len, stdout); fflush(stdout); } static void myCallBack() { /* called during i/o, eval, graphics in ProcessEvents */ } static void myBusy(int which) { /* set a busy cursor ... if which = 1, unset if which = 0 */ } void myAskOk(const char *info) { } int myAskYesNoCancel(const char *question) { const int yes = 1; return yes; } #endif RInside::RInside(const int argc, const char* const argv[], const bool loadRcpp, const bool verbose, const bool interactive) #ifdef RINSIDE_CALLBACKS : callbacks(0) #endif { initialize(argc, argv, loadRcpp, verbose, interactive); } // TODO: use a vector would make all this a bit more readable void RInside::initialize(const int argc, const char* const argv[], const bool loadRcpp, const bool verbose, const bool interactive) { if (instance_m) { throw std::runtime_error( "can only have one RInside instance" ) ; } else { instance_m = this ; } verbose_m = verbose; // Default is false interactive_m = interactive; // generated from Makevars{.win} #include "RInsideEnvVars.h" #ifdef _WIN32 // we need a special case for Windows where users may deploy an RInside binary from CRAN // which will have R_HOME set at compile time to CRAN's value -- so let's try to correct // this here: a) allow user's setting of R_HOME and b) use R's get_R_HOME() function if (getenv("R_HOME") == NULL) { // if on Windows and not set char *rhome = get_R_HOME(); // query it, including registry if (rhome != NULL) { // if something was found setenv("R_HOME", get_R_HOME(), 1); // store what we got as R_HOME } // this will now be used in next blocks } #endif for (int i = 0; R_VARS[i] != NULL; i+= 2) { if (getenv(R_VARS[i]) == NULL) { // if env variable is not yet set if (setenv(R_VARS[i],R_VARS[i+1],1) != 0){ throw std::runtime_error(std::string("Could not set R environment variable ") + std::string(R_VARS[i]) + std::string(" to ") + std::string(R_VARS[i+1])); } } } #ifndef _WIN32 R_SignalHandlers = 0; // Don't let R set up its own signal handlers #endif init_tempdir(); const char *R_argv[] = {(char*)programName, "--gui=none", "--no-save", "--silent", "--vanilla", "--slave", "--no-readline"}; int R_argc = sizeof(R_argv) / sizeof(R_argv[0]); if (interactive_m) R_argc--; //Deleting the --no-readline option in interactive mode Rf_initEmbeddedR(R_argc, (char**)R_argv); #ifndef _WIN32 R_CStackLimit = -1; // Don't do any stack checking, see R Exts, '8.1.5 Threading issues' #endif R_ReplDLLinit(); // this is to populate the repl console buffers structRstart Rst; R_DefParams(&Rst); Rst.R_Interactive = (Rboolean) interactive_m; // sets interactive() to eval to false #ifdef _WIN32 char *temp = getenv("R_HOME"); // which is set above as part of R_VARS strncpy(rHome, temp, MAX_PATH); Rst.rhome = rHome; Rst.home = getRUser(); Rst.CharacterMode = LinkDLL; Rst.ReadConsole = myReadConsole; Rst.WriteConsole = myWriteConsole; Rst.CallBack = myCallBack; Rst.ShowMessage = myAskOk; Rst.YesNoCancel = myAskYesNoCancel; Rst.Busy = myBusy; #endif R_SetParams(&Rst); if (true || loadRcpp) { // we always need Rcpp, so load it anyway // Rf_install is used best by first assigning like this so that symbols get into // the symbol table where they cannot be garbage collected; doing it on the fly // does expose a minuscule risk of garbage collection -- with thanks to Doug Bates // for the explanation and Luke Tierney for the heads-up SEXP suppressMessagesSymbol = Rf_install("suppressMessages"); SEXP requireSymbol = Rf_install("require"); SEXP reqsymlang, langobj; // Protect temporaries as suggested by 'rchk', with thanks to Tomas Kalibera PROTECT(reqsymlang = Rf_lang2(requireSymbol, Rf_mkString("Rcpp"))); PROTECT(langobj = Rf_lang2(suppressMessagesSymbol, reqsymlang)); Rf_eval(langobj, R_GlobalEnv); UNPROTECT(2); } global_env_m = new Rcpp::Environment(); // member variable for access to R's global environment autoloads(); // loads all default packages, using code autogenerate from Makevars{,.win} if ((argc - optind) > 1){ // for argv vector in Global Env */ Rcpp::CharacterVector s_argv( argv+(1+optind), argv+argc ); assign(s_argv, "argv"); } else { assign(R_NilValue, "argv") ; } init_rand(); // for tempfile() to work correctly */ } void RInside::init_tempdir(void) { const char *tmp; // FIXME: if per-session temp directory is used (as R does) then return tmp = getenv("TMPDIR"); if (tmp == NULL) { tmp = getenv("TMP"); if (tmp == NULL) { tmp = getenv("TEMP"); if (tmp == NULL) tmp = "/tmp"; } } R_TempDir = (char*) tmp; if (setenv("R_SESSION_TMPDIR",tmp,1) != 0){ throw std::runtime_error(std::string("Could not set / replace R_SESSION_TMPDIR to ") + std::string(tmp)); } } void RInside::init_rand(void) { // code borrows from R's TimeToSeed() in datetime.c unsigned int pid = getpid(); struct timeval tv; // this is ifdef'ed by R, we just assume we have it gettimeofday (&tv, NULL); // we could borrow autoconf setup from littler to ensure unsigned int seed = (unsigned int)(((uint_least64_t) tv.tv_usec << 16) ^ tv.tv_sec); seed ^= (pid << 16); // R 2.14.0 started to also use pid to support parallel srand(seed); } void RInside::autoloads() { #include "RInsideAutoloads.h" // Autoload default packages and names from autoloads.h // // This function behaves in almost every way like // R's autoload: // function (name, package, reset = FALSE, ...) // { // if (!reset && exists(name, envir = .GlobalEnv, inherits = FALSE)) // stop("an object with that name already exists") // m <- match.call() // m[[1]] <- as.name("list") // newcall <- eval(m, parent.frame()) // newcall <- as.call(c(as.name("autoloader"), newcall)) // newcall$reset <- NULL // if (is.na(match(package, .Autoloaded))) // assign(".Autoloaded", c(package, .Autoloaded), env = .AutoloadEnv) // do.call("delayedAssign", list(name, newcall, .GlobalEnv, // .AutoloadEnv)) // invisible() // } // // What's missing is the updating of the string vector .Autoloaded with // the list of packages, which by my code analysis is useless and only // for informational purposes. // // // we build the call : // // delayedAssign( NAME, // autoloader( name = NAME, package = PACKAGE), // .GlobalEnv, // .AutoloadEnv ) // // where : // - PACKAGE is updated in a loop // - NAME is updated in a loop // // int i,j, idx=0, nobj ; Rcpp::Language delayed_assign_call(Rcpp::Function("delayedAssign"), R_NilValue, // arg1: assigned in loop R_NilValue, // arg2: assigned in loop *global_env_m, global_env_m->find(".AutoloadEnv") ); Rcpp::Language::Proxy delayed_assign_name = delayed_assign_call[1]; Rcpp::Language autoloader_call(Rcpp::Function("autoloader"), Rcpp::Named( "name", R_NilValue) , // arg1 : assigned in loop Rcpp::Named( "package", R_NilValue) // arg2 : assigned in loop ); Rcpp::Language::Proxy autoloader_name = autoloader_call[1]; Rcpp::Language::Proxy autoloader_pack = autoloader_call[2]; delayed_assign_call[2] = autoloader_call; try { for( i=0; i 1 for(i = 0; i < Rf_length(cmdexpr); i++){ ans = R_tryEval(VECTOR_ELT(cmdexpr, i), *global_env_m, &errorOccurred); if (errorOccurred) { if (verbose_m) Rf_warning("%s: Error in evaluating R code (%d)\n", programName, status); UNPROTECT(2); mb_m.rewind(); return 1; } if (verbose_m) { Rf_PrintValue(ans); } } mb_m.rewind(); break; case PARSE_INCOMPLETE: // need to read another line break; case PARSE_NULL: if (verbose_m) Rf_warning("%s: ParseStatus is null (%d)\n", programName, status); UNPROTECT(2); mb_m.rewind(); return 1; break; case PARSE_ERROR: if (verbose_m) Rf_warning("Parse Error: \"%s\"\n", line.c_str()); UNPROTECT(2); mb_m.rewind(); return 1; break; case PARSE_EOF: if (verbose_m) Rf_warning("%s: ParseStatus is eof (%d)\n", programName, status); break; default: if (verbose_m) Rf_warning("%s: ParseStatus is not documented %d\n", programName, status); UNPROTECT(2); mb_m.rewind(); return 1; break; } UNPROTECT(2); return 0; } void RInside::parseEvalQ(const std::string & line) { SEXP ans; int rc = parseEval(line, ans); if (rc != 0) { throw std::runtime_error(std::string("Error evaluating: ") + line); } } void RInside::parseEvalQNT(const std::string & line) { SEXP ans; parseEval(line, ans); } RInside::Proxy RInside::parseEval(const std::string & line) { SEXP ans; int rc = parseEval(line, ans); if (rc != 0) { throw std::runtime_error(std::string("Error evaluating: ") + line); } return Proxy( ans ); } RInside::Proxy RInside::parseEvalNT(const std::string & line) { SEXP ans; parseEval(line, ans); return Proxy( ans ); } Rcpp::Environment::Binding RInside::operator[]( const std::string& name ){ return (*global_env_m)[name]; } RInside& RInside::instance(){ return *instance_m; } RInside* RInside::instancePtr(){ return instance_m; } extern "C" { void run_Rmainloop(void); } void RInside::repl() { run_Rmainloop(); // Causes problems under Windows. // For example, terminates after plot(0,0) // R_ReplDLLinit(); // while (R_ReplDLLdo1() > 0) {} } /* callbacks */ #ifdef RINSIDE_CALLBACKS void Callbacks::Busy_( int which ){ R_is_busy = static_cast( which ) ; Busy( R_is_busy ) ; } int Callbacks::ReadConsole_( const char* prompt, unsigned char* buf, int len, int addtohistory ){ try { std::string res( ReadConsole( prompt, static_cast(addtohistory) ) ) ; /* At some point we need to figure out what to do if the result is * longer than "len"... For now, just truncate. */ int l = res.size() ; int last = (l>len-1)?len-1:l ; strncpy( (char*)buf, res.c_str(), last ) ; buf[last] = 0 ; return 1 ; } catch( const std::exception& ex){ return -1 ; } } void Callbacks::WriteConsole_( const char* buf, int len, int oType ){ if( len ){ buffer.assign( buf, len ) ; WriteConsole( buffer, oType) ; } } void RInside_ShowMessage( const char* message ){ RInside::instance().callbacks->ShowMessage( message ) ; } void RInside_WriteConsoleEx( const char* message, int len, int oType ){ RInside::instance().callbacks->WriteConsole_( message, len, oType ) ; } int RInside_ReadConsole(const char *prompt, unsigned char *buf, int len, int addtohistory){ return RInside::instance().callbacks->ReadConsole_( prompt, buf, len, addtohistory ) ; } void RInside_ResetConsole(){ RInside::instance().callbacks->ResetConsole() ; } void RInside_FlushConsole(){ RInside::instance().callbacks->FlushConsole() ; } void RInside_ClearerrConsole(){ RInside::instance().callbacks->CleanerrConsole() ; } void RInside_Busy( int which ){ RInside::instance().callbacks->Busy_(which) ; } void RInside::set_callbacks(Callbacks* callbacks_){ callbacks = callbacks_ ; #ifdef _WIN32 // do something to tell user that he doesn't get this #else /* short circuit the callback function pointers */ if( callbacks->has_ShowMessage() ){ ptr_R_ShowMessage = RInside_ShowMessage ; } if( callbacks->has_ReadConsole() ){ ptr_R_ReadConsole = RInside_ReadConsole; } if( callbacks->has_WriteConsole() ){ ptr_R_WriteConsoleEx = RInside_WriteConsoleEx ; ptr_R_WriteConsole = NULL; } if( callbacks->has_ResetConsole() ){ ptr_R_ResetConsole = RInside_ResetConsole; } if( callbacks->has_FlushConsole() ){ ptr_R_FlushConsole = RInside_FlushConsole; } if( callbacks->has_CleanerrConsole() ){ ptr_R_ClearerrConsole = RInside_ClearerrConsole; } if( callbacks->has_Busy() ){ ptr_R_Busy = RInside_Busy; } R_Outputfile = NULL; R_Consolefile = NULL; #endif } #endif RInside/src/RInside_C.cpp0000644000176200001440000000267213632026647014721 0ustar liggesusers // RInside_C.cpp: R/C++ interface class library -- Easier R embedding into C // // Copyright (C) 2020 - Lance Bachmeier and Dirk Eddelbuettel // // This file is part of RInside. // // RInside 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. // // RInside 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 RInside. If not, see . #include RInside *rr = NULL; extern "C" { void setupRinC() { if (rr == NULL) rr = new RInside; } void passToR(SEXP x, char * name) { if (rr != NULL) rr->assign(x, std::string(name)); } SEXP evalInR(char * cmd) { if (rr != NULL) return rr->parseEval(std::string(cmd)); else return R_NilValue; } void evalQuietlyInR(char * cmd) { if (rr != NULL) rr->parseEvalQ(std::string(cmd)); } void teardownRinC() { if (rr != NULL) { delete rr; rr = NULL; } } } RInside/ChangeLog0000644000176200001440000007677215002010337013373 0ustar liggesusers2025-04-22 Dirk Eddelbuettel * DESCRIPTION (Version, Date): Release 0.2.19 2025-04-08 Dirk Eddelbuettel * src/tools/RInsideEnvVars.r: Allow double quotes in env.var 2025-03-19 Dirk Eddelbuettel * inst/examples/sandboxed_server/example_server.cpp: Remove obsolete test for C++11 use in server * inst/examples/standard/rinside_sample17.cpp: Idem, dos2unix'ed 2024-10-28 Dirk Eddelbuettel * DESCRIPTION (Authors@R): Added 2024-05-24 Dirk Eddelbuettel * README.md: Use tinyverse.netlify.app for dependency badge 2024-04-23 Dirk Eddelbuettel * .github/workflows/ci.yaml (jobs): Update to actions/checkout@v4, add r-ci-setup actions 2023-09-17 Dirk Eddelbuettel * inst/examples/sandboxed_server/README.md: Add README noting need to rebuild RInside with `RINSIDE_CALLBACKS` defined 2023-03-16 Dirk Eddelbuettel * DESCRIPTION (Version, Date): Roll minor version 2023-03-14 Joris Goosen * inst/examples/qt/cmake/CMakeLists.txt: Refine qt6 change * inst/examples/qt/README: Idem 2023-03-13 Joris Goosen * inst/examples/qt/qtdensity.cpp: Update to qt6 * inst/examples/qt/cmake/CMakeLists.txt: Idem * inst/examples/qt/README: Idem 2023-02-01 Dirk Eddelbuettel * DESCRIPTION (Version, Date): Release 0.2.18 * src/Makevars ($(USERLIB)): Use relative file location in install_name_tool call, additional checks for when to call * README.md: Update several URLs to https:// 2023-01-31 Dominick Samperi * src/RInside.cpp: Switch to run_Rmainloop() 2022-11-29 Dirk Eddelbuettel * .github/workflows/ci.yaml (jobs): Update to actions/checkout@v3 2022-04-03 Dirk Eddelbuettel * src/RInside.cpp (init_rand): Minor update inspired from the corresponding code in R 4.1.0 * inst/include/RInsideCommon.h: Include stdint.h 2022-03-31 Dirk Eddelbuettel * DESCRIPTION (Version, Date): Release 0.2.17 * README.md: Four more URLs were updated 2022-03-30 Dirk Eddelbuettel * src/RInside.cpp (myReadConsole): Windows-only patch provided by Tomas Kalibera for upcoming R 4.2.0, adjusted for R (>= 4.2.0) too 2021-12-23 Dirk Eddelbuettel * README.md: Remove unused continuous integration artifact and badge 2021-10-15 Dirk Eddelbuettel * DESCRIPTION (Version, Date): Roll minor version 2021-05-27 Dirk Eddelbuettel * DESCRIPTION (URL): Add github repo URL to DESCRIPTION 2021-01-17 Dirk Eddelbuettel * .github/workflows/ci.yaml: Add CI runner using r-ci * README.md: Add new badge 2020-12-03 Dirk Eddelbuettel * .travis.yml: Switch to r-ci using focal and bspm * inst/examples/standard/GNUmakefile: Whitespace changes 2020-08-16 Dirk Eddelbuettel * README.md: Add a 'last commit' badge 2020-03-12 Dirk Eddelbuettel * DESCRIPTION (Version, Date): Release 0.2.16 2020-03-11 Dirk Eddelbuettel * README.md: Small edits, added Debian badge 2020-03-10 Dirk Eddelbuettel * DESCRIPTION (Version, Date): Roll minor version * DESCRIPTION (Author): Add Lance * DESCRIPTION (Description): Update Description [ all based on an initial contribution by Lance Bachmeier ] * src/RInside_C.cpp: New C-only embedding with five simple functions * inst/include/RInside_C.h: Interface to new C-only embedding * R/RInsidePaths.R (RInsideCFlags,CFlags): C flags * inst/examples/c_interface/: New example directory * .editorconfig: Added for standard editor behaviour 2019-12-18 Dirk Eddelbuettel * src/tools/RInsideEnvVars.r: Add R_SESSION_INITIALIZED to excluded variables 2019-03-06 Dirk Eddelbuettel * DESCRIPTION (Version, Date): Release 0.2.15 2019-03-05 Dirk Eddelbuettel * DESCRIPTION (Version, Date): New minor version * src/RInside.cpp (initialize): Rewritten to use two (protected) temporary variable to avoid any chance of allocation races [rchk] * DESCRIPTION (Description): Edited linebreaks and wording 2018-12-26 Zé Vinícius * README.md: Correct typo in URL for Qt example 2018-09-02 Dirk Eddelbuettel * .travis.yml: Minor update to commented-out PPA for R 3.5 2018-06-14 François-David Collin * src/Makevars.win: Quote-protect path for Rscript 2017-08-17 Jonathon Love * src/setenv/setenv.c: Extend backslash handling on Windows 2017-08-16 Jonathon Love * src/RInside.cpp: On Windows, copy getenv("R_HOME") result 2017-04-28 Dirk Eddelbuettel * DESCRIPTION (Version): Release 0.2.14 2017-04-27 Dirk Eddelbuettel * .travis.yml: Switch to using run.sh for Travis CI * inst/include/RInsideCommon.h (HAVE_UINTPTR_T): Protect behind #ifndef 2017-02-10 Dirk Eddelbuettel * DESCRIPTION (Version, Date): Roll minor version * README.md: Use canonical URLs * inst/NEWS.Rd: Updated to use \CRANpkg{} * cleanup: Call GNUmakefile in examples directories too 2017-02-08 Łukasz Łaniewski-Wołłk * src/RInside.cpp (initialize): In interactive mode, allow use of readline * inst/examples/standard/rinside_interactive0.cpp: New example of a planetary motion solver with console for parameter override 2017-02-08 Dirk Eddelbuettel * inst/include/RInside.h (R): Move repl() declaration outside #ifdef * src/RInside.cpp (repl): Ditto for definition 2016-02-11 Kevin Ushey * src/RInside.cpp: Check for _WIN32 instead of WIN32 2016-02-08 Dirk Eddelbuettel * inst/examples/wt/GNUmakefile: Add -lboost_system 2016-02-07 Mattias Ellert * src/Makevars: Also use LDFLAGS * src/tools/RInsideEnvVars.r: Exclude three more variables containing the build path 2015-05-20 Dirk Eddelbuettel * DESCRIPTION: Release 0.2.13 2015-05-16 Dirk Eddelbuettel * .travis.yml (install): Use ppa for r-cran-rcpp in .travis.yml 2015-05-15 Dirk Eddelbuettel * inst/include/RInsideCommon.h: Do not include RInterface.h here as the file gets included from several source files * src/RInside.cpp: But rather include RInterface.h here just once 2015-01-27 Dirk Eddelbuettel * DESCRIPTION: Release 0.2.12 2015-01-08 Dirk Eddelbuettel * DESCRIPTION (Description): Updated Description: to note that we now have eight examples subdirectories, and that (all but one of) these example directories use Makefiles with GNU make extensions, which have therefore been renamed to GNUmakefile to please R CMD check * DESCRIPTIION (Version): Bumped Version: and Date: * inst/examples/armadillo/GNUmakefile: Renamed from Makefile * inst/examples/eigen/GNUmakefile: Ditto * inst/examples/mpi/GNUmakefile: Ditto * inst/examples/sandboxed_server/GNUmakefile: Ditto * inst/examples/standard/GNUmakefile: Ditto * inst/examples/threads/GNUmakefile: Ditto * inst/examples/wt/GNUmakefile: Ditto 2014-11-25 Christian Authmann * inst/examples/sandboxed_server/: New example of a 'sandboxed' server for safer communication [of a subset of types] out of process 2014-10-10 Christian Authmann * inst/examples/standard/rinside_sample16.cpp: New example demonstrating object wrapping and exposing C++ functions * inst/examples/standard/rinside_sample17.cpp: New example demonstrating the same using C++11 features 2014-09-08 Dirk Eddelbuettel * src/RInside.cpp (WriteConsole_): Applied correction by Christian Authmann in GitHub PR #5 * inst/examples/standard/rinside_callbacks1.cpp: New example also supplied by Christian Authmann in PR #5 2014-07-28 Dirk Eddelbuettel * inst/examples/standard/rinside_module_sample0.cpp: Commented-out two short segments in already-disabled file which remains defunct 2014-07-08 Dirk Eddelbuettel * inst/examples/standard/rinside_module_sample9.cpp: Repaired following the fix to Rcpp's InternalFunction 2014-06-24 Dirk Eddelbuettel * inst/examples/standard/rinside_sample15.cpp (main): New example showing how to create a lattice plot, in response to a SO question 2014-03-24 Dirk Eddelbuettel * src/Makevars (PKG_CPPFLAGS): Use '=' instead of '+=' 2014-02-11 Dirk Eddelbuettel * DESCRIPTION: Release 0.2.11 * inst/examples/*/Makefile: Note that Rcpp (>= 0.11.0) no longer requires the RCPPLIBS variable * doxyfile (STRIP_FROM_PATH): Update for git repo 2014-02-10 Dirk Eddelbuettel * DESCRIPTION: Move Rcpp (>= 0.11.0) from Depends: to Imports: * NAMESPACE: Added importFrom(Rcpp, evalCpp) * .Rbuildignore: Added .travis.yml and doxyfile * src/RInside.cpp: Added --vanilla --slave to default arguments * src/Makefile: PKG_LIBS no longer points to Rcpp's library * inst/examples/standard/Makefile: Note that Rcpp (>= 0.11.0) no longer requires the RCPPLIBS variable * inst/examples/standard/rinside_test0.cpp: Minor tweaks * inst/examples/standard/rinside_sample9.cpp: In this already-disabled example, comment out a data structure no longer provided by Rcpp 2014-02-05 Kevin Ushey * inst/include/RInside.h: Make global_env_m a pointer to avoid the default constructor initializing it before R has actually been called * src/RInside.cpp: ditto 2013-12-27 Dirk Eddelbuettel * .travis.yml: Added 2013-08-11 Dirk Eddelbuettel * inst/examples/qt/qtdensity.h: Added a few more explicit #include statements which Qt 5.1 now appears to require -- with thanks to Spencer Behling for the patch * inst/examples/qt/qtdensity.h: Moved one #include to header file 2013-04-22 Dirk Eddelbuettel * inst/examples/armadillo/rinside_arma0.cpp: Reverse order of includes so that RcppArmadillo.h is included before RInside * inst/examples/armadillo/rinside_arma1.cpp: Idem 2013-02-12 Dirk Eddelbuettel * inst/include/RInside.h: Set default value of loadRcpp to true * src/RInside.cpp: Assign R's global env. only after R has been loaded, also load Rcpp unconditionally 2013-01-23 Dirk Eddelbuettel * inst/examples/mpi/rinside_mpi_sample4.cpp: Added new example contributed by Nicholas Pezolano and Martin Morgan 2012-12-05 Dirk Eddelbuettel * DESCRIPTION: Release 0.2.10 * src/RInside.cpp: Set R_CStackLimit to -1 to block stack checking, place assignment after initialization of embedded R instance (on all platforms but Windows which does not have R_CStackLimit) * inst/include/RInsideCommon.h: Updated to ensure R_CStackLimit is defined, added a few more #include statements here * inst/examples/threads/boostEx.cpp: New example directory for simple multi-threaded use demo building on a simple Boost mutex example * cleanup: Also clean new example directory threads/ * doxyfile: Added new example directory threads/ * inst/examples/qt/qtdensity.pro: Corrected link order statement permitting use of example on Windows as well as Linux / OS X * inst/examples/standard/rinside_sample9.cpp: Disabled as passing external C/C++ function through simplified interface currently borked * inst/examples/standard/rinside_module_sample0.cpp: Idem 2012-11-08 Dirk Eddelbuettel * inst/examples/standard/rinside_sample11.cpp: added include for unistd so that unlink() is declared as needed for g++ (>= 4.7) 2012-11-04 Dirk Eddelbuettel * DESCRIPTION: Release 0.2.9 2012-10-28 Peter Aberline * inst/examples/standard/cmake/CMakeLists.txt: R_ARCH autodetection * inst/examples/armadillo/cmake/CMakeLists.txt: Dito * inst/examples/eigen/cmake/CMakeLists.txt: Dito * inst/examples/armadillo/cmake/WIN.readme.txt: Added instructions for running windows binaries. * inst/examples/eigen/cmake/WIN.readme.txt: Dito 2012-10-15 Dirk Eddelbuettel * inst/include/RInside.h: Added two new boolean arguments to constructor to set verbose and/or interactive mode; verbose mode can also be changed via a setter function. * src/RInside.cpp: Corresponding implementation * inst/examples/standard/rinside_sample13.cpp: New example illustrating the new more fault-tolerant modes * inst/examples/standard/rinside_sample14.cpp: New example illustrating the new more fault-tolerant modes with interactive mode 2012-10-11 Dirk Eddelbuettel * inst/include/RInside.h: Added non-throwing variants of parseEval() and parseEvalQ() (which add 'NT' to the function name) * src/RInside.cpp: Implementation of non-throwing parseEval() variants * inst/examples/qt/qtdensity.cpp: Made more tolerant of bad user input by evaluating via non-calling function, and assigning to a temporary variable first. * inst/examples/wt/wtdensity.cpp: Dito 2012-10-10 Dirk Eddelbuettel * src/RInside.cpp: Applied (modified) patch by Theodore Lytras which lets us recover from parsing errors on erroneous input lines 2012-10-05 Dirk Eddelbuettel * inst/examples/standard/rinside_test2.cpp: Simple new test to check the search path 2012-09-15 Dirk Eddelbuettel * src/RInside.cpp (initialize): On Windows, if R_HOME is not set as an environment variable, use R's get_R_HOME() to get it from registry 2012-09-13 Dirk Eddelbuettel * inst/examples/standard/Makefile.win: Added more explicit statement about the need to set R_HOME on Windows to run the binaries, or to install RInside from sources on Windows so that R_HOME is set that way 2012-09-07 Dirk Eddelbuettel * DESCRIPTION: Release 0.2.8 2012-09-06 Dirk Eddelbuettel * src/RInside.cpp: Include local headers from src/ * src/Makevars{.win}: Declare explicit dependency on headers for RInside.cpp 2012-09-05 Dirk Eddelbuettel * src/Makevars: Updating required headers here now * src/Makevars.win: Updating required headers here now * configure: Deprecated, no longer used or installed * configure.win: Deprecated, no longer used or installed * inst/examples/standard/Makefile.win: R_ARCH autodetection 2012-09-04 Dirk Eddelbuettel * src/Makevars.win: Ensure static library is copied to target on both architectures 2012-08-19 Dirk Eddelbuettel * inst/examples/eigen/cmake/CMakeLists.txt: Added a second patch by Peter to support compilation on Windows * inst/examples/armadillo/cmake/CMakeLists.txt: idem 2012-08-13 Dirk Eddelbuettel * inst/examples/eigen/cmake/CMakeLists.txt: Added Peter's patch * inst/examples/armadillo/cmake/CMakeLists.txt: idem 2012-08-12 Dirk Eddelbuettel * DESCRIPTION: Release 0.2.7 * inst/examples/eigen/: New example directory for Eigen * inst/examples/eigen/rinside_eigen0.cpp: simple first example * inst/examples/eigen/rinside_eigen1.cpp: second example 2012-08-10 Dirk Eddelbuettel * inst/examples/armadillo/: New example directory for Armadillo * inst/examples/armadillo/rinside_arma0.cpp: simple first example * inst/examples/armadillo/rinside_arma1.cpp: second example 2012-04-08 Dirk Eddelbuettel * inst/examples/standard/rinside_sample12.cpp: New example 2012-03-30 Dirk Eddelbuettel * inst/examples/wt/wtdensity.cpp: Extended / prettyfied Wt example to use CSS styling as well as some simple headers and descriptions * inst/examples/wt/wtdensity.css: Added simple CSS markup * inst/examples/wt/wtdensity.xml: Added text and headers * inst/examples/wt/wtdensityPlain.cpp: Renamed old version 2012-01-18 Dirk Eddelbuettel * DESCRIPTION: Added BugReports: and MailingList: fields 2012-01-15 Dirk Eddelbuettel * inst/examples/standard/cmake/CMakeLists.txt: Added patch by Peter which adds CMake build support on Windows 2012-01-11 Dirk Eddelbuettel * DESCRIPTION: Release 0.2.6 * DESCRIPTION: Updated Description: text 2012-01-08 Dirk Eddelbuettel * src/RInside.cpp: Correct console writer on Windows to not use Rprintf (with thanks to both James Bates and John Brzustowski) * src/RInside.cpp: Update RNG seeding to same scheme now used by R which blends both (millisecond) time and process id * src/RInside.cpp: Replace fprintf(stderr,...) with Rf_error(...) * src/setenv/setenv.c: Idem * inst/examples/*: Added CMake build support for all example directories kindly provided by Peter Aberline; this helps when coding inside of IDEs such as Eclipse, KDevelop or Code::Blocks * inst/examples/standard/Makefile.win: Allow for an R_ARCH variable to be set to enforce either i386 or x64 builds 2011-12-06 Dirk Eddelbuettel * DESCRIPTION: Release 0.2.5 * src/RInside.cpp: Applied (a slightly simpler versions of) a patch by James Bates which restores RInside on Windows -- at long last! * inst/include/RInsideCommon.h: Define #Win32 in #WIN32 is set so that we get some symbols from Rembedded.h * inst/THANKS: Add James Bates for help with RInside on Windows * doxyfile: Add inst/examples/wt to example path * cleanup: Some fixes ensuring qt and wt example can be cleaned * .Rbuildignore: Add some local files from qt and wt examples 2011-12-04 Dirk Eddelbuettel * inst/examples/wt/wtdensity.cpp: bandwidth value capped at 200 like qt * inst/examples/qt/qtdensity.cpp: Default to svg creation via the svg() now in base R, ie remove both the test for cairoDevice and the fallback use of png graphics code; we still need to filter the svg file * inst/examples/qt/qtdensity.h: adjust accordingly * cleanup: Clean qt and wt example directories too 2011-11-24 Dirk Eddelbuettel * inst/examples/wt: New example directory 'wt' providing a Webtoolkit (aka 'witty') based density slider application * inst/examples/wt/wtdensity.cpp: Application in less than 200 lines * inst/examples/wt/Makefile: Makefile to build and launch (on Ubuntu) 2011-11-20 Dirk Eddelbuettel * inst/examples/qt/qtdensity.pro: Use QMAKE_LIBS, not QMAKE_LFLAGS 2011-04-24 Dirk Eddelbuettel * DESCRIPTION: Release 0.2.4 * doxyfile: Updated path settings 2011-04-20 Dirk Eddelbuettel * inst/examples/mpi/*cpp: Minor updates and simplifications 2011-04-19 Dirk Eddelbuettel * DESCRIPTION: Updated Description, also state current Windows run-time issue more prominently * inst/examples/standard/rinside_sample1.cpp: Minor simplification * inst/examples/standard/rinside_sample2.cpp: Idem * inst/examples/standard/rinside_sample3.cpp: Idem * inst/examples/standard/rinside_sample5.cpp: Idem * inst/examples/standard/rinside_sample7.cpp: Idem 2011-04-16 Dirk Eddelbuettel * inst/NEWS: Added, at long last, with backfills based on the ChangeLog and blog postings * R/RInsidePaths.R (RInsideCxxFlags): Do not use quotes around path 2011-04-03 Dirk Eddelbuettel * inst/examples/qt/: Moved merged SVN+PNG files back into top-level * inst/examples/qt/qtdensitySVG/qtdensity.pro: No longer need to set -Wno-unused-parameter as Rcpp 0.9.3 has a fix 2011-04-01 Dirk Eddelbuettel * inst/examples/qt/qtdensitySVG/qtdensity.cpp: Merged the PNG and SVG version by using a boolean based on whether cairoDevice loaded or not 2011-03-25 Dirk Eddelbuettel * inst/examples/qt/: Split qtdensity example into default (png) and svg variants as svg needs cairoDevice and has a clipping bug 2011-03-16 Dirk Eddelbuettel * inst/examples/qt/qtdensity.h: Small rearrangements and simplifications 2011-03-15 Dirk Eddelbuettel * inst/examples/qt/*: Added new example combining RInside with Qt illustrating the standard 'slider to select bandwidth for density estimate' example found in demo(tkdensity) and other places 2011-03-06 Dirk Eddelbuettel * inst/examples/standard/rinside_sample11.cpp: New example in response to r-help question by Paul Smith 2011-02-17 Dirk Eddelbuettel * inst/examples/standard/rinside_sample6.cpp: Updated to direct `R["a"] = a;' assignments 2011-01-26 Dirk Eddelbuettel * inst/examples/standard/rinside_sample10.cpp: New example in response to r-devel question by Wayne Zhang 2011-01-20 Dirk Eddelbuettel * src/RInside.cpp (initialize): Assign results of Rf_install to avoid any risk of garbage collection -- with thanks to Doug and Luke 2010-12-26 Dirk Eddelbuettel * src/RInside.cpp (initialize): If Rcpp is requested, load it explicitly before we call autoload() for all R default packages (with thanks to Murray Stokely for the patch) * Changelog: Moved up from inst/ for easier C-x 4 a use 2010-08-06 Dirk Eddelbuettel * Release 0.2.3 * src/Makevars: Set emacs header for Makefile mode * src/Makevars.win: Set emacs header for Makefile mode 2010-07-09 Dirk Eddelbuettel * inst/include/RInside.h: New argument to constructor to select loading of Rcpp * src/RInside.cpp: Idem, also load Rcpp more quietly 2010-07-05 Dirk Eddelbuettel * inst/examples/standard/rinside_sample3.rcpp: Simpler with new Rcpp API * inst/examples/standard/rinside_sample4.rcpp: Idem 2010-06-16 Romain Francois * inst/examples/standard/rinside_sample9.cpp: new example illustrating how to expose a C++ function to the embedded R * inst/examples/standard/rinside_module_sample0.cpp: new example illustrating how to use an Rcpp module from RInside * inst/include/*.h: moved the headers to include so that there is only one copy * inst/include/MemBuf.h: change from signature of add to use const std::string& instead of const char* * src/RInside.cpp: loading the Rcpp package 2010-04-21 Dirk Eddelbuettel * src/MemBuf.cpp: Added #include so that even Solaris sees strlen() -- with thanks to Brian Ripley * src/Makefile: Remove -Wall option which Solaris cc does not support -- with thanks to Brian Ripley 2010-04-05 Dirk Eddelbuettel * src/RInside.cpp: Add #ifdef to Callback code to break on Windows 2010-03-26 Romain Francois * src/RInside.h: the Proxy class is moved inside RInside and parseEval now returns a Proxy so that the proxy class does its job implicitely * inst/examples/standard/rinside_sample8.cpp: simplify the example to implicit use of the Proxy class 2010-03-25 Dirk Eddelbuettel * src/RInside.h: New Proxy class with operator T() to borrow Rcpp's automatic wrappers * inst/examples/standard/rinside_sample8.cpp: Use Proxy() 2010-03-22 Dirk Eddelbuettel * DESCRIPTION: Increase Version: to 0.2.2 * .Rbuildignore: Added to exclude volatile Doxygen-generated docs from tarball, zip-archives will be made available as for Rcpp 2010-03-20 Dirk Eddelbuettel * R/RInsidePaths.R: Updated to current version of Rcpp's file (minus the cxx0x bits) in order to standardize linking options, with this we now default to static linking on OS X and Windows as Rcpp does. * src/RInside.cpp: Use explicit std::string() constructors for all text arguments inside throw() calls (to satisfy the Windows compiler) 2010-03-16 Dirk Eddelbuettel * src/RInside.{h,cpp}: parseEval* function changed slightly so that SEXP parseEval(string) is now preferred, and it as well as void parseEvalQ(string) now throw exceptions; they call the non-throwing older int parseEval(string, SEXP). We changed the parseEvalQ from int to void which is more in-line with it purpose. * inst/examples/standard/rinside_sample{2,4,5}.cpp: Adapted accordingly, mostly by removing no-longer-needed error checking and exepction throw which has now move 'up' into RInside.cpp 2010-02-25 Dirk Eddelbuettel * inst/examples/mpi/: Added two variants using the C++ API to MPI 2010-02-23 Dirk Eddelbuettel * src/RInside.cpp: Add new parseEval() member function returning a SEXP * src/RInside.h: idem * src/inst/examples/standard/rinside_sample8.cpp: Show new parseEval() 2010-02-17 Dirk Eddelbuettel * inst/examples/mpi/: Add examples contributed by Jianping Hua * inst/examples/: Update two existing examples to new Rcpp API 2010-02-12 Romain Francois * src/MemBuf.h: MemBuf simplified using std::string * src/RInside.h: RInside gains an operator[](string) to allow treating the RInside instance as a proxy to the global environment so that we can do: RInside R; R["x"] = 10 ; All the actual work is done by the Rcpp::Environment class 2010-02-04 Romain Francois * RInside::autoloads revisited with the new Rcpp api * RInside gains a default constructor to be used when there is no command line arguments 2010-01-28 Romain Francois * src/RInside.{h,cpp}: Retire assign(vector> ) because now this can be taken care of by template specialization * DESCRIPTION: require Rcpp 0.7.3.6 2010-01-28 Dirk Eddelbuettel * src/RInside.{h,cpp}: Restore assign(vector>) which is not (yet?) covered by the more general templated solution * src/RInside.h: Minor cleanup regarding logTxt usage * src/Makefile: Make sure we find Rcpp.h headers 2010-01-27 Romain Francois * src/RInside.{h,cpp}: include Rcpp.h and use the Rf_ prefixed R API functions. stop using macros from Rdefines because they don't work with R_NOREMAP * src/RInside.{h,cpp}: using the new Rcpp API assign becomes a template and let Rcpp::Environment.assign deal with the type of the object and how to wrap it. specializations of wrap for vector> and vector> are created to maintain original interface. 2010-01-06 Dirk Eddelbuettel * DESCRIPTION: Increase Version: to 0.2.1 * src/RInside.cpp: Change startup so that interactive() comes out FALSE, with that no longer call Rf_KillAllDevices(); as we may not have had devices in the first place. * src/RInside.h: Logging helper protected by #ifndef as it is in Rcpp too * tools/unix2dos.r: Simple CRLF -> LF filter to nuke a Windows warning * src/Makefile.win: Employ unix2dos.r on two autogenerated files * DESCRIPTON: Set Depends: to R (>= 2.10.0) and Rcpp (>= 0.7.0) * src/*: Add full copyright headers and update copyright to 2010 2009-12-21 Dirk Eddelbuettel * src/setenv.c: Minor error case fix for Windows * DESCRIPTON: Lower requirement for Rcpp to (>= 0.6.7) 2009-12-20 Dirk Eddelbuettel * DESCRIPTION: Increase Version: to 0.2.0 * src/setenv: Another small cleanup * inst/THANKS: Added Richard for all the initial help with Windows * src/RInside.cpp: Uncommented fpu_setup() for now * inst/doc/{html,man.latex}: Removed autogenerated doxygen files from svn as they are too volatile, will remain in tarball as for Rcpp 2009-12-16 Dirk Eddelbuettel * src/tools/RInsideEnvVars.r: Deal with slashed on Windows platform 2009-12-15 Dirk Eddelbuettel * DESCRIPTION: Remove 'OS_type: unix' as we now build and run on Windoze * src/Makefile.win: src/RInside.h, src/RInside.cpp: Added support for building on Windows using the standard MinGW toolchain * src/setenv.c: Windows implementation of setenv() kindly provided by Richard Holbrey during earlier attempts to build on Windows * inst/examples/Makefile.win: Similarly Makefile for Windows examples 2009-12-12 Dirk Eddelbuettel * src/RInside.cpp: Destructor does a few additional things as per the R_Cleanup example in section 8.1.2 on 'Setting R callbacks' * src/RIinside.h: Added simple logTxt() to log if defined and not otherwise. 2009-10-01 Dirk Eddelbuettel * inst/examples/rinside_sample5.cpp: Another examples based on r-devel post 2009-09-29 Dirk Eddelbuettel * inst/examples/rinside_sample4.cpp: New example based on new r-devel post 2009-09-25 Dirk Eddelbuettel * DESCRIPTION: Increase Version: to 0.1.1 * inst/THANKS: Added new file to say Thank You! to contributors * inst/examples/Makefile: set R_HOME variable to output of 'R RHOME', use R_HOME to call R as R_HOME/bin/R, use R instead of Rscript, query R about CXX and CPPFLAGS, general editing and overhaul * inst/examples/*.cpp: More consistent formatting using Emacs 'M-x untabify' * src/Makefile: Add $R_ARCH to install path for header files (thanks to Jeff), call R with --vanilla switch (thanks to Jan), use R instead of Rscript, general editing and overhaul 2009-09-19 Dirk Eddelbuettel * DESCRIPTION: Increase Version: to 0.1.0, initial CRAN release * DESCRIPTION: Add 'OS_type: unix' to stop builds on Windows * DESCRIPTION: Add 'URL' pointer * doxyfile: Added Doxygen configuration file * inst/doc/: Added Doxygen generated html, latex, man files * inst/examples/Makefile: Also link against BLAS and LAPACK libs * inst/examples/rinside_sample3.cpp: New example using lm() and coef() * inst/examples/rinside_sample2.cpp: Added a try/catch block * src/Makefile: use $(R_HOME)/bin/R as per Kurt's reminder 2009-09-11 Dirk Eddelbuettel * src/Makefile: Enhanced to now automatically regenerate the two R-derived header files, and to also query R for directories which should make the build more portable across different systems * src/MemBuf/cpp: Switch error message from fprintf to std::cerr to avoid unncessary trouble with g++-4.4, with thanks to Michael Kane for the heads-up * R/RInsidePaths.R: Added path helper functions called by Makefiles * NAMESPACE: Added (empty) file so we can call 'path helpers' * inst/examples/Makefile: Rewritten to no longer used fixed path settings but rather query R, Rcpp and RInside 2009-07-28 Dirk Eddelbuettel * inst/examples/rinside_sample2.cpp: Another simple example inspired by a long thread on r-devel 2009-07-28 Dirk Eddelbuettel * src/RInside.cpp: Added patch by Daniel F Schwarz to not set env vars with prior values (to e.g. allow non-standard R_HOME) 2009-07-19 Dirk Eddelbuettel * DESCRIPTION: Release 0.0.2 * src/MemBuf.cpp: Added one-line patch by Miguel Lechón in add() method to correctly re-set pointer---with a bug Thanks! to Miguel * src/RInside.cpp: Added a few more assign() functions for STL vectors of types double, int and string, as well as int matrices * src/RInside.*: Minor cleanups and edits * inst/examples/small_test*.cpp: Added two small examples to illustrate and test the bug reported by Miguel Lechón * inst/examples/Makefile: generalised targets 2009-02-12 Dirk Eddelbuettel * src/: Added new assign() method for strings, added 'quiet' Eval without return; made more function interfaces use references * man/: Added less-than-minimal RInside-package.Rd * inst/rinside_sample0: Added simple Hello World example 2009-02-10 Dirk Eddelbuettel * Initial upload of version '0.0.1' to R-Forge SVN RInside/NAMESPACE0000644000176200001440000000010313632017564013027 0ustar liggesusersuseDynLib("RInside", .registration=TRUE) importFrom(Rcpp, evalCpp) RInside/inst/0000755000176200001440000000000015002010355012553 5ustar liggesusersRInside/inst/include/0000755000176200001440000000000014501315710014204 5ustar liggesusersRInside/inst/include/Callbacks.h0000644000176200001440000000452712257416630016255 0ustar liggesusers// -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 8 -*- // // Callbacks.h: R/C++ interface class library -- Easier R embedding into C++ // // Copyright (C) 2010 Dirk Eddelbuettel and Romain Francois // // This file is part of RInside. // // RInside 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. // // RInside 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 RInside. If not, see . #ifndef RINSIDE_CALLBACKS_H #define RINSIDE_CALLBACKS_H #include #ifdef RINSIDE_CALLBACKS class Callbacks { public: Callbacks() : R_is_busy(false), buffer() {} ; virtual ~Callbacks(){} ; virtual void ShowMessage(const char* message) {} ; virtual void Suicide(const char* message) {}; virtual std::string ReadConsole( const char* prompt, bool addtohistory ) { return ""; }; virtual void WriteConsole( const std::string& line, int type ) {}; virtual void FlushConsole() {}; virtual void ResetConsole() {}; virtual void CleanerrConsole(){} ; virtual void Busy( bool is_busy ) {} ; void Busy_( int which ) ; int ReadConsole_( const char* prompt, unsigned char* buf, int len, int addtohistory ) ; void WriteConsole_( const char* buf, int len, int oType ) ; // TODO: ShowFiles // TODO: ChooseFile // TODO: loadHistory // TODO: SaveHistory virtual bool has_ShowMessage() { return false ; } ; virtual bool has_Suicide() { return false ; } ; virtual bool has_ReadConsole() { return false ; } ; virtual bool has_WriteConsole() { return false ; } ; virtual bool has_ResetConsole() { return false ; } ; virtual bool has_CleanerrConsole() { return false ; } ; virtual bool has_Busy() { return false ; } ; virtual bool has_FlushConsole(){ return false; } ; private: bool R_is_busy ; std::string buffer ; } ; #endif #endif RInside/inst/include/RInsideConfig.h0000644000176200001440000000171714501315710017046 0ustar liggesusers// RInsideConfig.h: R/C++ interface class library -- Easier R embedding into C++ // // Copyright (C) 2010 Dirk Eddelbuettel and Romain Francois // // This file is part of RInside. // // RInside 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. // // RInside 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 RInside. If not, see . #ifndef RINSIDE_RINSIDECONFIG_H #define RINSIDE_RINSIDECONFIG_H // uncomment to turn on the experimental callbacks // #define RINSIDE_CALLBACKS #endif RInside/inst/include/RInside.h0000644000176200001440000000636613047334645015741 0ustar liggesusers// -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 4 -*- // // RInside.h: R/C++ interface class library -- Easier R embedding into C++ // // Copyright (C) 2009 Dirk Eddelbuettel // Copyright (C) 2010 - 2017 Dirk Eddelbuettel and Romain Francois // // This file is part of RInside. // // RInside 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. // // RInside 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 RInside. If not, see . #ifndef RINSIDE_RINSIDE_H #define RINSIDE_RINSIDE_H #include #include class RInside { private: MemBuf mb_m; Rcpp::Environment* global_env_m; bool verbose_m; // switch toggled by constructor, or setter bool interactive_m; // switch set by constructor only void init_tempdir(void); void init_rand(void); void autoloads(void); void initialize(const int argc, const char* const argv[], const bool loadRcpp, const bool verbose, const bool interactive); static RInside* instance_m ; #ifdef RINSIDE_CALLBACKS Callbacks* callbacks ; friend void RInside_ShowMessage( const char* message); friend void RInside_WriteConsoleEx( const char* message, int len, int oType ); friend int RInside_ReadConsole(const char *prompt, unsigned char *buf, int len, int addtohistory); friend void RInside_ResetConsole(); friend void RInside_FlushConsole(); friend void RInside_ClearerrConsole(); friend void RInside_Busy(int which); #endif public: class Proxy { public: Proxy(SEXP xx): x(xx) { }; template operator T() { return ::Rcpp::as(x); } private: Rcpp::RObject x; }; int parseEval(const std::string &line, SEXP &ans); // parse line, return in ans; error code rc void parseEvalQ(const std::string &line); // parse line, no return (throws on error) void parseEvalQNT(const std::string &line); // parse line, no return (no throw) Proxy parseEval(const std::string &line); // parse line, return SEXP (throws on error) Proxy parseEvalNT(const std::string &line); // parse line, return SEXP (no throw) template void assign(const T& object, const std::string& nam) { global_env_m->assign( nam, object ) ; } RInside() ; RInside(const int argc, const char* const argv[], const bool loadRcpp=true, // overridden in code, cannot be set to false const bool verbose=false, const bool interactive=false); ~RInside(); void setVerbose(const bool verbose) { verbose_m = verbose; } Rcpp::Environment::Binding operator[]( const std::string& name ); static RInside& instance(); static RInside* instancePtr(); void repl(); #ifdef RINSIDE_CALLBACKS void set_callbacks(Callbacks* callbacks_) ; #endif }; #endif RInside/inst/include/RInside_C.h0000644000176200001440000000202113632015267016157 0ustar liggesusers // RInside_C.h: R/C++ interface class library -- Easier R embedding into C // // Copyright (C) 2020 - Lance Bachmeier and Dirk Eddelbuettel // // This file is part of RInside. // // RInside 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. // // RInside 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 RInside. If not, see . #include #ifndef RINSIDE_RINSIDE_C_H #define RINSIDE_RINSIDE_C_H void setupRinC(); void passToR(SEXP x, char * name); SEXP evalInR(char * cmd); void evalQuietlyInR(char * cmd); void teardownRinC(); #endif RInside/inst/include/MemBuf.h0000644000176200001440000000230712257416630015543 0ustar liggesusers// -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 8 -*- // // MemBuf.h: R/C++ interface class library -- Easier R embedding into C++ // // Copyright (C) 2009 Dirk Eddelbuettel // Copyright (C) 2010 Dirk Eddelbuettel and Romain Francois // // This file is part of RInside. // // RInside 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. // // RInside 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 RInside. If not, see . class MemBuf { // simple C++-ification of littler's membuf private: std::string buffer ; public: MemBuf(int sizebytes=1024); ~MemBuf(); void resize(); void rewind(); void add(const std::string& ); inline const char* getBufPtr() { return buffer.c_str() ; }; }; RInside/inst/include/RInsideCommon.h0000644000176200001440000000402614222434264017073 0ustar liggesusers // RInsideCommon.h: R/C++ interface class library -- Easier R embedding into C++ // // Copyright (C) 2010 - 2022 Dirk Eddelbuettel and Romain Francois // // This file is part of RInside. // // RInside 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. // // RInside 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 RInside. If not, see . #ifndef RINSIDE_RINSIDECOMMON_H #define RINSIDE_RINSIDECOMMON_H #include #include // gettimeofday() #include // pid_t #include // getpid() #include // uint_least64_t (in init_rand()) #include // intptr_t (one day we use cinttypes from C++11) #include // uint64_t (one day we use cstdint from C++11) #include #include #include #include #ifdef WIN32 #ifndef Win32 // needed for parts of Rembedded.h #define Win32 #endif #endif #ifndef WIN32 // needed to turn-off stack checking, and we already have uintptr_t #define CSTACK_DEFNS #ifndef HAVE_UINTPTR_T #define HAVE_UINTPTR_T #endif #endif #include #include #include // simple logging help inline void logTxtFunction(const char* file, const int line, const char* expression, const bool verbose) { if (verbose) { std::cout << file << ":" << line << " expression: " << expression << std::endl; } } #ifdef logTxt #undef logTxt #endif //#define logTxt(x, b) logTxtFunction(__FILE__, __LINE__, x, b); #define logTxt(x, b) #endif RInside/inst/THANKS0000644000176200001440000000203712276557475013525 0ustar liggesusers Miguel Lechón for finding (and fixing!) a memory-management bug Daniel F Schwarz for a patch to not override pre-set environment variables Michael Kane for testing on RHEL Jan de Leeuw for testing on OS X Jeffrey Horner for finding and fixing an OS X build bug Simon Urbanek for OS X (and general) build tips Richard Holbrey for initial help with the the Windows build Jianping Hua for contributing two MPI-based examples Murray Stokely for a patch regarding timing of Rcpp autoloads James Bates for a patch restoring RInside on Windows John Brzustowski for a correction to the Windows initialization Peter Aberline for contributing CMake support for all examples Theodore Lytras for a patch helping to recover from (some) errors Spencer Behling for a patch getting the Qt example ready for Qt 5.1 Nicholas Pezolano for a new MPI example Martin Morgan for a new MPI example Kevin Ushey for debugging a seg.fault issue post Rcpp 0.11.0 RInside/inst/examples/0000755000176200001440000000000013632015267014407 5ustar liggesusersRInside/inst/examples/threads/0000755000176200001440000000000012453643755016052 5ustar liggesusersRInside/inst/examples/threads/GNUmakefile0000644000176200001440000000330512453643755020125 0ustar liggesusers ## This Makefile is __very__ barebones ## ## It works on Debian/Ubuntu. On other systems, add -I and -L flags as needed. ## comment this out if you need a different version of R, ## and set set R_HOME accordingly as an environment variable R_HOME := $(shell R RHOME) ## include headers and libraries for R RCPPFLAGS := $(shell $(R_HOME)/bin/R CMD config --cppflags) RLDFLAGS := $(shell $(R_HOME)/bin/R CMD config --ldflags) RBLAS := $(shell $(R_HOME)/bin/R CMD config BLAS_LIBS) RLAPACK := $(shell $(R_HOME)/bin/R CMD config LAPACK_LIBS) ## if you need to set an rpath to R itself, also uncomment #RRPATH := -Wl,-rpath,$(R_HOME)/lib ## include headers and libraries for Rcpp interface classes RCPPINCL := $(shell echo 'Rcpp:::CxxFlags()' | $(R_HOME)/bin/R --vanilla --slave) RCPPLIBS := $(shell echo 'Rcpp:::LdFlags()' | $(R_HOME)/bin/R --vanilla --slave) ## include headers and libraries for RInside embedding classes RINSIDEINCL := $(shell echo 'RInside:::CxxFlags()' | $(R_HOME)/bin/R --vanilla --slave) RINSIDELIBS := $(shell echo 'RInside:::LdFlags()' | $(R_HOME)/bin/R --vanilla --slave) ## minimal Boost libs -- works for me on Ubuntu, may need -L switches elsewhere... BOOSTLIBS := -lboost_thread ## compiler etc settings used in default make rules CXX := $(shell $(R_HOME)/bin/R CMD config CXX) CPPFLAGS := -Wall $(shell $(R_HOME)/bin/R CMD config CPPFLAGS) CXXFLAGS := $(RCPPFLAGS) $(RCPPINCL) $(RINSIDEINCL) $(shell $(R_HOME)/bin/R CMD config CXXFLAGS) LDLIBS := $(RLDFLAGS) $(RRPATH) $(RBLAS) $(RLAPACK) $(RCPPLIBS) $(RINSIDELIBS) $(BOOSTLIBS) all: boostEx boostEx: boostEx.cpp $(CXX) $(CPPFLAGS) $(CXXFLAGS) -o $@ $^ $(LDLIBS) strip $@ clean: rm -f boostEx RInside/inst/examples/threads/boostEx.cpp0000644000176200001440000000200712257416630020170 0ustar liggesusers// -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; -*- #include #include #include class Resource { public: Resource(): i(0), RR(RInside::instance()) { } void use() { boost::mutex::scoped_lock lock(guard); RR.parseEvalQ("cat(\"Hello, world from use()\\n\")"); ++i; } int getValue() { return i; } private: int i; RInside & RR; // reference to embedded R instance boost::mutex guard; }; void thread_func(Resource& resource) { resource.use(); } extern uintptr_t R_CStackLimit; int main(int argc, char *argv[]) { RInside R(argc, argv); R.parseEvalQ("cat(\"Hello, world from main()\\n\")"); Resource resource; boost::thread_group thread_group; thread_group.create_thread(boost::bind(thread_func, boost::ref(resource))); thread_group.create_thread(boost::bind(thread_func, boost::ref(resource))); thread_group.join_all(); std::cout << "At end value is " << resource.getValue() << std::endl; return 0; } RInside/inst/examples/c_interface/0000755000176200001440000000000014366363660016661 5ustar liggesusersRInside/inst/examples/c_interface/GNUmakefile0000644000176200001440000000124014366363660020730 0ustar liggesusers# Basic R extensions info R_HOME := $(shell R RHOME) RLDFLAGS := $(shell $(R_HOME)/bin/R CMD config --ldflags) # Header files required by Rcpp RCPPFLAGS := $(shell $(R_HOME)/bin/R CMD config --cppflags) # Location of RInsideC.h RINSIDECINCL := $(shell echo 'RInside:::CFlags()' | $(R_HOME)/bin/R --vanilla --slave) # Location of RInsideC library RINSIDECLIBS := $(shell echo 'RInside:::LdFlags()' | $(R_HOME)/bin/R --vanilla --slave) # C compiler CC := $(shell $(R_HOME)/bin/R CMD config CC) FLAGS := $(RLDFLAGS) $(RCPPFLAGS) $(RINSIDECLIBS) $(RINSIDECINCL) hello: $(CC) hello.c $(FLAGS) -o hello ./hello pass: $(CC) passdata.c $(FLAGS) -o passdata ./passdata RInside/inst/examples/c_interface/hello.c0000644000176200001440000000017113632015267020117 0ustar liggesusers#include int main() { setupRinC(); evalQuietlyInR("print('Hello, World')"); teardownRinC(); } RInside/inst/examples/c_interface/passdata.rb0000644000176200001440000000152613632015267021002 0ustar liggesusersrequire 'ffi' module R extend FFI::Library libdir = `Rscript -e \'cat(find.package("RInside"))\'` ffi_lib "#{libdir}/lib/libRInside.so" attach_function :setupRinC, [ ], :void attach_function :evalQuietlyInR, [ :string ], :void attach_function :evalInR, [ :string ], :pointer attach_function :teardownRinC, [ ], :void end module Rlib extend FFI::Library ffi_lib "libR.so" attach_function :Rf_PrintValue, [ :pointer ], :void attach_function :REAL, [ :pointer ], :pointer end #~ Create a variable and set its value in R #~ Pass the SEXP from R to Ruby #~ Call Rf_PrintValue from Ruby R.setupRinC() R.evalQuietlyInR("y <- 4.5") Rlib.Rf_PrintValue(R.evalInR("y")) #~ Obtain a pointer in Ruby to the data array underlying #~ the v created in R R.evalQuietlyInR("v <- c(1.5, 3.4, 4.2)") puts Rlib.REAL(R.evalInR("v")) R.teardownRinC() RInside/inst/examples/c_interface/hello.rb0000644000176200001440000000064313632015267020304 0ustar liggesusers#~ Hello World in Ruby #~ Printing is done by R, not Ruby require 'ffi' module R extend FFI::Library libdir = `Rscript -e \'cat(find.package("RInside"))\'` ffi_lib "#{libdir}/lib/libRInside.so" attach_function :setupRinC, [ ], :void attach_function :evalQuietlyInR, [ :string ], :void attach_function :teardownRinC, [ ], :void end R.setupRinC() R.evalQuietlyInR("print('Hello from R!')") R.teardownRinC() RInside/inst/examples/c_interface/passdata.c0000644000176200001440000000051113632015267020612 0ustar liggesusers#include int main() { setupRinC(); evalQuietlyInR("y <- 3"); evalQuietlyInR("z <- 2.5"); evalQuietlyInR("print(y*z)"); evalQuietlyInR("y <- rnorm(10)"); evalQuietlyInR("print(y)"); SEXP vec = evalInR("y"); Rf_PrintValue(vec); printf("%f\n", REAL(vec)[4]); teardownRinC(); } RInside/inst/examples/qt/0000755000176200001440000000000014404743006015030 5ustar liggesusersRInside/inst/examples/qt/README0000644000176200001440000000261614404201404015704 0ustar liggesusers This directory provides a simple example of using RInside with the Qt toolkit---using a SVG renderer. Usage is standard Qt usage, through cmake. To build from commandline try the following from this directory: ``` mkdir build; cd build cmake -S ../cmake -G "Unix Makefiles" make -j ``` On Ubuntu you would need at least the following packages installed: libqt6svgwidgets6 qt6-tools-dev-tools qt6-base-dev r-base-dev libqt6svg6-dev What could be easier on some systems, depending on how Qt was installed, is using Qt Creator. This can be done through "Open Project" and loading "CMakeLists.txt". If you are on macOs and there are errors on "SUBSTRING" needing 4 arguments try starting QtCreator manually from a terminal. If you get similar errors on Windows then perhaps R isn't on the PATH and you might need to add the `bin/x64` folder of R manually. To generate SVG output, this version depends on the cairoDevice package for R which you may need to install. According to its author Michael Lawrence, there are two small issues. The first is that the SVG produced by cairoDevice is a littler richer than the subset which Qt can show. We address this by filtering the file before viewing it. The other is an apparent error in the clipping which we cannot do anything about---Michael considers it a rendering issue. All the help by Michael in getting the svg variant to roll is gratefully acknowledged. RInside/inst/examples/qt/cmake/0000755000176200001440000000000014404201404016077 5ustar liggesusersRInside/inst/examples/qt/cmake/CMakeLists.txt0000644000176200001440000000637114404201404020646 0ustar liggesuserscmake_minimum_required(VERSION 3.21) project(qtdensitydemo) find_package(Qt6 REQUIRED) find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets SvgWidgets) set(CMAKE_VERBOSE_MAKEFILE ON) set(CMAKE_MESSAGE_CONTEXT_SHOW ON) set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_FIND_FRAMEWORK ON) set(CMAKE_INCLUDE_CURRENT_DIR ON) set(CMAKE_VERBOSE_MAKEFILE 0) set(CMAKE_AUTOMOC ON) set(CMAKE_AUTORCC ON) set(CMAKE_AUTOUIC ON) set(QT_USE_QTSVG 1) add_definitions(${QT_DEFINITIONS}) add_definitions(-DQT_DLL) include_directories(${QT_INCLUDE_DIR}) link_directories(${QT_LIBRARY_DIR}) execute_process(COMMAND R RHOME OUTPUT_VARIABLE R_HOME) set(sources ../main.cpp ../qtdensity.cpp) set(headers ../qtdensity.h) set(NUM_TRUNC_CHARS 2) execute_process(COMMAND R CMD config --cppflags OUTPUT_VARIABLE RCPPFLAGS) string(SUBSTRING ${RCPPFLAGS} ${NUM_TRUNC_CHARS} -1 RCPPFLAGS) include_directories(${RCPPFLAGS}) execute_process(COMMAND R CMD config --ldflags OUTPUT_VARIABLE RLDFLAGS) string(LENGTH ${RLDFLAGS} RLDFLAGS_LEN) string(STRIP ${RLDFLAGS} RLDFLAGS) execute_process(COMMAND Rscript -e "Rcpp:::CxxFlags()" OUTPUT_VARIABLE RCPPINCL) string(SUBSTRING ${RCPPINCL} ${NUM_TRUNC_CHARS} -1 RCPPINCL) string(REPLACE "\"" "" RCPPINCL ${RCPPINCL}) #Rcpp::CxxFlags() adds quotes around the include directory, which is friendly and all but breaks include_directories include_directories(${RCPPINCL}) execute_process(COMMAND Rscript -e "Rcpp:::LdFlags()" OUTPUT_VARIABLE RCPPLIBS) if (${RCPPLIBS} MATCHES "[-][L]([^ ;])+") string(SUBSTRING ${CMAKE_MATCH_0} ${NUM_TRUNC_CHARS} -1 RCPPLIBS_L) link_directories(${RCPPLIBS_L} ) endif() if (${RCPPLIBS} MATCHES "[-][l][R]([^;])+") string(SUBSTRING ${CMAKE_MATCH_0} ${NUM_TRUNC_CHARS} -1 RCPPLIBS_l) endif() execute_process(COMMAND Rscript -e "RInside:::CxxFlags()" OUTPUT_VARIABLE RINSIDEINCL) string(SUBSTRING ${RINSIDEINCL} ${NUM_TRUNC_CHARS} -1 RINSIDEINCL) include_directories(${RINSIDEINCL}) execute_process(COMMAND Rscript -e "RInside:::LdFlags()" OUTPUT_VARIABLE RINSIDELIBS) string(STRIP ${RINSIDELIBS} RINSIDELIBS ) string(REPLACE "\"" "" RINSIDELIBS ${RINSIDELIBS}) if (${RINSIDELIBS} MATCHES "[-][L]([^ ;])+") string(SUBSTRING ${CMAKE_MATCH_0} ${NUM_TRUNC_CHARS} -1 RINSIDELIBS_L) link_directories(${RINSIDELIBS_L}) endif() if (${RINSIDELIBS} MATCHES "[-][l][R]([^;])+") string(SUBSTRING ${CMAKE_MATCH_0} ${NUM_TRUNC_CHARS} -1 RINSIDELIBS_l) endif() if (${RINSIDELIBS} MATCHES ".+\.a$") set(RINSIDELIBS_l ${RINSIDELIBS}) endif() execute_process(COMMAND R CMD config CXXFLAGS OUTPUT_VARIABLE RCXXFLAGS) execute_process(COMMAND R CMD config BLAS_LIBS OUTPUT_VARIABLE RBLAS) execute_process(COMMAND R CMD config LAPACK_LIBS OUTPUT_VARIABLE RLAPACK) set(CMAKE_CXX_FLAGS "-W -Wall -pedantic -Wextra ${CMAKE_CXX_FLAGS}") if (CMAKE_BUILD_TYPE STREQUAL "DEBUG" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebugInfo" ) add_definitions("-DDEBUG") elseif ( CMAKE_BUILD_TYPE STREQUAL "RELEASE" ) add_definitions("-O3") endif() qt_add_executable(qtdensitydemo ${sources} ${headers}) target_link_libraries( qtdensitydemo PRIVATE Qt6::Gui Qt6::Core Qt6::Widgets Qt6::SvgWidgets ${BLAS_LIBS} ${LAPACK_LIBS} ${RCPPLIBS_l} ${RINSIDELIBS_l} ${RLDFLAGS} ) RInside/inst/examples/qt/qtdensity.cpp0000644000176200001440000001356114404060001017551 0ustar liggesusers// -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; indent-tabs-mode: nil; -*- // // Qt usage example for RInside, inspired by the standard 'density // sliders' example for other GUI toolkits -- this time with SVG // // Copyright (C) 2011 - 2013 Dirk Eddelbuettel and Romain Francois #include "qtdensity.h" #include QtDensity::QtDensity(RInside & R) : m_R(R) { m_bw = 100; // initial bandwidth, will be scaled by 100 so 1.0 m_kernel = 0; // initial kernel: gaussian m_cmd = "c(rnorm(100,0,1), rnorm(50,5,1))"; // simple mixture m_R["bw"] = m_bw; // pass bandwidth to R, and have R compute a temp.file name m_tempfile = QString::fromStdString(Rcpp::as(m_R.parseEval("tfile <- tempfile()"))); m_svgfile = QString::fromStdString(Rcpp::as(m_R.parseEval("sfile <- tempfile()"))); setupDisplay(); } void QtDensity::setupDisplay(void) { QWidget *window = new QWidget; window->setWindowTitle("Qt and RInside demo: density estimation"); QSpinBox *spinBox = new QSpinBox; QSlider *slider = new QSlider(Qt::Horizontal); spinBox->setRange(5, 200); slider->setRange(5, 200); QObject::connect(spinBox, SIGNAL(valueChanged(int)), slider, SLOT(setValue(int))); QObject::connect(slider, SIGNAL(valueChanged(int)), spinBox, SLOT(setValue(int))); spinBox->setValue(m_bw); QObject::connect(spinBox, SIGNAL(valueChanged(int)), this, SLOT(getBandwidth(int))); QLabel *cmdLabel = new QLabel("R command for random data creation"); QLineEdit *cmdEntry = new QLineEdit(m_cmd); QObject::connect(cmdEntry, SIGNAL(textEdited(QString)), this, SLOT(getRandomDataCmd(QString))); QObject::connect(cmdEntry, SIGNAL(editingFinished()), this, SLOT(runRandomDataCmd())); QGroupBox *kernelRadioBox = new QGroupBox("Density Estimation kernel"); QRadioButton *radio1 = new QRadioButton("&Gaussian"); QRadioButton *radio2 = new QRadioButton("&Epanechnikov"); QRadioButton *radio3 = new QRadioButton("&Rectangular"); QRadioButton *radio4 = new QRadioButton("&Triangular"); QRadioButton *radio5 = new QRadioButton("&Cosine"); radio1->setChecked(true); QVBoxLayout *vbox = new QVBoxLayout; vbox->addWidget(radio1); vbox->addWidget(radio2); vbox->addWidget(radio3); vbox->addWidget(radio4); vbox->addWidget(radio5); kernelRadioBox->setMinimumSize(260,140); kernelRadioBox->setMaximumSize(260,140); kernelRadioBox->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); kernelRadioBox->setLayout(vbox); QButtonGroup *kernelGroup = new QButtonGroup; kernelGroup->addButton(radio1, 0); kernelGroup->addButton(radio2, 1); kernelGroup->addButton(radio3, 2); kernelGroup->addButton(radio4, 3); kernelGroup->addButton(radio5, 4); QObject::connect(kernelGroup, SIGNAL(idClicked(int)), this, SLOT(getKernel(int))); m_svg = new QSvgWidget(); runRandomDataCmd(); // also calls plot() QGroupBox *estimationBox = new QGroupBox("Density estimation bandwidth (scaled by 100)"); QHBoxLayout *spinners = new QHBoxLayout; spinners->addWidget(spinBox); spinners->addWidget(slider); QVBoxLayout *topright = new QVBoxLayout; topright->addLayout(spinners); topright->addWidget(cmdLabel); topright->addWidget(cmdEntry); estimationBox->setMinimumSize(360,140); estimationBox->setMaximumSize(360,140); estimationBox->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); estimationBox->setLayout(topright); QHBoxLayout *upperlayout = new QHBoxLayout; upperlayout->addWidget(kernelRadioBox); upperlayout->addWidget(estimationBox); QHBoxLayout *lowerlayout = new QHBoxLayout; lowerlayout->addWidget(m_svg); QVBoxLayout *outer = new QVBoxLayout; outer->addLayout(upperlayout); outer->addLayout(lowerlayout); window->setLayout(outer); window->show(); } void QtDensity::plot(void) { const char *kernelstrings[] = { "gaussian", "epanechnikov", "rectangular", "triangular", "cosine" }; m_R["bw"] = m_bw; m_R["kernel"] = kernelstrings[m_kernel]; // that passes the string to R std::string cmd0 = "svg(width=6,height=6,pointsize=10,filename=tfile); "; std::string cmd1 = "plot(density(y, bw=bw/100, kernel=kernel), xlim=range(y)+c(-2,2), main=\"Kernel: "; std::string cmd2 = "\"); points(y, rep(0, length(y)), pch=16, col=rgb(0,0,0,1/4)); dev.off()"; std::string cmd = cmd0 + cmd1 + kernelstrings[m_kernel] + cmd2; // stick the selected kernel in the middle m_R.parseEvalQ(cmd); filterFile(); // we need to simplify the svg file for display by Qt m_svg->load(m_svgfile); } void QtDensity::getBandwidth(int bw) { if (bw != m_bw) { m_bw = bw; plot(); } } void QtDensity::getKernel(int kernel) { if (kernel != m_kernel) { m_kernel = kernel; plot(); } } void QtDensity::getRandomDataCmd(QString txt) { m_cmd = txt; } void QtDensity::runRandomDataCmd(void) { std::string cmd = "y2 <- " + m_cmd.toStdString() + "; y <- y2"; m_R.parseEvalQNT(cmd); plot(); // after each random draw, update plot with estimate } void QtDensity::filterFile() { // cairoDevice creates richer SVG than Qt can display // but per Michaele Lawrence, a simple trick is to s/symbol/g/ which we do here QFile infile(m_tempfile); infile.open(QFile::ReadOnly); QFile outfile(m_svgfile); outfile.open(QFile::WriteOnly | QFile::Truncate); QTextStream in(&infile); QTextStream out(&outfile); static QRegularExpression rx1("= 0.11.0) and can be omitted RCPPINCL = $$system($$R_HOME/bin/Rscript -e \"Rcpp:::CxxFlags\(\)\") RCPPLIBS = $$system($$R_HOME/bin/Rscript -e \"Rcpp:::LdFlags\(\)\") ## for some reason when building with Qt we get this each time ## /usr/local/lib/R/site-library/Rcpp/include/Rcpp/module/Module_generated_ctor_signature.h:25: warning: unused parameter ‘classname ## so we turn unused parameter warnings off ## no longer needed with Rcpp 0.9.3 or later #RCPPWARNING = -Wno-unused-parameter ## include headers and libraries for RInside embedding classes RINSIDEINCL = $$system($$R_HOME/bin/Rscript -e \"RInside:::CxxFlags\(\)\") RINSIDELIBS = $$system($$R_HOME/bin/Rscript -e \"RInside:::LdFlags\(\)\") ## compiler etc settings used in default make rules QMAKE_CXXFLAGS += $$RCPPWARNING $$RCPPFLAGS $$RCPPINCL $$RINSIDEINCL QMAKE_LIBS += $$RLDFLAGS $$RBLAS $$RLAPACK $$RINSIDELIBS $$RCPPLIBS ## addition clean targets QMAKE_CLEAN += qtdensity Makefile RInside/inst/examples/qt/main.cpp0000644000176200001440000000100612257416630016461 0ustar liggesusers// -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 8; -*- // // Qt usage example for RInside, inspired by the standard 'density // sliders' example for other GUI toolkits // // Copyright (C) 2011 Dirk Eddelbuettel and Romain Francois #include #include "qtdensity.h" int main(int argc, char *argv[]) { RInside R(argc, argv); // create an embedded R instance QApplication app(argc, argv); QtDensity qtdensity(R); // pass R inst. by reference return app.exec(); } RInside/inst/examples/qt/qtdensity.h0000644000176200001440000000277412257416630017243 0ustar liggesusers// -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; indent-tabs-mode: nil; -*- // // Qt usage example for RInside, inspired by the standard 'density // sliders' example for other GUI toolkits // // Copyright (C) 2011 - 2013 Dirk Eddelbuettel and Romain Francois #ifndef QTDENSITY_H #define QTDENSITY_H #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include class QtDensity : public QMainWindow { Q_OBJECT public: QtDensity(RInside & R); private slots: void getBandwidth(int bw); void getKernel(int kernel); void getRandomDataCmd(QString txt); void runRandomDataCmd(void); private: void setupDisplay(void); // standard GUI boilderplate of arranging things void plot(void); // run a density plot in R and update the void filterFile(void); // modify the richer SVG produced by R QSvgWidget *m_svg; // the SVG device RInside & m_R; // reference to the R instance passed to constructor QString m_tempfile; // name of file used by R for plots QString m_svgfile; // another temp file, this time from Qt int m_bw, m_kernel; // parameters used to estimate the density QString m_cmd; // random draw command string }; #endif RInside/inst/examples/eigen/0000755000176200001440000000000013047337041015473 5ustar liggesusersRInside/inst/examples/eigen/rinside_eigen0.cpp0000644000176200001440000000120612257416630021066 0ustar liggesusers// -*- c-indent-level: 4; c-basic-offset: 4; indent-tabs-mode: nil; -*- // // Simple example using Eigen classes // // Copyright (C) 2012 Dirk Eddelbuettel and Romain Francois #include // for the embedded R via RInside #include int main(int argc, char *argv[]) { RInside R(argc, argv); // create an embedded R instance std::string cmd = "diag(3)"; // create a Matrix in r const Eigen::Map m = // parse, eval + return result Rcpp::as >(R.parseEval(cmd)); std::cout << m << std::endl; // and use Eigen i/o exit(0); } RInside/inst/examples/eigen/cmake/0000755000176200001440000000000012257416630016557 5ustar liggesusersRInside/inst/examples/eigen/cmake/CMakeLists.txt0000644000176200001440000001321512257416630021321 0ustar liggesuserscmake_minimum_required(VERSION 2.8.4) set (VERBOSE 1) set (SRC_DIR ${CMAKE_CURRENT_SOURCE_DIR}/..) execute_process(COMMAND R RHOME OUTPUT_VARIABLE R_HOME) file(GLOB sources ${SRC_DIR}/*.cpp) set(NUM_TRUNC_CHARS 2) set (RPATH "R") set (RSCRIPT_PATH "Rscript") if (CMAKE_HOST_WIN32) execute_process(COMMAND ${RSCRIPT_PATH} -e "cat(.Platform$r_arch)" OUTPUT_VARIABLE R_ARCH) execute_process(COMMAND ${RPATH} --arch ${R_ARCH} RHOME OUTPUT_VARIABLE R_HOME) string(REPLACE "\\" "/" R_HOME ${R_HOME}) set (RPATH ${R_HOME}/bin/R) endif() set (RCPPFLAGS_CMD " ${RPATH} " " CMD " " config " " --cppflags ") execute_process(COMMAND ${RPATH} CMD config --cppflags OUTPUT_VARIABLE RCPPFLAGS) if (CMAKE_HOST_WIN32) if (${RCPPFLAGS} MATCHES "[-][I]([^ ;])+") set (RCPPFLAGS ${CMAKE_MATCH_0}) endif() endif() string(SUBSTRING ${RCPPFLAGS} ${NUM_TRUNC_CHARS} -1 RCPPFLAGS) include_directories(${RCPPFLAGS}) execute_process(COMMAND R CMD config --ldflags OUTPUT_VARIABLE RLDFLAGS) string(LENGTH ${RLDFLAGS} RLDFLAGS_LEN) if (${RLDFLAGS} MATCHES "[-][L]([^ ;])+") string(SUBSTRING ${CMAKE_MATCH_0} ${NUM_TRUNC_CHARS} -1 RLDFLAGS_L) string(STRIP ${RLDFLAGS_L} RLDFLAGS_L ) link_directories(${RLDFLAGS_L} ) endif() if (${RLDFLAGS} MATCHES "[-][l]([^;])+") string(SUBSTRING ${CMAKE_MATCH_0} ${NUM_TRUNC_CHARS} -1 RLDFLAGS_l) string(STRIP ${RLDFLAGS_l} RLDFLAGS_l ) endif() execute_process(COMMAND Rscript -e "Rcpp:::CxxFlags()" OUTPUT_VARIABLE RCPPINCL) string(SUBSTRING ${RCPPINCL} ${NUM_TRUNC_CHARS} -1 RCPPINCL) include_directories(${RCPPINCL}) execute_process(COMMAND Rscript -e "Rcpp:::LdFlags()" OUTPUT_VARIABLE RCPPLIBS) execute_process(COMMAND Rscript -e "RInside:::CxxFlags()" OUTPUT_VARIABLE RINSIDEINCL) string(SUBSTRING ${RINSIDEINCL} ${NUM_TRUNC_CHARS} -1 RINSIDEINCL) include_directories(${RINSIDEINCL}) execute_process(COMMAND Rscript -e "RInside:::LdFlags()" OUTPUT_VARIABLE RINSIDELIBS) execute_process(COMMAND Rscript -e "cat(paste('-I', system.file('include', package = 'RcppEigen'), sep=''))" OUTPUT_VARIABLE RCPPEIGENINCL) string(SUBSTRING ${RCPPEIGENINCL} ${NUM_TRUNC_CHARS} -1 RCPPEIGENINCL) include_directories(${RCPPEIGENINCL}) if (CMAKE_HOST_WIN32) string(LENGTH "libRcpp.a" lenRcppName) string(LENGTH ${RCPPLIBS} lenRcppFQName) math(EXPR RLibPathLen ${lenRcppFQName}-${lenRcppName}-1) string(SUBSTRING ${RCPPLIBS} 0 ${RLibPathLen} RCPPLIBS_L) link_directories(${RCPPLIBS_L}) math(EXPR RLibPathLen ${RLibPathLen}+1) string(SUBSTRING ${RCPPLIBS} ${RLibPathLen} -1 RCPPLIBS_l) #Remove the quotes string(SUBSTRING ${RINSIDELIBS} 1 -1 RINSIDELIBS) string(LENGTH ${RINSIDELIBS} lenRInsideFQNameLen) math(EXPR lenRInsideFQNameLen ${lenRInsideFQNameLen}-1) string(SUBSTRING ${RINSIDELIBS} 0 ${lenRInsideFQNameLen} RINSIDELIBS) string(LENGTH "libRInside.a" lenRInsideName) string(LENGTH ${RINSIDELIBS} lenRInsideFQName) math(EXPR RLibPathLen ${lenRInsideFQName}-${lenRInsideName}-1) string(SUBSTRING ${RINSIDELIBS} 0 ${RLibPathLen} RINSIDELIBS_L) math(EXPR RLibPathLen ${RLibPathLen}+1) string(SUBSTRING ${RINSIDELIBS} ${RLibPathLen} -1 RINSIDELIBS_l) link_directories(${RINSIDELIBS_L}) set ( BLAS_LIBS ${CMAKE_CURRENT_SOURCE_DIR}/libblas.lib) set ( LAPACK_LIBRARY ${CMAKE_CURRENT_SOURCE_DIR}/liblapack.lib) link_directories(${CMAKE_CURRENT_SOURCE_DIR}) else() if (${RCPPLIBS} MATCHES "[-][L]([^ ;])+") string(SUBSTRING ${CMAKE_MATCH_0} ${NUM_TRUNC_CHARS} -1 RCPPLIBS_L) link_directories(${RCPPLIBS_L} ) endif() if (${RCPPLIBS} MATCHES "[-][l][R]([^;])+") string(SUBSTRING ${CMAKE_MATCH_0} ${NUM_TRUNC_CHARS} -1 RCPPLIBS_l) endif() if (${RINSIDELIBS} MATCHES "[-][L]([^ ;])+") string(SUBSTRING ${CMAKE_MATCH_0} ${NUM_TRUNC_CHARS} -1 RINSIDELIBS_L) link_directories(${RINSIDELIBS_L}) endif() if (${RINSIDELIBS} MATCHES "[-][l][R]([^;])+") string(SUBSTRING ${CMAKE_MATCH_0} ${NUM_TRUNC_CHARS} -1 RINSIDELIBS_l) endif() # If the faster 'gold' linker is used, to avoid complaints about undefined symbol SET(CMAKE_FIND_LIBRARY_SUFFIXES_SAVED ${CMAKE_FIND_LIBRARY_SUFFIXES}) # Backup LIST(APPEND CMAKE_FIND_LIBRARY_SUFFIXES ".so.3") FIND_LIBRARY(BLAS_LIBRARY blas) SET(CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES_SAVED}) # Restore LIST(APPEND EXTRA_LIBRARIES ${BLAS_LIBRARY}) endif() execute_process(COMMAND R CMD config CXXFLAGS OUTPUT_VARIABLE RCXXFLAGS) execute_process(COMMAND R CMD config BLAS_LIBS OUTPUT_VARIABLE RBLAS) execute_process(COMMAND R CMD config LAPACK_LIBS OUTPUT_VARIABLE RLAPACK) FIND_LIBRARY(LAPACK_LIBRARY lapack) set(CMAKE_CXX_FLAGS "-W -Wall -pedantic -Wextra ${CMAKE_CXX_FLAGS}") if (CMAKE_BUILD_TYPE STREQUAL "DEBUG" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebugInfo" ) add_definitions("-DDEBUG") elseif ( CMAKE_BUILD_TYPE STREQUAL "RELEASE" ) add_definitions("-O3") endif() foreach (next_SOURCE ${sources}) get_filename_component(source_name ${next_SOURCE} NAME_WE) add_executable( ${source_name} ${next_SOURCE} ) target_link_libraries(${source_name} ${RLDFLAGS_l}) target_link_libraries(${source_name} ${BLAS_LIBS}) target_link_libraries(${source_name} ${LAPACK_LIBS}) target_link_libraries(${source_name} ${RINSIDELIBS_l}) target_link_libraries(${source_name} ${RCPPLIBS_l}) target_link_libraries(${source_name} ${EXTRA_LIBRARIES}) target_link_libraries(${source_name} ${LAPACK_LIBRARY}) endforeach (next_SOURCE ${sources}) RInside/inst/examples/eigen/cmake/WIN.readme.txt0000644000176200001440000000244312257416630021214 0ustar liggesusers Building these examples on Windows is a bit more difficult than on Linux. * Put R in the path: C:\R\R-2.1X.X\bin C:\R\R-2.1X.X\bin\i386 * Add required environment variables: R_HOME C:\R\R-2.1X.X CYGWIN nodosfilewarning * Then libpack and libblas for Windows needed to be obtained from: http://icl.cs.utk.edu/lapack-for-windows/lapack/index.html#libraries_mingw * The CMakeLists.txt files expect the liblapack.lib and libblas.lib files to be in the same directory as themselves for the Windows build. You can edit lines 7 and 8 of the the CMakeLists.txt files if they are not in this location. * I generally build in a 'build' directly below cmake: mkdir build cd build cmake -G "Unix Makefiles" ../. make To run these example there are further DLL dependencies required not installed by RTools: libgcc_s_dw2-1.dll libgfortran.dll libquadmath-0.dll liblapack.dll I was able to grab these by installing MinGW from: http://sourceforge.net/projects/mingw/files/MinGW/Base/gcc/Version4/ Use the version that matches the gcc version that is installed by RTools. Once installed, either add their location to the PATH, or copy them to either the same directory as the example executable, or put them in the windows/system32 folder. Peter peter dot aberline at gmail dot com RInside/inst/examples/eigen/rinside_eigen1.cpp0000644000176200001440000000173012257416630021071 0ustar liggesusers// -*- c-indent-level: 4; c-basic-offset: 4; indent-tabs-mode: nil; -*- // // Simple example using Eigen classes on matrix data generated in R // // Copyright (C) 2012 Dirk Eddelbuettel and Romain Francois #include // for the embedded R via RInside #include int main(int argc, char *argv[]) { RInside R(argc, argv); // create an embedded R instance std::string cmd = "set.seed(42); matrix(rnorm(9),3,3)"; // create a random Matrix in r const Eigen::Map m = // parse, eval + return result Rcpp::as >(R.parseEval(cmd)); Eigen::MatrixXd n = m.transpose() * m; Eigen::ColPivHouseholderQR nqr(n); std::cout << "Initial Matrix m\n" << m << std::endl; std::cout << "Product n = m' * m\n" << n << std::endl; std::cout << "n.sum() " << n.sum() << std::endl; std::cout << "nrq.rank() " << nqr.rank() << std::endl; exit(0); } RInside/inst/examples/eigen/GNUmakefile0000644000176200001440000000371712453643755017571 0ustar liggesusers## -*- mode: make; tab-width: 8; -*- ## ## Simple Makefile ## comment this out if you need a different version of R, ## and set set R_HOME accordingly as an environment variable R_HOME := $(shell R RHOME) sources := $(wildcard *.cpp) programs := $(sources:.cpp=) ## include headers and libraries for R RCPPFLAGS := $(shell $(R_HOME)/bin/R CMD config --cppflags) RLDFLAGS := $(shell $(R_HOME)/bin/R CMD config --ldflags) RBLAS := $(shell $(R_HOME)/bin/R CMD config BLAS_LIBS) RLAPACK := $(shell $(R_HOME)/bin/R CMD config LAPACK_LIBS) ## if you need to set an rpath to R itself, also uncomment #RRPATH := -Wl,-rpath,$(R_HOME)/lib ## include headers and libraries for Rcpp interface classes ## note that RCPPLIBS will be empty with Rcpp (>= 0.11.0) and can be omitted RCPPINCL := $(shell echo 'Rcpp:::CxxFlags()' | $(R_HOME)/bin/R --vanilla --slave) RCPPLIBS := $(shell echo 'Rcpp:::LdFlags()' | $(R_HOME)/bin/R --vanilla --slave) ## include headers and libraries for RInside embedding classes RINSIDEINCL := $(shell echo 'RInside:::CxxFlags()' | $(R_HOME)/bin/R --vanilla --slave) RINSIDELIBS := $(shell echo 'RInside:::LdFlags()' | $(R_HOME)/bin/R --vanilla --slave) ## RcppEigen headers RCPPEIGENINCL := $(shell echo 'cat(paste("-I", system.file("include", package = "RcppEigen"), sep = ""))' | $(R_HOME)/bin/R --vanilla --slave) ## compiler etc settings used in default make rules CXX := $(shell $(R_HOME)/bin/R CMD config CXX) CPPFLAGS := -Wall $(shell $(R_HOME)/bin/R CMD config CPPFLAGS) CXXFLAGS := $(RCPPFLAGS) $(RCPPINCL) $(RCPPEIGENINCL) $(RINSIDEINCL) $(shell $(R_HOME)/bin/R CMD config CXXFLAGS) LDLIBS := $(RLDFLAGS) $(RRPATH) $(RBLAS) $(RLAPACK) $(RCPPLIBS) $(RINSIDELIBS) all: $(programs) @test -x /usr/bin/strip && strip $^ run: $(programs) @for p in $(programs); do echo; echo "Running $$p:"; ./$$p; done clean: rm -vf $(programs) rm -vrf *.dSYM runAll: for p in $(programs); do echo "Running $$p"; ./$$p; done RInside/inst/examples/sandboxed_server/0000755000176200001440000000000015002010355017726 5ustar liggesusersRInside/inst/examples/sandboxed_server/GNUmakefile0000644000176200001440000000512112436367153022022 0ustar liggesusers## -*- mode: make; tab-width: 8; -*- ## ## Simple Makefile ## ## TODO: ## proper configure for non-Debian file locations, [ Done ] ## allow RHOME to be set for non-default R etc ## comment this out if you need a different version of R, ## and set set R_HOME accordingly as an environment variable R_HOME := $(shell R RHOME) sources_datatypes := $(wildcard datatypes/*.cpp) objects_datatypes := $(sources_datatypes:.cpp=.o) sources_server := $(wildcard server/*.cpp) objects_server := $(sources_server:.cpp=.o) sources_client := $(wildcard client/*.cpp) objects_client := $(sources_client:.cpp=.o) sources_common := $(wildcard common/*.cpp) objects_common := $(sources_common:.cpp=.o) server := example_server client := example_client ## include headers and libraries for R RCPPFLAGS := $(shell $(R_HOME)/bin/R CMD config --cppflags) RLDFLAGS := $(shell $(R_HOME)/bin/R CMD config --ldflags) RBLAS := $(shell $(R_HOME)/bin/R CMD config BLAS_LIBS) RLAPACK := $(shell $(R_HOME)/bin/R CMD config LAPACK_LIBS) ## if you need to set an rpath to R itself, also uncomment #RRPATH := -Wl,-rpath,$(R_HOME)/lib ## include headers and libraries for Rcpp interface classes ## note that RCPPLIBS will be empty with Rcpp (>= 0.11.0) and can be omitted RCPPINCL := $(shell echo 'Rcpp:::CxxFlags()' | $(R_HOME)/bin/R --vanilla --slave) RCPPLIBS := $(shell echo 'Rcpp:::LdFlags()' | $(R_HOME)/bin/R --vanilla --slave) ## include headers and libraries for RInside embedding classes RINSIDEINCL := $(shell echo 'RInside:::CxxFlags()' | $(R_HOME)/bin/R --vanilla --slave) RINSIDELIBS := $(shell echo 'RInside:::LdFlags()' | $(R_HOME)/bin/R --vanilla --slave) ## compiler etc settings used in default make rules CXX := $(shell $(R_HOME)/bin/R CMD config CXX) CPPFLAGS := -std=c++11 -Wall $(shell $(R_HOME)/bin/R CMD config CPPFLAGS) CXXFLAGS := $(RCPPFLAGS) $(RCPPINCL) $(RINSIDEINCL) $(shell $(R_HOME)/bin/R CMD config CXXFLAGS) LDLIBS := $(RLDFLAGS) $(RRPATH) $(RBLAS) $(RLAPACK) $(RCPPLIBS) $(RINSIDELIBS) all: $(server) $(client) echo "\n\nCompilation finished.\nRun ./example_server in one shell, then run ./example_client in another." $(server): $(objects_server) $(objects_common) $(objects_datatypes) example_server.o $(CXX) $+ $(LDLIBS) -o $@ $(client): $(objects_client) $(objects_common) $(objects_datatypes) example_client.o $(CXX) $+ $(LDLIBS) -o $@ %.o: %.cpp $(CXX) $(CPPFLAGS) $(CXXFLAGS) -I. -c $+ -o $@ clean: rm -vf $(server) $(client) $(objects_server) $(objects_client) $(objects_common) $(objects_datatypes) example_server.o example_client.o RInside/inst/examples/sandboxed_server/datatypes/0000755000176200001440000000000014501314747021743 5ustar liggesusersRInside/inst/examples/sandboxed_server/datatypes/foo.h0000644000176200001440000000131312436367153022701 0ustar liggesusers#pragma once /* * These are just two example classes that will be communicated between program and rserver. * * See common/binarystream.h/.cpp for information about serialization, * see foo_rcpp_wrapper_*.h for code that converts these objects into R objects and back. */ #include "common/binarystream.h" #include #include /* * Foo just contains a name and two numbers. */ class Foo { public: Foo(const std::string &name, int32_t a, int32_t b); ~Foo(); std::string name; int32_t a, b; // These three are for IPC static const int32_t TYPEID = 1; void serialize(BinaryStream &stream) const; static Foo deserialize(BinaryStream &stream); }; RInside/inst/examples/sandboxed_server/datatypes/foo_rcpp_wrapper_definitions.h0000644000176200001440000000113512436367153030062 0ustar liggesusers#pragma once /* * Foo objects are wrapped into a trivial list. More complicated objects should either * map to a similar native R type or possibly create their own S4 definitions. */ namespace Rcpp { // Foo template<> SEXP wrap(const Foo &foo) { Rcpp::List list; list["name"] = foo.name; list["a"] = foo.a; list["b"] = foo.b; return Rcpp::wrap(list); } template<> Foo as(SEXP sexp) { Rcpp::List list = Rcpp::as(sexp); return Foo( Rcpp::as(list["name"]), Rcpp::as(list["a"]), Rcpp::as(list["b"]) ); } } RInside/inst/examples/sandboxed_server/datatypes/bar.h0000644000176200001440000000136412436367153022670 0ustar liggesusers#pragma once /* * These are just two example classes that will be communicated between program and rserver. * * See binarystream.h/.cpp for information about serialization, * see bar_rcpp_wrapper_*.h for code that converts these objects into R objects and back. */ #include "common/binarystream.h" #include #include #include "foo.h" /* * Bar contains a name and a Foo object, because recursive data structures are fun! */ class Bar { public: Bar(const std::string &name, const Foo &foo); ~Bar(); std::string name; Foo foo; // These three are for IPC static const int32_t TYPEID = 2; void serialize(BinaryStream &stream) const; static Bar deserialize(BinaryStream &stream); }; RInside/inst/examples/sandboxed_server/datatypes/bar_rcpp_wrapper_definitions.h0000644000176200001440000000076712436367153030055 0ustar liggesusers#pragma once /* * These wrappers only wrap into a trivial list. More complicated objects should either * map to a similar */ namespace Rcpp { // Bar template<> SEXP wrap(const Bar &bar) { Rcpp::List list; list["name"] = bar.name; list["foo"] = bar.foo; return Rcpp::wrap(list); } template<> Bar as(SEXP sexp) { Rcpp::List list = Rcpp::as(sexp); return Bar( Rcpp::as(list["name"]), Rcpp::as(list["foo"]) ); } } RInside/inst/examples/sandboxed_server/datatypes/bar.cpp0000644000176200001440000000056312436367153023223 0ustar liggesusers#include "bar.h" Bar::Bar(const std::string &name, const Foo &foo) : name(name), foo(foo) { } Bar::~Bar() { } void Bar::serialize(BinaryStream &stream) const { stream.write(name); stream.write(foo); } Bar Bar::deserialize(BinaryStream &stream) { auto name = stream.read(); auto foo = stream.read(); return Bar(name, foo); } RInside/inst/examples/sandboxed_server/datatypes/bar_rcpp_wrapper_declarations.h0000644000176200001440000000017412436367153030202 0ustar liggesusers#pragma once namespace Rcpp { // Bar template<> SEXP wrap(const Bar &bar); template<> Bar as(SEXP sexp); } RInside/inst/examples/sandboxed_server/datatypes/foo_rcpp_wrapper_declarations.h0000644000176200001440000000017212436367153030217 0ustar liggesusers#pragma once namespace Rcpp { // Foo template<> SEXP wrap(const Foo &foo); template<> Foo as(SEXP sexp); } RInside/inst/examples/sandboxed_server/datatypes/foo.cpp0000644000176200001440000000067212436367153023243 0ustar liggesusers #include "foo.h" Foo::Foo(const std::string &name, int32_t a, int32_t b) : name(name), a(a), b(b) { } Foo::~Foo() { } void Foo::serialize(BinaryStream &stream) const { stream.write(name); stream.write(a); stream.write(b); } Foo Foo::deserialize(BinaryStream &stream) { auto name = stream.read(); auto a = stream.read(); auto b = stream.read(); return Foo(name, a, b); } RInside/inst/examples/sandboxed_server/server/0000755000176200001440000000000014501315642021246 5ustar liggesusersRInside/inst/examples/sandboxed_server/server/internalfunction_clone.h0000644000176200001440000000521012436367153026170 0ustar liggesusers#pragma once /* * Ok, frankly, this is a hack. * We need an InternalFunction, but we don't have a compatible C++ function - we only have * the parameter count and typeids. * * To do this, we need to get down to the point where the function parameters are nothing but an array of SEXP. * And that's so deep in the CppFunction implementation of Rcpp, that we need some detours to get there. */ class CppFunctionForRInsideServer: public Rcpp::CppFunctionBase { public: CppFunctionForRInsideServer(RInsideServer &server, uint32_t callback_id, const std::vector &types) : server(server), callback_id(callback_id), types(types) { } virtual ~CppFunctionForRInsideServer() { } SEXP operator()(SEXP* args) { // TODO: how do we get the amount of arguments passed? We should probably verify them. BEGIN_RCPP LOG("Callback %u called", callback_id); server.sendReply(RIS_REPLY_CALLBACK); server.stream.write(callback_id); size_t paramcount = types.size() - 1; for (size_t i=0;i types; }; // Instantiate the standard deleter. TODO: can we avoid this? template void Rcpp::standard_delete_finalizer(CppFunctionForRInsideServer* obj); namespace Rcpp{ // This is a clone of Rcpp's InternalFunction, just with a different constructor. RCPP_API_CLASS(InternalFunctionForRInsideServer_Impl) { public: RCPP_GENERATE_CTOR_ASSIGN(InternalFunctionForRInsideServer_Impl) InternalFunctionForRInsideServer_Impl(RInsideServer &server, uint32_t callback_id, const std::vector &types) { set(XPtr(new CppFunctionForRInsideServer(server, callback_id, types), false)); } void update(SEXP){} private: inline void set( SEXP xp){ Environment RCPP = Environment::Rcpp_namespace() ; Function intf = RCPP["internal_function"] ; Storage::set__( intf( xp ) ) ; } }; typedef InternalFunctionForRInsideServer_Impl InternalFunctionForRInsideServer ; } RInside/inst/examples/sandboxed_server/server/rinsideserver.cpp0000644000176200001440000001606412436367153024656 0ustar liggesusers/* * Copyright (c) 2014 Christian Authmann */ #define LOG(...) {fprintf(stderr, "%d: ", getpid());fprintf(stderr, __VA_ARGS__);fprintf(stderr, "\n");} #include #include "rinsideserver.h" #include "internalfunction_clone.h" #include #include // Two helper functions. static void replace_all(std::string &str, const std::string &search, const std::string &replace) { size_t start_pos = 0; while ((start_pos = str.find(search, start_pos)) != std::string::npos) { str.replace(start_pos, search.length(), replace); start_pos += replace.length(); } }; static std::string read_file_as_string(const std::string &filename) { std::ifstream in(filename, std::ios::in | std::ios::binary); if (in) { std::string contents; in.seekg(0, std::ios::end); contents.resize(in.tellg()); in.seekg(0, std::ios::beg); in.read(&contents[0], contents.size()); in.close(); return contents; } throw std::runtime_error("Could not read file"); } std::map > RInsideServer::registry_sexp_from_stream; std::map > RInsideServer::registry_sexp_to_stream; RInsideServer::RInsideServer(BinaryStream &stream, RInside &R, RInsideCallbacks &Rcallbacks) : stream(std::move(stream)), R(R), Rcallbacks(Rcallbacks), can_send_reply(false) { } RInsideServer::~RInsideServer() { } /* * Just a shorthand for the repetitive error handling that follows. * The CMD_TRY must only start after all relevant input has been read, i.e. when the server would be allowed to send a reply. * Connection errors are always considered fatal and will cause the server to stop. */ #define CMD_TRY try { #define CMD_CATCH } catch (const BinaryStream::stream_exception) { throw; } catch (const std::exception &e) { std::string s = e.what(); LOG("Command failed: %s", s.c_str()); sendReply(RIS_REPLY_ERROR); stream.write(s); } void RInsideServer::run() { auto magic = stream.read(); if (magic != RIS_MAGIC_NUMBER) throw std::runtime_error("Client sent the wrong magic number"); while (true) { auto cmd = stream.read(); allowSendReply(); //LOG("Requested command: %d", cmd); if (cmd == RIS_CMD_EXIT) { LOG("Exiting because the client requested it"); return; } else if (cmd == RIS_CMD_SETVALUE) { auto name = stream.read(); LOG("Setting value for %s", name.c_str()); auto sexp = sexp_from_stream(); CMD_TRY R[name] = sexp; sendReply(RIS_REPLY_OK); CMD_CATCH } else if (cmd == RIS_CMD_GETVALUE) { auto name = stream.read(); LOG("Returning value for %s", name.c_str()); auto type = stream.read(); CMD_TRY auto sexp = R[name]; sexp_to_stream(sexp, type, true); CMD_CATCH } else if (cmd == RIS_CMD_SETCALLBACK) { auto name = stream.read(); LOG("Setting callback for %s", name.c_str()); auto callback_id = stream.read(); auto result_type = stream.read(); auto paramcount = stream.read(); std::vector param_types; param_types.reserve(paramcount+1); param_types.push_back(result_type); for (size_t i=0;i(); param_types.push_back(type); } CMD_TRY R[name] = Rcpp::InternalFunctionForRInsideServer(*this, callback_id, param_types); sendReply(RIS_REPLY_OK); CMD_CATCH LOG("Callback %s initialized", name.c_str()); } else if (cmd == RIS_CMD_RUN) { auto source = stream.read(); // R on linux doesn't deal well with windows \r\n line endings, so we replace those replace_all(source, "\r\n", "\n"); auto type = stream.read(); CMD_TRY std::string delimiter = "\n\n"; size_t start = 0; size_t end = 0; while (true) { end = source.find(delimiter, start); if (end == std::string::npos) break; std::string line = source.substr(start, end-start); start = end+delimiter.length(); LOG("src: %s", line.c_str()); R.parseEvalQ(line); } std::string lastline = source.substr(start); LOG("src: %s", lastline.c_str()); auto result = R.parseEval(lastline); LOG("Trying to return the result of the R code as a value with typeid %d", type); if (type == 0) sendReply(RIS_REPLY_OK); else { sexp_to_stream(result, type, true); } CMD_CATCH } else if (cmd == RIS_CMD_GETCONSOLE) { LOG("Returning console output"); std::string output = Rcallbacks.getConsoleOutput(); Rcallbacks.resetConsoleOutput(); sendReply(RIS_REPLY_VALUE); stream.write(output); } else if (cmd == RIS_CMD_INITPLOT) { LOG("Initializing plot"); auto width = stream.read(); auto height = stream.read(); CMD_TRY R.parseEval("rserver_plot_tempfile = tempfile(\"rs_plot\", fileext=\".png\")"); R.parseEval("png(rserver_plot_tempfile, width=" + std::to_string(width) + ", height=" + std::to_string(height)+", bg=\"transparent\")"); sendReply(RIS_REPLY_OK); CMD_CATCH } else if (cmd == RIS_CMD_GETPLOT) { LOG("Returning plot"); CMD_TRY R.parseEval("dev.off()"); std::string filename = Rcpp::as(R["rserver_plot_tempfile"]); std::string output = read_file_as_string(filename); std::remove(filename.c_str()); sendReply(RIS_REPLY_VALUE); stream.write(output); CMD_CATCH } else throw std::runtime_error("Client sent unknown command"); } } SEXP RInsideServer::sexp_from_stream() { auto type = stream.read(); if (registry_sexp_from_stream.count(type) < 1) { LOG("unknown type in sexp_from_stream: %d", type); throw std::runtime_error("Unknown datatype in sexp_from_stream"); } return registry_sexp_from_stream[type](stream); } void RInsideServer::sexp_to_stream(SEXP sexp, int32_t type, bool include_reply) { if (registry_sexp_to_stream.count(type) < 1) { LOG("unknown type in sexp_to_stream: %d", type); throw std::runtime_error("Unknown datatype in sexp_to_stream"); } registry_sexp_to_stream[type](*this, sexp, include_reply); } void RInsideServer::registerDefaultTypes() { // TODO: Rcpp does not natively wrap chars. //registerType(); //registerType(); registerType(); registerType(); registerType(); registerType(); registerType(); registerType(); registerType(); registerType(); registerType(); //registerType>(); //registerType>(); registerType>(); registerType>(); registerType>(); registerType>(); registerType>(); registerType>(); registerType>(); registerType>(); registerType>(); } RInside/inst/examples/sandboxed_server/server/rinsideserver.h0000644000176200001440000000417112436367153024317 0ustar liggesusers/* * Copyright (c) 2014 Christian Authmann */ #pragma once #include "common/typeid.h" #include "common/binarystream.h" #include "common/constants.h" #include "rinside_callbacks.h" #include #include #include class CppFunctionForRInsideServer; class RInsideServer { public: RInsideServer(BinaryStream &stream, RInside &R, RInsideCallbacks &Rcallbacks); ~RInsideServer(); void run(); private: SEXP sexp_from_stream(); void sexp_to_stream(SEXP, int32_t type, bool include_reply = false); BinaryStream stream; RInside &R; RInsideCallbacks &Rcallbacks; bool can_send_reply; void sendReply(char reply) { if (!can_send_reply) throw std::runtime_error("Cannot send a reply at this time, exiting"); can_send_reply = false; stream.write(reply); } void allowSendReply() { if (can_send_reply) throw std::runtime_error("allowSendReply() called twice, exiting"); can_send_reply = true; } static std::map > registry_sexp_from_stream; static std::map > registry_sexp_to_stream; public: static void registerDefaultTypes(); template static void registerType() { int32_t type = TYPEID(); if (registry_sexp_from_stream.count(type) > 0 || registry_sexp_to_stream.count(type) > 0) throw std::runtime_error("registerType(): type already registered"); registry_sexp_from_stream[type] = [] (BinaryStream &stream) -> SEXP { T value = stream.read(); return Rcpp::wrap(value); }; registry_sexp_to_stream[type] = [type] (RInsideServer &server, SEXP sexp, bool include_reply) -> void { T value = Rcpp::as(sexp); /* * The reply should be sent after type conversion. If type conversion throws an exception, * the server cannot reply with REPLY_ERROR after another reply has been sent. */ if (include_reply) server.sendReply(RIS_REPLY_VALUE); server.stream.write(type); server.stream.write(value); }; } friend class CppFunctionForRInsideServer; }; RInside/inst/examples/sandboxed_server/server/rinside_callbacks.h0000644000176200001440000000273612436367153025074 0ustar liggesusersclass RInsideCallbacks : public Callbacks { public: // see inst/includes/Callbacks.h for a list of all overrideable methods virtual std::string ReadConsole( const char* prompt, bool addtohistory ) { return ""; }; virtual void WriteConsole( const std::string& line, int type ) { output_buffer << line; //printf("Got buffer of type %d: '%s'\n", type, line.c_str()); }; virtual void FlushConsole() { }; virtual void ResetConsole() { }; virtual void CleanerrConsole() { }; virtual void Busy( bool /*is_busy*/ ) { }; virtual void ShowMessage(const char* message) { //printf("Got Message: '%s'\n", message); }; virtual void Suicide(const char* message) { LOG("R Suicide: %s", message); throw std::runtime_error("R suicided"); // TODO: is this the correct way to handle suicides? }; virtual bool has_ReadConsole() { return true; }; virtual bool has_WriteConsole() { return true; }; virtual bool has_FlushConsole(){ return true; }; virtual bool has_ResetConsole() { return true; }; virtual bool has_CleanerrConsole() { return true; }; virtual bool has_Busy() { return true; }; virtual bool has_ShowMessage() { return true; }; virtual bool has_Suicide() { return true; }; void resetConsoleOutput() { output_buffer.str(""); output_buffer.clear(); } std::string getConsoleOutput() { return output_buffer.str(); } private: std::ostringstream output_buffer; }; RInside/inst/examples/sandboxed_server/example_server.cpp0000644000176200001440000002060414766575231023506 0ustar liggesusers/* * Copyright (c) 2014 Christian Authmann */ #include "common/binarystream.h" #include "common/constants.h" #include "datatypes/foo.h" #include "datatypes/bar.h" #include #include #include // memset() #include #include #include #include #include #include // for sleeping #include #include #include #include #include #include #include #include #include /* * This is an example server. It sets up an R environment and a listening socket, then waits * for clients and fork()s. * The actual communication with clients is handled by server/rinsideserver.cpp. * This file only does initialization and process tracking. */ /* * Since the server fork()s a lot, we would like to prepend the pid to each logged line */ #define LOG(...) {fprintf(stderr, "%d: ", getpid());fprintf(stderr, __VA_ARGS__);fprintf(stderr, "\n");} /* * If an R script gets stuck in an infinite loop, we need to stop it eventually. We thus define a global * timeout after which it gets killed. * * It would be desirable to allow the client to specify the timeout. Unfortunately, only the fork()ed * child process can communicate with the client, but the parent process needs to know about the timeout, * making this more complicated than one might expect. */ const int TIMEOUT_SECONDS = 600; #include #include "datatypes/foo_rcpp_wrapper_declarations.h" #include "datatypes/bar_rcpp_wrapper_declarations.h" #include #include #if !defined(RINSIDE_CALLBACKS) #error "RInside was not compiled with RINSIDE_CALLBACKS" #endif #include "datatypes/foo_rcpp_wrapper_definitions.h" #include "datatypes/bar_rcpp_wrapper_definitions.h" /* * The RInsideServer must be included AFTER RInside and all wrappers are included */ #include "server/rinsideserver.h" int cmpTimespec(const struct timespec &t1, const struct timespec &t2) { if (t1.tv_sec < t2.tv_sec) return -1; if (t1.tv_sec > t2.tv_sec) return 1; if (t1.tv_nsec < t2.tv_nsec) return -1; if (t1.tv_nsec > t2.tv_nsec) return 1; return 0; } void signal_handler(int signum) { LOG("Caught signal %d, exiting", signum); exit(signum); } int main() { // register our custom types with the server RInsideServer::registerDefaultTypes(); RInsideServer::registerType(); RInsideServer::registerType(); // Install signal handlers int signals[] = {SIGHUP, SIGINT, 0}; for (int i=0;signals[i];i++) { if (signal(signals[i], signal_handler) == SIG_ERR) { perror("Cannot install signal handler"); exit(1); } else printf("Signal handler for %d installed\n", signals[i]); } signal(SIGPIPE, SIG_IGN); /* * If R prints anything to the console, we must catch it. * Instead of redirecting stdout (which we might want to use for diagnostics or logging), we * use RInside's callbacks. They're marked experimental and aren't enabled by default, but in our * tests, they worked just fine. */ RInsideCallbacks *Rcallbacks = new RInsideCallbacks(); // Initialize R environment printf("...loading R\n"); RInside R; R.set_callbacks( Rcallbacks ); printf("...loading packages\n"); try { /* * Loading packages is slow. We want to load all common packages once on * server startup, before the fork() * * For example, sandboxR might be useful to restrict the damage an R script can do. * See https://github.com/rapporter/sandboxR */ //R.parseEval("library(\"sandboxR\")"); } catch (const std::exception &e) { printf("error loading packages: %s\nR's output:\n%s", e.what(), Rcallbacks->getConsoleOutput().c_str()); exit(5); } Rcallbacks->resetConsoleOutput(); printf("R is ready\n"); // get rid of leftover sockets unlink(ris_socket_address); // create a fresh socket int listen_fd = socket(AF_UNIX, SOCK_STREAM, 0); if (listen_fd < 0) { perror("socket() failed"); exit(1); } // bind socket struct sockaddr_un server_addr; memset((void *) &server_addr, 0, sizeof(server_addr)); server_addr.sun_family = AF_UNIX; strcpy(server_addr.sun_path, ris_socket_address); if (bind(listen_fd, (sockaddr *) &server_addr, sizeof(server_addr)) < 0) { perror("bind() failed"); exit(1); } // adjust this for your own needs.. chmod(ris_socket_address, 0777); /* * We need to keep track of all the children to enforce timeouts. This map * contains pids of all child processes and their end times. */ std::map running_clients; printf("Socket started, listening..\n"); // Start listening and fork() listen(listen_fd, 5); while (true) { /* * Try to reap all child processes that exited on their own. Not only * will this keep our running_clients map small, it will also allow the * OS to remove any "zombie" processes. */ int status; pid_t exited_pid; while ((exited_pid = waitpid(-1, &status, WNOHANG)) > 0) { LOG("Client %d no longer exists", (int) exited_pid); running_clients.erase(exited_pid); } /* * Now check if any children exceeded their timeout. Kill them. */ struct timespec current_t; clock_gettime(CLOCK_MONOTONIC, ¤t_t); for (auto it = running_clients.begin(); it != running_clients.end(); ) { auto timeout_t = it->second; if (cmpTimespec(timeout_t, current_t) < 0) { auto timeouted_pid = it->first; LOG("Client %d gets killed due to timeout", (int) timeouted_pid); /* * We kill the client using SIGHUP. Since we installed a signal handler, and signal handlers * are kept during fork(), this should be enough to end it. * That is, unless an R package removes the signal handler. In that case, we'd need to keep * tracking the process and force a SIGKILL if it refuses to exit. */ if (kill(timeouted_pid, SIGHUP) < 0) { perror("kill() failed"); ++it; } else { // the postincrement of the iterator is important to avoid using an invalid iterator running_clients.erase(it++); } } else { ++it; } } /* * Wait for new connections. * * We may want to limit the amount of clients running at the same time. */ if (running_clients.size() > 10) { std::this_thread::sleep_for(std::chrono::milliseconds(5000)); continue; } struct pollfd pollfds[1]; pollfds[0].fd = listen_fd; pollfds[0].events = POLLIN; int poll_res = poll(pollfds, /* count = */ 1, /* timeout in ms = */ 5000); if (poll_res < 0) { perror("poll() failed"); exit(1); } /* * If no new connection is made within 5 seconds, we repeat the loop and check * for finished or timeouted children again. */ if (poll_res == 0) continue; if ((pollfds[0].revents & POLLIN) == 0) continue; struct sockaddr_un client_addr; socklen_t client_addr_len = sizeof(client_addr); int client_fd = accept(listen_fd, (struct sockaddr *) &client_addr, &client_addr_len); if (client_fd < 0) { if (errno == EAGAIN || errno == EWOULDBLOCK) continue; perror("accept() failed"); exit(1); } // fork pid_t pid = fork(); if (pid < 0) { perror("fork() failed"); exit(1); } if (pid == 0) { /* * This is the child process. * * If the child process needs to drop any privileges the server may have had, * this is an excellent time to do so. * Whether it's a chroot, seccomp-bpf or a MAC framework like SELinux or AppArmor. * * Note that neither is an excuse to run the parent process unrestricted; creating * a new restricted user for the server seems wise. */ close(listen_fd); LOG("Client starting"); auto start_c = clock(); struct timespec start_t; clock_gettime(CLOCK_MONOTONIC, &start_t); try { BinaryStream stream(client_fd, client_fd); RInsideServer ris(stream, R, *Rcallbacks); ris.run(); } catch (const std::exception &e) { LOG("Exception: %s", e.what()); } auto end_c = clock(); struct timespec end_t; clock_gettime(CLOCK_MONOTONIC, &end_t); double c = (double) (end_c - start_c) / CLOCKS_PER_SEC; double t = (double) (end_t.tv_sec - start_t.tv_sec) + (double) (end_t.tv_nsec - start_t.tv_nsec) / 1000000000; LOG("Client finished, %.3fs real, %.3fs CPU", t, c); exit(0); } else { // This is the parent process close(client_fd); struct timespec timeout_t; clock_gettime(CLOCK_MONOTONIC, &timeout_t); timeout_t.tv_sec += TIMEOUT_SECONDS; running_clients[pid] = timeout_t; } } } RInside/inst/examples/sandboxed_server/client/0000755000176200001440000000000014501314747021223 5ustar liggesusersRInside/inst/examples/sandboxed_server/client/rinsideclient.h0000644000176200001440000000515012436367153024235 0ustar liggesusers/* * Copyright (c) 2014 Christian Authmann */ #pragma once #include "common/binarystream.h" #include "common/constants.h" #include "common/typeid.h" #include #include #include #include #include "callback_helper.h" class RInsideClient { public: RInsideClient(BinaryStream &stream); ~RInsideClient(); void parseEvalQ(const std::string &code) { runScript(code, 0); can_send_command = true; }; template T parseEval(const std::string &code) { runScript(code, TYPEID()); auto result = stream.read(); can_send_command = true; return result; }; template void setValue(const std::string &name, const T &value) { writeCommand(RIS_CMD_SETVALUE); stream.write(name); stream.write(TYPEID()); stream.write(value); readReply(true, false); can_send_command = true; }; template T getValue(const std::string &name) { writeCommand(RIS_CMD_GETVALUE); stream.write(name); stream.write(TYPEID()); readReply(false, true); auto type = stream.read(); if (type != TYPEID()) unrecoverable_error("getValue() returned wrong type"); auto result = stream.read(); can_send_command = true; return result; }; template void setCallback(const std::string &name, std::function &callback) { uint32_t callback_id = next_callback_id++; int32_t result_type = TYPEID(); size_t paramcount = sizeof...(Params); writeCommand(RIS_CMD_SETCALLBACK); stream.write(name); stream.write(callback_id); stream.write(result_type); stream.write(paramcount); // now write the types of the parameters callback_helper::send_pack::send(stream); // remember the callback std::function func = std::bind(callback_helper::call, std::ref(callback), std::ref(stream)); callbacks[callback_id] = func; readReply(true, false); can_send_command = true; } std::string getConsoleOutput(); void initPlot(uint32_t width=800, uint32_t height=600); std::string getPlot(); private: void runScript(const std::string code, int32_t result_typeid); void writeCommand(char command); char readReply(bool accept_ok = true, bool accept_value = false); void unrecoverable_error(const std::string &error); BinaryStream stream; uint32_t next_callback_id; std::map > callbacks; bool had_unrecoverable_error; bool can_send_command; }; RInside/inst/examples/sandboxed_server/client/rinsideclient.cpp0000644000176200001440000000643512436367153024577 0ustar liggesusers/* * Copyright (c) 2014 Christian Authmann */ #include "rinsideclient.h" #include "common/constants.h" #include #include RInsideClient::RInsideClient(BinaryStream &_stream) : stream(std::move(_stream)), next_callback_id(1), had_unrecoverable_error(false), can_send_command(false) { stream.write(RIS_MAGIC_NUMBER); can_send_command = true; } RInsideClient::~RInsideClient() { if (!had_unrecoverable_error && can_send_command) { try { stream.write(RIS_CMD_EXIT); } catch (...) { // don't ever throw in a destructor! } } } void RInsideClient::runScript(const std::string code, int32_t result_typeid) { writeCommand(RIS_CMD_RUN); stream.write(code); stream.write(result_typeid); while (true) { auto reply = stream.read(); if (reply == RIS_REPLY_CALLBACK) { auto callback_id = stream.read(); auto &func = callbacks.at(callback_id); try { func(); } catch (const callback_helper::parameter_error_exception &e) { // This is a recoverable error! can_send_command = true; throw std::runtime_error(e.what()); } catch (...) { had_unrecoverable_error = true; throw; } } else if (reply == RIS_REPLY_OK) { if (result_typeid != 0) unrecoverable_error("runScript() did not return a value when one was requested"); return; } else if (reply == RIS_REPLY_VALUE) { if (result_typeid == 0) unrecoverable_error("runScript() did return a value when none was requested"); auto type = stream.read(); if (type != result_typeid) unrecoverable_error("runScript() did return a value of the wrong type"); return; } } } std::string RInsideClient::getConsoleOutput() { writeCommand(RIS_CMD_GETCONSOLE); readReply(false, true); auto result = stream.read(); can_send_command = true; return result; } void RInsideClient::initPlot(uint32_t width, uint32_t height) { writeCommand(RIS_CMD_INITPLOT); stream.write(width); stream.write(height); readReply(true, false); can_send_command = true; } std::string RInsideClient::getPlot() { writeCommand(RIS_CMD_GETPLOT); readReply(false, true); auto result = stream.read(); can_send_command = true; return result; } void RInsideClient::writeCommand(char command) { if (had_unrecoverable_error) throw std::runtime_error("RInsideClient cannot continue due to previous unrecoverable errors"); if (!can_send_command) throw std::runtime_error("RInsideClient cannot send a command at this time"); stream.write(command); can_send_command = false; } char RInsideClient::readReply(bool accept_ok, bool accept_value) { auto reply = stream.read(); if (reply == RIS_REPLY_ERROR) { auto error = stream.read(); can_send_command = true; throw std::runtime_error(std::string("Error in R Server: ") + error); } if (reply == RIS_REPLY_OK && !accept_ok) unrecoverable_error("Got unexpected reply from the R server"); if (reply == RIS_REPLY_VALUE && !accept_value) unrecoverable_error("Got unexpected reply from the R server"); return reply; } void RInsideClient::unrecoverable_error(const std::string &error) { had_unrecoverable_error = true; throw std::runtime_error(error); } RInside/inst/examples/sandboxed_server/client/callback_helper.h0000644000176200001440000000636312436367153024503 0ustar liggesusers/* * Copyright (c) 2014 Christian Authmann */ namespace callback_helper { // A recursive template sending the TYPEIDs of all template parameters over the stream template struct send_pack; template struct send_pack { static void send(BinaryStream &stream) { auto type = TYPEID(); stream.write(type); send_pack::send(stream); } }; template <> struct send_pack<> { static void send(BinaryStream &stream) { } }; // An exception when the wrong type is sent over the stream class type_mismatch_exception : std::exception { }; // An exception when the server failed to transform a parameter, but can still continue class parameter_error_exception : public std::runtime_error { public: explicit parameter_error_exception(const std::string &error) : std::runtime_error(error) {}; }; // read a typeid from the stream, compare it to the expected type, then read the value template T read_from_stream_with_typeid(BinaryStream &stream) { auto result = stream.read(); if (result == RIS_REPLY_ERROR) { auto error = stream.read(); throw parameter_error_exception(error); } else if (result != RIS_REPLY_VALUE) { throw std::runtime_error("Invalid reply from server"); } auto type = stream.read(); if (type != TYPEID()) { printf("trying to read type %d, got type %d\n", (int) TYPEID(), (int) type); throw type_mismatch_exception(); } return stream.read(); } // auto-generated functions for calling callbacks template void call(const std::function &fun, BinaryStream &stream) { RESULT_TYPE result = fun(); int32_t result_type = TYPEID(); stream.write(result_type); stream.write(result); } template void call(const std::function &fun, BinaryStream &stream) { auto x0 = read_from_stream_with_typeid::type>(stream); RESULT_TYPE result = fun(x0); int32_t result_type = TYPEID(); stream.write(result_type); stream.write(result); } template void call(const std::function &fun, BinaryStream &stream) { auto x0 = read_from_stream_with_typeid::type>(stream); auto x1 = read_from_stream_with_typeid::type>(stream); RESULT_TYPE result = fun(x0, x1); int32_t result_type = TYPEID(); stream.write(result_type); stream.write(result); } template void call(const std::function &fun, BinaryStream &stream) { auto x0 = read_from_stream_with_typeid::type>(stream); auto x1 = read_from_stream_with_typeid::type>(stream); auto x2 = read_from_stream_with_typeid::type>(stream); RESULT_TYPE result = fun(x0, x1, x2); int32_t result_type = TYPEID(); stream.write(result_type); stream.write(result); } // TODO: more parameters } RInside/inst/examples/sandboxed_server/example_client.cpp0000644000176200001440000001623012436367153023450 0ustar liggesusers/* * Copyright (c) 2014 Christian Authmann */ #include "datatypes/foo.h" #include "datatypes/bar.h" #include "common/constants.h" #include "common/binarystream.h" #include "client/rinsideclient.h" #include #include #include #include #include #include #include #include /* * The following examples often talk about "serializable types". These are any * user-defined objects with a TYPEID, serialize() and deserialize() methods * (in this example: Foo and Bar) as well as std::string, most arithmetic types * and vectors of these. * * See common/typeid.h for a list. */ static void test_setting_getting() { auto stream = BinaryStream::connectToUnixSocket(ris_socket_address); RInsideClient R(stream); /* * We can set variables in the R environment to any object we like, provided * that the object is of a serializable type. * We can get them accordingly. */ Foo foo("testfoo", 42, 43); printf("setting Foo(%s, %d, %d) in the R environment\n", foo.name.c_str(), foo.a, foo.b); R.setValue("foo", foo); auto foo2 = R.getValue("foo"); printf("got Foo(%s, %d, %d) via getValue\n", foo2.name.c_str(), foo2.a, foo2.b); auto foo3 = R.parseEval("foo"); printf("got Foo(%s, %d, %d) via parseEval\n", foo3.name.c_str(), foo3.a, foo3.b); try { auto foo = R.getValue("IDoNotExist"); } catch (const std::runtime_error &e) { printf("Getting a nonexistent variable failed with message:\n%s\n", e.what()); } try { auto bar = R.getValue("foo"); } catch (const std::runtime_error &e) { printf("Getting foo as an object of class Bar failed with message:\n%s\n", e.what()); } } static void test_callbacks() { // We initialize a new connection. The server will spawn a new process with a clean environment. auto stream = BinaryStream::connectToUnixSocket(ris_socket_address); RInsideClient R(stream); /* * We can provide C++ functions to the R environment. Parameters and return value * must be of a serializable type. * * This has a bit of an overhead, since each time a function is called, the parameters * are sent over the network from R to C++, then the function is executed, and the * result is sent back from C++ to R. * You will want to avoid sending large objects, and you will want to avoid calling * remote functions hundreds of times per second. */ std::function loadFoo = [] (const std::string &name) -> Foo { return Foo(name, name.length(), 1); }; R.setCallback("loadFoo", loadFoo); std::function swapFoo = [] (const Foo &foo) -> Foo { return Foo(foo.name, foo.b, foo.a); }; R.setCallback("swapFoo", swapFoo); std::function loadBar = [] (int id) -> Bar { std::string foo_name = std::string("foo_") + std::to_string(id); return Bar(foo_name, Foo(foo_name, foo_name.length(), id)); }; R.setCallback("loadBar", loadBar); std::function(float, float, const std::vector &)> calibrate = [] (float offset, float scale, const std::vector &in) -> std::vector { std::vector out; out.reserve(in.size()); for ( auto &v : in ) out.push_back(offset + (float) v * scale); return out; }; R.setCallback("calibrate", calibrate); auto foo = R.parseEval("foo = loadFoo('loaded')"); printf("got Foo(%s, %d, %d) via loadFoo()\n", foo.name.c_str(), foo.a, foo.b); auto foo2 = R.parseEval("swapFoo(foo)"); printf("got Foo(%s, %d, %d) after swapFoo()\n", foo2.name.c_str(), foo2.a, foo2.b); auto bar = R.parseEval("loadBar(42)"); printf("got Bar(%s, Foo(%s, %d, %d))\n", bar.name.c_str(), bar.foo.name.c_str(), bar.foo.a, bar.foo.b); auto vec = R.parseEval>("calibrate(1.0, 0.3, c(1,2,3,4,5))"); printf("Got c("); for (auto &v : vec) printf("%.2f, ", v); printf(") from calibrate()\n"); try { auto foo3 = R.parseEval("loadFoo()"); printf("got Foo(%s, %d, %d) via loadFoo()\n", foo3.name.c_str(), foo3.a, foo3.b); } catch (const std::runtime_error &e) { printf("Calling loadFoo() with wrong parameters failed with message:\n%s\n", e.what()); } catch (...) { printf("Calling loadFoo() with wrong parameters lead to an unrecoverable error, ending test\n"); return; } // Passing incompatible parameters results in recoverable errors, so we can keep using the connection auto x = R.parseEval("x = 42;"); printf("Got x = %d\n", x); } static void test_console_output() { auto stream = BinaryStream::connectToUnixSocket(ris_socket_address); RInsideClient R(stream); /* * It's probably useful to capture the output of R's console. * So here's how you do it. */ R.parseEvalQ("print('Hello World')"); auto output = R.getConsoleOutput(); printf("Output of the R script:\n%s\n", output.c_str()); } static void test_plot() { auto stream = BinaryStream::connectToUnixSocket(ris_socket_address); RInsideClient R(stream); /* * According to a totally representative user survey, the main use of R is to draw fancy plots [citation needed]. * * Of course, we can do that. */ R.initPlot(400,600); R.parseEvalQ("plot(c(0,0), type = 'n', xlim=c(0,1), ylim=c(-1,1), xlab = 'x', ylab = 'y', bty='n')"); R.parseEvalQ("lines(c(0,0), c(-1,1), col='red', add=TRUE)"); R.parseEvalQ("curve(-x, 0, 1, 200, col='blue', add=TRUE)"); R.parseEvalQ("curve(0.5+sqrt(1-x^2)/2, 0, 1, 200, col='#00FF00', add=TRUE)"); R.parseEvalQ("curve(0.5-sqrt(1-x^2)/2, 0, 1, 200, col='#33EE33', add=TRUE)"); auto png = R.getPlot(); printf("Got a png from the plot, saving to plot.png\n"); std::fstream f("plot.png", std::fstream::out | std::fstream::binary | std::fstream::trunc); f << png; f.close(); } static void test_multiple() { /* * For our last trick, we'd like to show something that cannot be replicated using RInside directly: * Handling multiple R environments at the same time. */ auto stream1 = BinaryStream::connectToUnixSocket(ris_socket_address); RInsideClient R1(stream1); auto stream2 = BinaryStream::connectToUnixSocket(ris_socket_address); RInsideClient R2(stream2); R1.setValue("id", 1); R2.setValue("id", 2); auto id1 = R1.getValue("id"); auto id2 = R2.getValue("id"); printf("id of environment 1 is: %d, id of environment 2 is: %d\n", id1, id2); } int main(void) { try { printf("==========================\nTesting setting and getting:\n==========================\n"); test_setting_getting(); printf("\n==========================\nTesting callbacks:\n==========================\n"); test_callbacks(); printf("\n==========================\nTesting console output:\n==========================\n"); test_console_output(); printf("\n==========================\nTesting plots:\n==========================\n"); test_plot(); printf("\n==========================\nTesting multiple environments:\n==========================\n"); test_multiple(); } catch (const BinaryStream::stream_exception &e) { printf("Error communicating with the server\nDid you start ./example_server?\n"); } } RInside/inst/examples/sandboxed_server/README.md0000644000176200001440000000070314501602044021212 0ustar liggesusers ## Sandboxed Server The example provided in this directory requires `RInside` to be built with callback support. This can be enabled by uncommenting one line in the file `RInsideConfig.h` to define the preprocessor constant `RINSIDE_CALLBACKS`, and then rebuilding. Alternatively, adding a compiler flag `-DRINSIDE_CALLBACKS` and reinstalling would do too; this also requires using the same flag when building the example or similar applications. RInside/inst/examples/sandboxed_server/common/0000755000176200001440000000000014501314747021235 5ustar liggesusersRInside/inst/examples/sandboxed_server/common/binarystream.cpp0000644000176200001440000001045312436367153024450 0ustar liggesusers/* * Copyright (c) 2014 Christian Authmann */ #include "binarystream.h" #include #include // memset(), strerror() #include #include #include #include #include #include BinaryStream::BinaryStream(int read_fd, int write_fd) : is_eof(false), read_fd(read_fd), write_fd(write_fd) { } BinaryStream::~BinaryStream() { close(); } void BinaryStream::close() { if (read_fd == write_fd) write_fd = -1; if (read_fd >= 0) { ::close(read_fd); read_fd = -1; } if (write_fd >= 0) { ::close(write_fd); write_fd = -1; } is_eof = true; } BinaryStream::BinaryStream(BinaryStream &&other) : is_eof(other.is_eof), read_fd(other.read_fd), write_fd(other.write_fd) { other.is_eof = true; other.read_fd = -1; other.write_fd = -1; } BinaryStream &BinaryStream::operator=(BinaryStream &&other) { std::swap(is_eof, other.is_eof); std::swap(read_fd, other.read_fd); std::swap(write_fd, other.write_fd); return *this; } BinaryStream BinaryStream::connectToUnixSocket(const char *server_path) { int new_fd = socket(AF_UNIX, SOCK_STREAM, 0); if (new_fd < 0) throw stream_exception(); struct sockaddr_un server_addr; memset((void *) &server_addr, 0, sizeof(server_addr)); server_addr.sun_family = AF_UNIX; strcpy(server_addr.sun_path, server_path); if (connect(new_fd, (sockaddr *) &server_addr, sizeof(server_addr)) == -1) { ::close(new_fd); throw stream_exception(); } return BinaryStream(new_fd, new_fd); } void BinaryStream::write(const char *buffer, size_t len) { if (write_fd < 0) throw stream_exception(); //printf("Stream: writing %lu bytes\n", len); auto res = ::write(write_fd, buffer, len); if (res < 0 || (size_t) res != len) { // strerror(errno); throw stream_exception(); } } size_t BinaryStream::read(char *buffer, size_t len) { if (read_fd < 0 || is_eof) throw stream_exception(); //printf("Stream: reading %lu bytes\n", len); size_t remaining = len; size_t bytes_read = 0; while (remaining > 0) { auto r = ::read(read_fd, buffer, remaining); if (r == 0) { is_eof = true; throw stream_exception(); } if (r < 0) { // strerror(errno); throw stream_exception(); } bytes_read += r; buffer += r; remaining -= r; } if (bytes_read != len) throw stream_exception(); return bytes_read; } namespace serialization { // Strings void serializer::serialize(BinaryStream &stream, const std::string &string) { size_t len = string.size(); if (len > (size_t) (1<<31)) throw BinaryStream::stream_exception(); stream.write(len); stream.write(string.data(), len); } std::string serializer::deserialize(BinaryStream &stream) { auto len = stream.read(); if (len == 0) return ""; if (len > (size_t) (1<<31)) throw BinaryStream::stream_exception(); std::unique_ptr buffer( new char[len] ); stream.read(buffer.get(), len); std::string string(buffer.get(), len); return string; } // Vectors template void serializer>::serialize(BinaryStream &stream, const std::vector &vec) { size_t size = vec.size(); if (size > (size_t) (1<<31)) throw BinaryStream::stream_exception(); stream.write(size); for (size_t i=0;i std::vector serializer>::deserialize(BinaryStream &stream) { std::vector vec; auto size = stream.read(); if (size > (size_t) (1<<31)) throw BinaryStream::stream_exception(); vec.reserve(size); for (size_t i=0;i()); return vec; }; // Note: when adding more serializers, don't forget to add their declaration in binarystream.h! // Make sure to instantiate the vectors we need template struct serializer>; template struct serializer>; template struct serializer>; template struct serializer>; template struct serializer>; template struct serializer>; template struct serializer>; template struct serializer>; template struct serializer>; template struct serializer>; template struct serializer>; } RInside/inst/examples/sandboxed_server/common/binarystream.h0000644000176200001440000001370612436367153024121 0ustar liggesusers/* * Copyright (c) 2014 Christian Authmann */ #pragma once #include "typeid.h" #include #include #include #include #include #include /* * This is a stream class for IPC, meant to allow serialization of objects. * * We could use the POSIX socket API directly, but we choose to use a simple * wrapper for convenience and error handling via exceptions. * * We are not using std::iostream for several reasons. * First, the default overloads are meant for human-readable display, not * for efficient binary serialization. * Second, they're not reversible: * out << 2 << 7 << 42 * will result in a stream "2742", which cannot be correctly deserialized using * in >> a >> b >> c * * Instead, we're opting for a very simple binary stream implementation * providing nothing but read() and write() functions, including some * overloads. * * - Primitive types are serialized as their binary representation. * Do not attempt to communicate between machines of different word size * or endianess! * - some native types (std::string, ...) have their own serialization functions * - other classes must implement serialize() and deserialize() methods * (See foo.h for an example) * * Note that this is not meant as a lesson in good IPC or serialization design, * it's just a simple helper class to keep the rest of the code more readable. */ class BinaryStream { public: BinaryStream(int read_fd, int write_fd); ~BinaryStream(); void close(); BinaryStream(const BinaryStream &) = delete; BinaryStream &operator=(const BinaryStream &) = delete; BinaryStream(BinaryStream &&); BinaryStream &operator=(BinaryStream &&); static BinaryStream connectToUnixSocket(const char *); void write(const char *buffer, size_t len); template void write(const T& t); template void write(T& t); size_t read(char *buffer, size_t len); template typename std::enable_if< std::is_arithmetic::value, size_t>::type read(T *t) { return read((char *) t, sizeof(T)); } template T read(); class stream_exception : std::exception { }; private: bool is_eof; int read_fd, write_fd; }; /* * Declare functions for serialization/deserialization of important native classes */ namespace serialization { template struct serializer { }; template <> struct serializer { static void serialize(BinaryStream &, const std::string &); static std::string deserialize(BinaryStream &); }; template struct serializer> { static void serialize(BinaryStream &, const std::vector &); static std::vector deserialize(BinaryStream &); }; } /* * Figure out if a class has serialize and deserialize methods */ namespace binary_stream_helpers { /* * For void_t, see the CppCon2014 talk by Walter E. Brown: "Modern Template Metaprogramming: A Compendium", Part II */ template struct void_t_struct { using type = void; }; template using void_t = typename void_t_struct::type; /* * Figuring out whether a class has serialize() and deserialize() members */ template using serialize_member_t = decltype( std::declval().serialize( std::declval() ) ); template using deserialize_member_t = decltype( T::deserialize( std::declval() ) ); template struct has_serialization_members_cv : std::false_type { }; template struct has_serialization_members_cv, deserialize_member_t > > : std::integral_constant,void>::value && std::is_same, T>::value > { }; template struct has_serialization_members : has_serialization_members_cv< typename std::decay::type > { }; /* * Templates for serialization */ // Arithmetic types: serialize the binary representation template typename std::enable_if< std::is_arithmetic::value >::type stream_write(BinaryStream &stream, T& t) { stream.write((const char *) &t, sizeof(T)); } // User-defined types: call .serialize() template typename std::enable_if< has_typeid::value && std::is_class::value && has_serialization_members::value >::type stream_write(BinaryStream &stream, T& t) { t.serialize(stream); } // Other classes: hopefully there's a function in the serialization namespace template typename std::enable_if< has_typeid::value && std::is_class::value && !has_serialization_members::value >::type stream_write(BinaryStream &stream, T &t) { serialization::serializer< typename std::decay::type >::serialize(stream, t); } /* * Typed template for deserialization */ // Arithmetic types: deserialize the binary representation template typename std::enable_if< std::is_arithmetic::value, T >::type stream_read(BinaryStream &stream) { T value; stream.read(&value); return value; } // User-defined types: call ::deserialize() template typename std::enable_if< has_typeid::value && std::is_class::value && has_serialization_members::value, T >::type stream_read(BinaryStream &stream) { return T::deserialize(stream); } // Other classes: hopefully there's a function in the serialization namespace template typename std::enable_if< has_typeid::value && std::is_class::value && !has_serialization_members::value, T >::type stream_read(BinaryStream &stream) { return serialization::serializer< typename std::decay::type >::deserialize(stream); } } template void BinaryStream::write(const T& t) { binary_stream_helpers::stream_write(*this, t); } template void BinaryStream::write(T& t) { binary_stream_helpers::stream_write(*this, t); } template T BinaryStream::read() { return binary_stream_helpers::stream_read(*this); } RInside/inst/examples/sandboxed_server/common/constants.h0000644000176200001440000000213712436367153023431 0ustar liggesusers/* * Copyright (c) 2014 Christian Authmann */ #pragma once #define ris_socket_address "example_server.sock" const uint32_t RIS_MAGIC_NUMBER = 0xF00BA5; const char RIS_CMD_SETVALUE = 1; const char RIS_CMD_GETVALUE = 2; const char RIS_CMD_SETCALLBACK = 3; const char RIS_CMD_RUN = 4; const char RIS_CMD_GETCONSOLE = 5; const char RIS_CMD_INITPLOT = 6; const char RIS_CMD_GETPLOT = 7; const char RIS_CMD_EXIT = 8; const char RIS_REPLY_OK = 101; const char RIS_REPLY_CALLBACK = 102; const char RIS_REPLY_VALUE = 103; const char RIS_REPLY_ERROR = 104; /* * The Socket protocol is as follows: * * The Client initiates the connection by sending the "magic number" * * Then the Client sends a CMD, followed by the required parameters. * The server sends a REPLY, followed by a value, an error or any other * relevant payload. * * For the exact parameters of each command, see rinsideserver.cpp * * Communication is continued until the client terminates the connection. The server * should only terminate the connection when encountering an unrecoverable error. */ RInside/inst/examples/sandboxed_server/common/typeid.h0000644000176200001440000001017612436367153022715 0ustar liggesusers/* * Copyright (c) 2014 Christian Authmann */ #pragma once #include #include #include #include /* * We need a value for each type so we can communicate which type to send or receive over the socket. * * std::type_info won't help, since its values may change on each program start, making them unsuitable for client/server-communication. * * Our typeid is an int32_t. Negative values are reserved for native types (int, float, std::string, ...) while positive values * can be used in custom classes. See datatypes/foo.h for the syntax. */ namespace typeid_helpers { /* * For void_t, see the CppCon2014 talk by Walter E. Brown: "Modern Template Metaprogramming: A Compendium", Part II */ template struct void_t_struct { using type = void; }; template using void_t = typename void_t_struct::type; template struct has_typeid_member : std::false_type { }; template struct has_typeid_member > : std::true_type { }; /* * Note: Calling TYPEID() on an unsupported type yields some cryptic compiler errors. If you have seen errors in one of the lines below, * make sure that the type you're calling TYPEID() on is either * - a supported native type and has a specialization below * or * - a custom class with a public static const int32_t TYPEID */ template struct id { }; template struct id::value >::type> { static const int32_t value = T::TYPEID; }; template <> struct id { static const int32_t value = 0; }; template <> struct id { static const int32_t value = -1; }; template <> struct id { static const int32_t value = -2; }; template <> struct id { static const int32_t value = -3; }; template <> struct id { static const int32_t value = -4; }; template <> struct id { static const int32_t value = -5; }; template <> struct id { static const int32_t value = -6; }; template <> struct id { static const int32_t value = -7; }; template <> struct id { static const int32_t value = -8; }; template <> struct id { static const int32_t value = -9; }; template <> struct id { static const int32_t value = -10; }; template <> struct id { static const int32_t value = -11; }; template <> struct id, void> { static const int32_t value = -21; }; template <> struct id, void> { static const int32_t value = -22; }; template <> struct id, void> { static const int32_t value = -23; }; template <> struct id, void> { static const int32_t value = -24; }; template <> struct id, void> { static const int32_t value = -25; }; template <> struct id, void> { static const int32_t value = -26; }; template <> struct id, void> { static const int32_t value = -27; }; template <> struct id, void> { static const int32_t value = -28; }; template <> struct id, void> { static const int32_t value = -29; }; template <> struct id, void> { static const int32_t value = -30; }; template <> struct id, void> { static const int32_t value = -31; }; } template constexpr int32_t TYPEID() { return typeid_helpers::id< typename std::decay::type, void >::value; } template struct has_typeid : std::false_type { }; template struct has_typeid::type, void>::value)> > : std::true_type { }; RInside/inst/examples/mpi/0000755000176200001440000000000013047337034015173 5ustar liggesusersRInside/inst/examples/mpi/rinside_mpi_sample2.cpp0000644000176200001440000000216112257416630021626 0ustar liggesusers// -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 8; -*- // // Simple example showing in R console information about current node // // MPI C++ API version of file contributed by Jianping Hua // // Copyright (C) 2010 - 2011 Dirk Eddelbuettel and Romain Francois // // GPL'ed #include // mpi header #include // for the embedded R via RInside int main(int argc, char *argv[]) { MPI::Init(argc, argv); // mpi initialization int myrank = MPI::COMM_WORLD.Get_rank(); // obtain current node rank int nodesize = MPI::COMM_WORLD.Get_size(); // obtain total nodes running. RInside R(argc, argv); // create an embedded R instance std::stringstream txt; txt << "Hello from node " << myrank // node information << " of " << nodesize << " nodes!" << std::endl; R["txt"] = txt.str(); // assign string var to R variable 'txt' R.parseEvalQ("cat(txt)"); // eval init string, ignoring any returns MPI::Finalize(); // mpi finalization exit(0); } RInside/inst/examples/mpi/cmake/0000755000176200001440000000000012257416630016255 5ustar liggesusersRInside/inst/examples/mpi/cmake/CMakeLists.txt0000644000176200001440000000645012257416630021022 0ustar liggesuserscmake_minimum_required(VERSION 2.8.4) set (SRC_DIR ${CMAKE_CURRENT_SOURCE_DIR}/..) execute_process(COMMAND R RHOME OUTPUT_VARIABLE R_HOME) find_package(MPI REQUIRED) set(CMAKE_CXX_COMPILE_FLAGS ${CMAKE_CXX_COMPILE_FLAGS} ${MPI_COMPILE_FLAGS}) set(CMAKE_CXX_LINK_FLAGS ${CMAKE_CXX_LINK_FLAGS} ${MPI_LINK_FLAGS}) include_directories(${MPI_INCLUDE_PATH}) file(GLOB sources ${SRC_DIR}/*.cpp) set(NUM_TRUNC_CHARS 2) execute_process(COMMAND R CMD config --cppflags OUTPUT_VARIABLE RCPPFLAGS) string(SUBSTRING ${RCPPFLAGS} ${NUM_TRUNC_CHARS} -1 RCPPFLAGS) include_directories(${RCPPFLAGS}) execute_process(COMMAND R CMD config --ldflags OUTPUT_VARIABLE RLDFLAGS) string(LENGTH ${RLDFLAGS} RLDFLAGS_LEN) if (${RLDFLAGS} MATCHES "[-][L]([^ ;])+") string(SUBSTRING ${CMAKE_MATCH_0} ${NUM_TRUNC_CHARS} -1 RLDFLAGS_L) string(STRIP ${RLDFLAGS_L} RLDFLAGS_L ) link_directories(${RLDFLAGS_L} ) endif() if (${RLDFLAGS} MATCHES "[-][l]([^;])+") string(SUBSTRING ${CMAKE_MATCH_0} ${NUM_TRUNC_CHARS} -1 RLDFLAGS_l) string(STRIP ${RLDFLAGS_l} RLDFLAGS_l ) endif() execute_process(COMMAND Rscript -e "Rcpp:::CxxFlags()" OUTPUT_VARIABLE RCPPINCL) string(SUBSTRING ${RCPPINCL} ${NUM_TRUNC_CHARS} -1 RCPPINCL) include_directories(${RCPPINCL}) execute_process(COMMAND Rscript -e "Rcpp:::LdFlags()" OUTPUT_VARIABLE RCPPLIBS) if (${RCPPLIBS} MATCHES "[-][L]([^ ;])+") string(SUBSTRING ${CMAKE_MATCH_0} ${NUM_TRUNC_CHARS} -1 RCPPLIBS_L) link_directories(${RCPPLIBS_L} ) endif() if (${RCPPLIBS} MATCHES "[-][l][R]([^;])+") string(SUBSTRING ${CMAKE_MATCH_0} ${NUM_TRUNC_CHARS} -1 RCPPLIBS_l) endif() execute_process(COMMAND Rscript -e "RInside:::CxxFlags()" OUTPUT_VARIABLE RINSIDEINCL) string(SUBSTRING ${RINSIDEINCL} ${NUM_TRUNC_CHARS} -1 RINSIDEINCL) include_directories(${RINSIDEINCL}) execute_process(COMMAND Rscript -e "RInside:::LdFlags()" OUTPUT_VARIABLE RINSIDELIBS) if (${RINSIDELIBS} MATCHES "[-][L]([^ ;])+") string(SUBSTRING ${CMAKE_MATCH_0} ${NUM_TRUNC_CHARS} -1 RINSIDELIBS_L) link_directories(${RINSIDELIBS_L}) endif() if (${RINSIDELIBS} MATCHES "[-][l][R]([^;])+") string(SUBSTRING ${CMAKE_MATCH_0} ${NUM_TRUNC_CHARS} -1 RINSIDELIBS_l) endif() execute_process(COMMAND R CMD config CXXFLAGS OUTPUT_VARIABLE RCXXFLAGS) execute_process(COMMAND R CMD config BLAS_LIBS OUTPUT_VARIABLE RBLAS) execute_process(COMMAND R CMD config LAPACK_LIBS OUTPUT_VARIABLE RLAPACK) set(CMAKE_CXX_FLAGS "-W -Wall -pedantic -Wextra ${CMAKE_CXX_FLAGS}") if (CMAKE_BUILD_TYPE STREQUAL "DEBUG" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebugInfo" ) add_definitions("-DDEBUG") elseif ( CMAKE_BUILD_TYPE STREQUAL "RELEASE" ) add_definitions("-O3") endif() foreach (next_SOURCE ${sources}) get_filename_component(source_name ${next_SOURCE} NAME_WE) add_executable( ${source_name} ${next_SOURCE} ) target_link_libraries(${source_name} ${RCPPLIBS_l}) target_link_libraries(${source_name} ${RINSIDELIBS_l}) target_link_libraries(${source_name} ${RLDFLAGS_l}) target_link_libraries(${source_name} ${BLAS_LIBS}) target_link_libraries(${source_name} ${LAPACK_LIBS}) target_link_libraries(${source_name} ${MPI_LIBRARIES}) endforeach (next_SOURCE ${sources}) RInside/inst/examples/mpi/GNUmakefile0000644000176200001440000000366612453643755017272 0ustar liggesusers## -*- mode: make; tab-width: 8; -*- ## ## Simple Makefile for MPI use of RInside ## ## TODO: ## proper configure for non-Debian file locations, [ Done ] ## allow RHOME to be set for non-default R etc [ Done ] ## comment this out if you need a different version of R, ## and set set R_HOME accordingly as an environment variable R_HOME := $(shell R RHOME) sources := $(wildcard *.cpp) programs := $(sources:.cpp=) # OpenMPI header and libraries MPICPPFLAGS := $(shell mpic++ -showme:compile) MPILIBS := $(shell mpic++ -showme:link) ## include headers and libraries for R RCPPFLAGS := $(shell $(R_HOME)/bin/R CMD config --cppflags) RLDFLAGS := $(shell $(R_HOME)/bin/R CMD config --ldflags) RBLAS := $(shell $(R_HOME)/bin/R CMD config BLAS_LIBS) RLAPACK := $(shell $(R_HOME)/bin/R CMD config LAPACK_LIBS) ## include headers and libraries for Rcpp interface classes ## note that RCPPLIBS will be empty with Rcpp (>= 0.11.0) and can be omitted RCPPINCL := $(shell echo 'Rcpp:::CxxFlags()' | $(R_HOME)/bin/R --vanilla --slave) RCPPLIBS := $(shell echo 'Rcpp:::LdFlags()' | $(R_HOME)/bin/R --vanilla --slave) ## include headers and libraries for RInside embedding classes RINSIDEINCL := $(shell echo 'RInside:::CxxFlags()' | $(R_HOME)/bin/R --vanilla --slave) RINSIDELIBS := $(shell echo 'RInside:::LdFlags()' | $(R_HOME)/bin/R --vanilla --slave) ## compiler etc settings used in default make rules CXX := $(shell $(R_HOME)/bin/R CMD config CXX) CPPFLAGS := -Wall $(shell $(R_HOME)/bin/R CMD config CPPFLAGS) CXXFLAGS := $(MPICPPFLAGS) $(RCPPFLAGS) $(RCPPINCL) $(RINSIDEINCL) $(shell $(R_HOME)/bin/R CMD config CXXFLAGS) LDLIBS := $(MPILIBS) $(RLDFLAGS) $(RBLAS) $(RLAPACK) $(RCPPLIBS) $(RINSIDELIBS) all : $(programs) @test -x /usr/bin/strip && strip $^ run : $(programs) @test -x /usr/bin/mpirun && for p in $(programs); do echo; echo "Running $$p:"; mpirun -n 4 ./$$p; done clean: rm -vf $(programs) RInside/inst/examples/mpi/rinside_mpi_sample4.cpp0000644000176200001440000000640312257416630021633 0ustar liggesusers// -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 8; -*- // // Simple mpi example: Usage of RInside with a Master-Slave Model with worker // // MPI C API version of file contributed by Nicholas Pezolano and Martin Morgan // // Copyright (C) 2010 - 2013 Dirk Eddelbuettel // Copyright (C) 2013 Nicholas Pezolano // Copyright (C) 2013 Martin Morgan // // GPL'ed #include #include #include #include #include #define WORKTAG 1 #define DIETAG 2 /* Local functions */ static void master(void); static void slave(RInside &R); static int get_next_work_item(int &work, const int size_work, std::vector &data); static void do_work(int work,int &result,RInside &R); static void initalize(RInside &R); int itr = 0; int main(int argc, char **argv){ int myrank; MPI_Init(&argc, &argv); MPI_Comm_rank(MPI_COMM_WORLD, &myrank); RInside R(argc, argv); if (myrank == 0) { master(); } else { initalize(R); slave(R); } MPI_Finalize(); return 0; } static void initalize(RInside &R){ //load the following R library on every R instance std::string R_libs ="suppressMessages(library(random));"; R.parseEvalQ(R_libs); } static void master(void){ int ntasks, rank; std::vector data; int work; int result; int sum; MPI_Status status; //create some test "data" to pass around for(int i = 0; i< 10; i++){ data.push_back(i); } const int size_work = (int)data.size(); MPI_Comm_size(MPI_COMM_WORLD, &ntasks); for (rank = 1; rank < ntasks; ++rank) { get_next_work_item(work,size_work,data); MPI_Send(&work,1,MPI_INT,rank, WORKTAG,MPI_COMM_WORLD); } int ret = get_next_work_item(work,size_work,data); while (ret == 0) { MPI_Recv(&result,1,MPI_INT,MPI_ANY_SOURCE,MPI_ANY_TAG,MPI_COMM_WORLD,&status); sum += result; MPI_Send(&work,1,MPI_INT,status.MPI_SOURCE,WORKTAG,MPI_COMM_WORLD); ret = get_next_work_item(work,size_work,data); } for (rank = 1; rank < ntasks; ++rank) { MPI_Recv(&result, 1, MPI_INT, MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &status); sum += result; } for (rank = 1; rank < ntasks; ++rank) { MPI_Send(0, 0, MPI_INT, rank, DIETAG, MPI_COMM_WORLD); } std::cout << "sum of all iterations = " << sum << std::endl; } static void slave(RInside &R) { int work; int result; MPI_Status status; while (1) { MPI_Recv(&work, 1, MPI_INT, 0, MPI_ANY_TAG, MPI_COMM_WORLD, &status); if (status.MPI_TAG == DIETAG) { return; } do_work(work,result,R); MPI_Send(&result, 1, MPI_INT, 0, 0, MPI_COMM_WORLD); } } static int get_next_work_item(int &work,const int size_work, std::vector &data) { if (itr >= size_work) { return -1; } work = data[itr]; itr++; std::cout << "iteration = " << itr << std::endl; return 0; } static void do_work(int work,int &result,RInside &R){ //create a random number on every slave iteration R["work"] = work; std::string Rcmd = "work <- sample(1:10, 1)"; Rcpp::NumericVector M = R.parseEval(Rcmd); result = M(0); } RInside/inst/examples/mpi/rinside_mpi_sample3.cpp0000644000176200001440000000542412257416630021634 0ustar liggesusers// -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 8; -*- // // Simple mpi example: simulate sampling/averaging on multiple nodes and gathering the results. // // MPI C++ API version of file contributed by Jianping Hua // // Copyright (C) 2010 - 2011 Dirk Eddelbuettel and Romain Francois // // GPL'ed #include // mpi header file #include // for the embedded R via RInside int main(int argc, char *argv[]) { MPI::Init(argc, argv); // mpi initialization int myrank = MPI::COMM_WORLD.Get_rank(); // obtain current node rank int nodesize = MPI::COMM_WORLD.Get_size(); // obtain total nodes running. int sndcnt = 1, rcvcnt = 1; // # of elements in send/recv buffer double sendValue; // value to be collected in current node double *allvalues = new double[nodesize]; // to save all results // simulation info // to sample from a uniform distribution int rangeMin = 0, rangeMax = 10; // range of uniform distribution int sampleSize = 2; // points in each sample try { RInside R(argc, argv); // create an embedded R instance std::stringstream txt; txt << "x <- " << rangeMin << std::endl; R.parseEvalQ( txt.str() ); // assign x with lower range of uniform distribution txt << "y <- " << rangeMax << std::endl; R.parseEvalQ( txt.str() ); // assign y with upper range of uniform distribution txt << "n <- " << sampleSize << std::endl; R.parseEvalQ( txt.str() ); // assign n with the size of sample std::string evalstr = "mean(runif(n,x,y))"; // sampling, compute the mean Rcpp::NumericVector m = R.parseEval(evalstr); // eval str, convert result to NumericVector sendValue = m( 0 ); // assign the return value to the variable to be gathered //gather together values from all processes to allvalues MPI::COMM_WORLD.Gather((const void*)&sendValue, sndcnt, MPI::DOUBLE, (void*)allvalues, rcvcnt, MPI::DOUBLE, 0); // show what inidividual node's contribution std::cout << "node " << myrank << " has mean " << m(0) << std::endl; } catch(std::exception& ex) { std::cerr << "Exception caught: " << ex.what() << std::endl; } catch(...) { std::cerr << "Unknown exception caught" << std::endl; } // show gathered results in node 0 if ( myrank == 0 ) { std::cout << "values of all " << nodesize << " trials: " << std::endl; for ( int i = 0; i < nodesize; i++ ) std::cout << allvalues[ i ] << ", "; std::cout << std::endl; } // clean up delete[] allvalues; MPI::Finalize(); // mpi finalization exit(0); } RInside/inst/examples/mpi/rinside_mpi_sample0.cpp0000644000176200001440000000231012257416630021620 0ustar liggesusers// -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 8; -*- // // Simple example showing in R console information about current node // // This file was contributed by Jianping Hua // // Copyright (C) 2010 - 2011 Jianping Hua, Dirk Eddelbuettel and Romain Francois // // GPL'ed #include // mpi header #include // for the embedded R via RInside int main(int argc, char *argv[]) { // mpi related int myrank, nodesize; // node information MPI_Init(&argc,&argv); // mpi initialization MPI_Comm_rank(MPI_COMM_WORLD, &myrank); // obtain current node rank MPI_Comm_size(MPI_COMM_WORLD, &nodesize); // obtain total nodes running. RInside R(argc, argv); // create an embedded R instance std::stringstream txt; txt << "Hello from node " << myrank // node information << " of " << nodesize << " nodes!" << std::endl; R["txt"] = txt.str(); // assign string var to R variable 'txt' R.parseEvalQ("cat(txt)"); // eval init string, ignoring any returns MPI_Finalize(); // mpi finalization exit(0); } RInside/inst/examples/mpi/rinside_mpi_sample1.cpp0000644000176200001440000000552012257416630021627 0ustar liggesusers// -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 8; -*- // // Simple mpi example: simulate sampling/averaging on multiple nodes and gathering the results. // // This file was contributed by Jianping Hua // // Copyright (C) 2010 - 2011 Jianping Hua, Dirk Eddelbuettel and Romain Francois // // GPL'ed #include // mpi header file #include // for the embedded R via RInside int main(int argc, char *argv[]) { // mpi related int myrank, nodesize; // node information int sndcnt = 1, rcvcnt = 1; // # of elements in send/recv buffer MPI_Init(&argc,&argv); // mpi initialization MPI_Comm_rank(MPI_COMM_WORLD, &myrank); // obtain current node rank MPI_Comm_size(MPI_COMM_WORLD, &nodesize); // obtain total nodes running. double sendValue; // value to be collected in current node double *allvalues = new double[nodesize]; // to save all results // simulation info // to sample from a uniform distribution int rangeMin = 0, rangeMax = 10; // range of uniform distribution int sampleSize = 2; // points in each sample try { RInside R(argc, argv); // create an embedded R instance std::stringstream txt; txt << "x <- " << rangeMin << std::endl; R.parseEvalQ( txt.str() ); // assign x with lower range of uniform distribution txt << "y <- " << rangeMax << std::endl; R.parseEvalQ( txt.str() ); // assign y with upper range of uniform distribution txt << "n <- " << sampleSize << std::endl; R.parseEvalQ( txt.str() ); // assign n with the size of sample std::string evalstr = "mean(runif(n,x,y))"; // sampling, compute the mean Rcpp::NumericVector m = R.parseEval(evalstr); // eval str, convert result to NumericVector sendValue = m( 0 ); // assign the return value to the variable to be gathered //gather together values from all processes to allvalues MPI_Gather(&sendValue, sndcnt, MPI_DOUBLE, allvalues, rcvcnt, MPI_DOUBLE, 0, MPI_COMM_WORLD); // show what inidividual node's contribution std::cout << "node " << myrank << " has mean " << m(0) << std::endl; } catch(std::exception& ex) { std::cerr << "Exception caught: " << ex.what() << std::endl; } catch(...) { std::cerr << "Unknown exception caught" << std::endl; } // show gathered results in node 0 if ( myrank == 0 ) { std::cout << "values of all " << nodesize << " trials: " << std::endl; for ( int i = 0; i < nodesize; i++ ) std::cout << allvalues[ i ] << ", "; std::cout << std::endl; } // clean up delete[] allvalues; MPI_Finalize(); // mpi finalization exit(0); } RInside/inst/examples/wt/0000755000176200001440000000000012656102730015036 5ustar liggesusersRInside/inst/examples/wt/wtdensity.cpp0000644000176200001440000002045712257416630017610 0ustar liggesusers// -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 8; -*- // // Wt usage example for RInside, inspired by the standard 'density sliders' example // // Copyright (C) 2011 Dirk Eddelbuettel and Romain Francois // // This file is licensed under GPL 2 or later, as are the rest of RInside and Rcpp // // Derived from hello.C in the Wt sources // Copyright (C) 2008 Emweb bvba, Heverlee, Belgium. #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace Wt; class DensityApp : public WApplication { public: DensityApp(const WEnvironment& env, RInside & R); private: WLineEdit *codeEdit_; // to edit the RNG draw expression WButtonGroup *group_; // holds the radiobuttons WSpinBox *spin_; // selects the density bandwidth WImage *img_; // displays the image WFileResource *imgfile_; // controls the file resources WText *greeting_; // text label for status message void reportButton(); // called when new button selected void reportEdit(); // called when RNG expression edited void reportSpinner(); // called when bandwidth changed void plot(); // to call R for new plot enum Kernel { Gaussian = 0, Epanechnikov = 1, Rectangular = 2, Triangular = 3, Cosine = 4 }; RInside & R_; // reference to embedded R instance std::string tempfile_; // name of file used by R for plots int bw_, kernel_; // parameters used to estimate the density std::string cmd_; // random draw command string Rcpp::NumericVector Yvec_; // the random draw }; // The env argument contains information about the new session, and the initial request. // It must be passed to the WApplication // constructor so it is typically also an argument // for your custom application constructor. DensityApp::DensityApp(const WEnvironment& env, RInside & R) : WApplication(env), R_(R) { setTitle("Witty WebApp With RInside"); // application title setCssTheme("polished"); messageResourceBundle().use(appRoot() + "wtdensity"); new WText(WString::tr("overview"), root()); std::string tfcmd = "tfile <- tempfile(pattern=\"img\", tmpdir=\"/tmp\", fileext=\".png\")"; tempfile_ = Rcpp::as(R_.parseEval(tfcmd)); // assign to 'tfile' in R, and report back bw_ = 100; kernel_ = 0; // parameters used to estimate the density cmd_ = "c(rnorm(100,0,1), rnorm(50,5,1))"; // random draw command string new WText(WString::tr("user input"), root()); Wt::WContainerWidget *wc = new Wt::WContainerWidget(root()); wc->setStyleClass("box"); Wt::WHBoxLayout *layout = new Wt::WHBoxLayout(); Wt::WContainerWidget *midbox = new Wt::WContainerWidget(root()); layout->addWidget(midbox); Wt::WContainerWidget *container = new Wt::WContainerWidget(root()); layout->addWidget(container); wc->setLayout(layout, AlignTop | AlignJustify); midbox->addWidget(new WText("Density estimation scale factor (div. by 100)")); midbox->addWidget(new WBreak()); // insert a line break spin_ = new WSpinBox(midbox); spin_->setRange(5, 200); spin_->setValue(bw_); spin_->valueChanged().connect(this, &DensityApp::reportSpinner); midbox->addWidget(new WBreak()); // insert a line break midbox->addWidget(new WText("R Command for data generation")); // show some text midbox->addWidget(new WBreak()); // insert a line break codeEdit_ = new WLineEdit(midbox); // allow text input codeEdit_->setTextSize(30); codeEdit_->setText(cmd_); codeEdit_->setFocus(); // give focus codeEdit_->enterPressed().connect(this, &DensityApp::reportEdit); group_ = new Wt::WButtonGroup(container); // use button group to arrange radio buttons Wt::WRadioButton *button; button = new Wt::WRadioButton("Gaussian", container); new Wt::WBreak(container); group_->addButton(button, Gaussian); button = new Wt::WRadioButton("Epanechnikov", container); new Wt::WBreak(container); group_->addButton(button, Epanechnikov); button = new Wt::WRadioButton("Rectangular", container); new Wt::WBreak(container); group_->addButton(button, Rectangular); button = new Wt::WRadioButton("Triangular", container); new Wt::WBreak(container); group_->addButton(button, Triangular); button = new Wt::WRadioButton("Cosine", container); new Wt::WBreak(container); group_->addButton(button, Cosine); group_->setCheckedButton(group_->button(kernel_)); group_->checkedChanged().connect(this, &DensityApp::reportButton); new WText(WString::tr("r result"), root()); Wt::WContainerWidget *botbox = new Wt::WContainerWidget(root()); botbox->setStyleClass("box"); imgfile_ = new Wt::WFileResource("image/png", tempfile_); imgfile_->suggestFileName("density.png"); // name the clients sees of datafile img_ = new Wt::WImage(imgfile_, "PNG version", botbox); new WText(WString::tr("browser info"), root()); Wt::WContainerWidget *stbox = new Wt::WContainerWidget(root()); stbox->setStyleClass("box"); greeting_ = new WText(stbox); // empty text greeting_->setText("Setting up..."); useStyleSheet("wtdensity.css"); // set our style sheet last reportEdit(); // create a new RNG draw in Yvec_ plot(); // and draw a new density plot } void DensityApp::reportButton() { kernel_ = group_->checkedId(); // get id of selected kernel plot(); } void DensityApp::reportEdit() { cmd_ = codeEdit_->text().toUTF8(); // get text written in box, as UTF-8, assigned to string std::string rng = "y2 <- " + cmd_ + "; y <- y2"; R_.parseEvalQNT(rng); // evaluates expression, assigns to 'y' Yvec_ = R_["y"]; // cache the y vector plot(); } void DensityApp::reportSpinner() { bw_ = spin_->value(); // get the value of the spin selector plot(); } void DensityApp::plot() { const char *kernelstr[] = { "gaussian", "epanechnikov", "rectangular", "triangular", "cosine" }; greeting_->setText("Starting R call"); R_["tfile"] = tempfile_; R_["bw"] = bw_; R_["kernel"] = kernelstr[kernel_]; // passes the string to R R_["y"] = Yvec_; std::string cmd0 = "png(filename=tfile,width=600,height=400); plot(density(y, bw=bw/100, kernel=kernel), xlim=range(y)+c(-2,2), main=\"Kernel: "; std::string cmd1 = "\"); points(y, rep(0, length(y)), pch=16, col=rgb(0,0,0,1/4)); dev.off()"; std::string cmd = cmd0 + kernelstr[kernel_] + cmd1; // stick the selected kernel in the middle R_.parseEvalQ(cmd); // evaluate command -- generates new density plot imgfile_->setChanged(); // important: tells consumer that image has changed, forces refresh greeting_->setText("Finished request from " + this->environment().clientAddress() + " using " + this->environment().userAgent()) ; } WApplication *createApplication(const WEnvironment& env) { // You could read information from the environment to decide whether // the user has permission to start a new application // // We grab an instance of the embedded R. Note we can start only one, // so resource conflicts have to be managed (eg add mutexes etc) // return new DensityApp(env, RInside::instance()); } int main(int argc, char **argv) { RInside R(argc, argv); // create the one embedded R instance // Your main method may set up some shared resources, but should then // start the server application (FastCGI or httpd) that starts listening // for requests, and handles all of the application life cycles. // // The last argument to WRun specifies the function that will instantiate // new application objects. That function is executed when a new user surfs // to the Wt application, and after the library has negotiated browser // support. The function should return a newly instantiated application // object. return WRun(argc, argv, createApplication); } RInside/inst/examples/wt/cmake/0000755000176200001440000000000012257416630016122 5ustar liggesusersRInside/inst/examples/wt/cmake/CMakeLists.txt0000644000176200001440000000626112257416630020667 0ustar liggesuserscmake_minimum_required(VERSION 2.8.4) set (SRC_DIR ${CMAKE_CURRENT_SOURCE_DIR}/..) execute_process(COMMAND R RHOME OUTPUT_VARIABLE R_HOME) file(GLOB sources ${SRC_DIR}/*.cpp) set(NUM_TRUNC_CHARS 2) execute_process(COMMAND R CMD config --cppflags OUTPUT_VARIABLE RCPPFLAGS) string(SUBSTRING ${RCPPFLAGS} ${NUM_TRUNC_CHARS} -1 RCPPFLAGS) include_directories(${RCPPFLAGS}) execute_process(COMMAND R CMD config --ldflags OUTPUT_VARIABLE RLDFLAGS) string(LENGTH ${RLDFLAGS} RLDFLAGS_LEN) if (${RLDFLAGS} MATCHES "[-][L]([^ ;])+") string(SUBSTRING ${CMAKE_MATCH_0} ${NUM_TRUNC_CHARS} -1 RLDFLAGS_L) string(STRIP ${RLDFLAGS_L} RLDFLAGS_L ) link_directories(${RLDFLAGS_L} ) endif() if (${RLDFLAGS} MATCHES "[-][l]([^;])+") string(SUBSTRING ${CMAKE_MATCH_0} ${NUM_TRUNC_CHARS} -1 RLDFLAGS_l) string(STRIP ${RLDFLAGS_l} RLDFLAGS_l ) endif() execute_process(COMMAND Rscript -e "Rcpp:::CxxFlags()" OUTPUT_VARIABLE RCPPINCL) string(SUBSTRING ${RCPPINCL} ${NUM_TRUNC_CHARS} -1 RCPPINCL) include_directories(${RCPPINCL}) execute_process(COMMAND Rscript -e "Rcpp:::LdFlags()" OUTPUT_VARIABLE RCPPLIBS) if (${RCPPLIBS} MATCHES "[-][L]([^ ;])+") string(SUBSTRING ${CMAKE_MATCH_0} ${NUM_TRUNC_CHARS} -1 RCPPLIBS_L) link_directories(${RCPPLIBS_L} ) endif() if (${RCPPLIBS} MATCHES "[-][l][R]([^;])+") string(SUBSTRING ${CMAKE_MATCH_0} ${NUM_TRUNC_CHARS} -1 RCPPLIBS_l) endif() execute_process(COMMAND Rscript -e "RInside:::CxxFlags()" OUTPUT_VARIABLE RINSIDEINCL) string(SUBSTRING ${RINSIDEINCL} ${NUM_TRUNC_CHARS} -1 RINSIDEINCL) include_directories(${RINSIDEINCL}) execute_process(COMMAND Rscript -e "RInside:::LdFlags()" OUTPUT_VARIABLE RINSIDELIBS) if (${RINSIDELIBS} MATCHES "[-][L]([^ ;])+") string(SUBSTRING ${CMAKE_MATCH_0} ${NUM_TRUNC_CHARS} -1 RINSIDELIBS_L) link_directories(${RINSIDELIBS_L}) endif() if (${RINSIDELIBS} MATCHES "[-][l][R]([^;])+") string(SUBSTRING ${CMAKE_MATCH_0} ${NUM_TRUNC_CHARS} -1 RINSIDELIBS_l) endif() execute_process(COMMAND R CMD config CXXFLAGS OUTPUT_VARIABLE RCXXFLAGS) execute_process(COMMAND R CMD config BLAS_LIBS OUTPUT_VARIABLE RBLAS) execute_process(COMMAND R CMD config LAPACK_LIBS OUTPUT_VARIABLE RLAPACK) set(CMAKE_CXX_FLAGS "-W -Wall -pedantic -Wextra ${CMAKE_CXX_FLAGS}") if (CMAKE_BUILD_TYPE STREQUAL "DEBUG" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebugInfo" ) add_definitions("-DDEBUG") elseif ( CMAKE_BUILD_TYPE STREQUAL "RELEASE" ) add_definitions("-O3") endif() foreach (next_SOURCE ${sources}) get_filename_component(source_name ${next_SOURCE} NAME_WE) add_executable( ${source_name} ${next_SOURCE} ) target_link_libraries(${source_name} ${RCPPLIBS_l}) target_link_libraries(${source_name} ${RINSIDELIBS_l}) target_link_libraries(${source_name} ${RLDFLAGS_l}) target_link_libraries(${source_name} ${BLAS_LIBS}) target_link_libraries(${source_name} ${LAPACK_LIBS}) target_link_libraries(${source_name} "wt") target_link_libraries(${source_name} "wthttp") target_link_libraries(${source_name} "boost_signals") endforeach (next_SOURCE ${sources}) RInside/inst/examples/wt/wtdensity.xml0000644000176200001440000000443412257416630017623 0ustar liggesusers
The data file "{1}" could not be found. Check your deployment.

Overview

This example demonstrates some of the capabilities of the the Wt library, in combination with the RInside classes for embedding the R statistical language and environment.

It reimplements a standard GUI / application setting: drawing from a random distribution, and estimation a non-parametric density for which the user selects the kernel and bandwidth. RInside already contains an example of this using Qt to provide a standard application.

Here we show how to do the same in a web application which, thanks to the abstractions provided by the Wt, is rather straightforward.

User Input for Density Estimation

User Input for Density Estimation

The user can select a bandwidth factor (to be divided by 100), an R expression to generate data (with a default for a mixture distributions) and a kernel function.

Resulting R Chart

Resulting R Chart

The chart below is created by R given the selected user input.

Browser Information

Browser Information

The string below is provided by the client's browser and often reveals operating system and IP address.

RInside/inst/examples/wt/GNUmakefile0000644000176200001440000000465412656102512017117 0ustar liggesusers ## This Makefile is __very__ barebones with respect to Wt. ## ## It works on Debian/Ubuntu. On other systems, add -I and -L flags as needed. See the cmake use in Wt. ## comment this out if you need a different version of R, ## and set set R_HOME accordingly as an environment variable R_HOME := $(shell R RHOME) ## include headers and libraries for R RCPPFLAGS := $(shell $(R_HOME)/bin/R CMD config --cppflags) RLDFLAGS := $(shell $(R_HOME)/bin/R CMD config --ldflags) RBLAS := $(shell $(R_HOME)/bin/R CMD config BLAS_LIBS) RLAPACK := $(shell $(R_HOME)/bin/R CMD config LAPACK_LIBS) ## if you need to set an rpath to R itself, also uncomment #RRPATH := -Wl,-rpath,$(R_HOME)/lib ## include headers and libraries for Rcpp interface classes RCPPINCL := $(shell echo 'Rcpp:::CxxFlags()' | $(R_HOME)/bin/R --vanilla --slave) RCPPLIBS := $(shell echo 'Rcpp:::LdFlags()' | $(R_HOME)/bin/R --vanilla --slave) ## include headers and libraries for RInside embedding classes ## note that RCPPLIBS will be empty with Rcpp (>= 0.11.0) and can be omitted RINSIDEINCL := $(shell echo 'RInside:::CxxFlags()' | $(R_HOME)/bin/R --vanilla --slave) RINSIDELIBS := $(shell echo 'RInside:::LdFlags()' | $(R_HOME)/bin/R --vanilla --slave) ## minimal Wt libs -- works for me on Ubuntu, may need -L switches elsewhere... WITTYLIBS := -lwt -lwthttp -lboost_signals -lboost_system ## compiler etc settings used in default make rules CXX := $(shell $(R_HOME)/bin/R CMD config CXX) CPPFLAGS := -Wall $(shell $(R_HOME)/bin/R CMD config CPPFLAGS) CXXFLAGS := $(RCPPFLAGS) $(RCPPINCL) $(RINSIDEINCL) $(shell $(R_HOME)/bin/R CMD config CXXFLAGS) LDLIBS := $(RLDFLAGS) $(RRPATH) $(RBLAS) $(RLAPACK) $(RCPPLIBS) $(RINSIDELIBS) $(WITTYLIBS) all: wtdensity wtdensityPlain wtdensityPlain: wtdensityPlain.cpp $(CXX) $(CPPFLAGS) $(CXXFLAGS) -o $@ $^ $(LDLIBS) strip $@ wtdensity: wtdensity.cpp $(CXX) $(CPPFLAGS) $(CXXFLAGS) -o $@ $^ $(LDLIBS) strip $@ run: wtdensity ## Wt resources location on Debian/Ubuntu; adjust as needed test -L resources || ln -s /usr/lib/Wt/resources . ./$< --docroot "." --http-addr 127.0.0.1 --http-port 8080 runPlain: wtdensityPlain ## Wt resources location on Debian/Ubuntu; adjust as needed test -L resources || ln -s /usr/lib/Wt/resources . ./$< --docroot "." --http-addr 127.0.0.1 --http-port 8081 clean: rm -f wtdensity wtdensityPlain resources RInside/inst/examples/wt/wtdensity.css0000644000176200001440000000051212257416630017604 0ustar liggesusersbody, html { font-family: verdana,helvetica,tahoma,sans-serif; } p.p { margin: 16px 0px; font-size: smaller; } .box { margin: 5px 20px; font-size: smaller; font-family: sans-serif; } h2 { padding-left: 30px; border-bottom: 1px solid #000; font-size: larger; } h2 span { border-bottom: 0.2em solid #000; } RInside/inst/examples/wt/wtdensityPlain.cpp0000644000176200001440000001754512257416630020600 0ustar liggesusers// -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 8; -*- // // Wt usage example for RInside, inspired by the standard 'density sliders' example // // Copyright (C) 2011 Dirk Eddelbuettel and Romain Francois // // This file is licensed under GPL 2 or later, as are the rest of RInside and Rcpp // // Derived from hello.C in the Wt sources // Copyright (C) 2008 Emweb bvba, Heverlee, Belgium. #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace Wt; class DensityApp : public WApplication { public: DensityApp(const WEnvironment& env, RInside & R); private: WLineEdit *codeEdit_; // to edit the RNG draw expression WButtonGroup *group_; // holds the radiobuttons WSpinBox *spin_; // selects the density bandwidth WImage *img_; // displays the image WFileResource *imgfile_; // controls the file resources WText *greeting_; // text label for status message void reportButton(); // called when new button selected void reportEdit(); // called when RNG expression edited void reportSpinner(); // called when bandwidth changed void plot(); // to call R for new plot enum Kernel { Gaussian = 0, Epanechnikov = 1, Rectangular = 2, Triangular = 3, Cosine = 4 }; RInside & R_; // reference to embedded R instance std::string tempfile_; // name of file used by R for plots int bw_, kernel_; // parameters used to estimate the density std::string cmd_; // random draw command string Rcpp::NumericVector Yvec_; // the random draw }; // The env argument contains information about the new session, and the initial request. // It must be passed to the WApplication // constructor so it is typically also an argument // for your custom application constructor. DensityApp::DensityApp(const WEnvironment& env, RInside & R) : WApplication(env), R_(R) { setTitle("Witty WebApp With RInside"); // application title std::string tfcmd = "tfile <- tempfile(pattern=\"img\", tmpdir=\"/tmp\", fileext=\".png\")"; tempfile_ = Rcpp::as(R_.parseEval(tfcmd)); // assign to 'tfile' in R, and report back bw_ = 100; kernel_ = 0; // parameters used to estimate the density cmd_ = "c(rnorm(100,0,1), rnorm(50,5,1))"; // random draw command string Wt::WGroupBox *wc = new Wt::WGroupBox("Density Estimation", root()); Wt::WHBoxLayout *layout = new Wt::WHBoxLayout(); Wt::WContainerWidget *midbox = new Wt::WContainerWidget(root()); layout->addWidget(midbox); Wt::WContainerWidget *container = new Wt::WContainerWidget(root()); layout->addWidget(container); wc->setLayout(layout, AlignTop | AlignJustify); midbox->addWidget(new WText("Density estimation scale factor (div. by 100)")); midbox->addWidget(new WBreak()); // insert a line break spin_ = new WSpinBox(midbox); spin_->setRange(5, 200); spin_->setValue(bw_); spin_->valueChanged().connect(this, &DensityApp::reportSpinner); midbox->addWidget(new WBreak()); // insert a line break midbox->addWidget(new WText("R Command for data generation")); // show some text midbox->addWidget(new WBreak()); // insert a line break codeEdit_ = new WLineEdit(midbox); // allow text input codeEdit_->setTextSize(30); codeEdit_->setText(cmd_); codeEdit_->setFocus(); // give focus codeEdit_->enterPressed().connect(this, &DensityApp::reportEdit); group_ = new Wt::WButtonGroup(container); // use button group to arrange radio buttons Wt::WRadioButton *button; button = new Wt::WRadioButton("Gaussian", container); new Wt::WBreak(container); group_->addButton(button, Gaussian); button = new Wt::WRadioButton("Epanechnikov", container); new Wt::WBreak(container); group_->addButton(button, Epanechnikov); button = new Wt::WRadioButton("Rectangular", container); new Wt::WBreak(container); group_->addButton(button, Rectangular); button = new Wt::WRadioButton("Triangular", container); new Wt::WBreak(container); group_->addButton(button, Triangular); button = new Wt::WRadioButton("Cosine", container); new Wt::WBreak(container); group_->addButton(button, Cosine); group_->setCheckedButton(group_->button(kernel_)); group_->checkedChanged().connect(this, &DensityApp::reportButton); Wt::WGroupBox *botbox = new Wt::WGroupBox("Resulting chart", root()); imgfile_ = new Wt::WFileResource("image/png", tempfile_); imgfile_->suggestFileName("density.png"); // name the clients sees of datafile img_ = new Wt::WImage(imgfile_, "PNG version", botbox); Wt::WGroupBox *stbox = new Wt::WGroupBox("Status", root()); greeting_ = new WText(stbox); // empty text greeting_->setText("Setting up..."); reportEdit(); // create a new RNG draw in Yvec_ plot(); // and draw a new density plot } void DensityApp::reportButton() { kernel_ = group_->checkedId(); // get id of selected kernel plot(); } void DensityApp::reportEdit() { cmd_ = codeEdit_->text().toUTF8(); // get text written in box, as UTF-8, assigned to string std::string rng = "y <- " + cmd_ + ";"; R_.parseEvalQ(rng); // evaluates expression, assigns to 'y' Yvec_ = R_["y"]; // cache the y vector plot(); } void DensityApp::reportSpinner() { bw_ = spin_->value(); // get the value of the spin selector plot(); } void DensityApp::plot() { const char *kernelstr[] = { "gaussian", "epanechnikov", "rectangular", "triangular", "cosine" }; greeting_->setText("Starting R call"); R_["tfile"] = tempfile_; R_["bw"] = bw_; R_["kernel"] = kernelstr[kernel_]; // passes the string to R R_["y"] = Yvec_; std::string cmd0 = "png(filename=tfile,width=600,height=400); plot(density(y, bw=bw/100, kernel=kernel), xlim=range(y)+c(-2,2), main=\"Kernel: "; std::string cmd1 = "\"); points(y, rep(0, length(y)), pch=16, col=rgb(0,0,0,1/4)); dev.off()"; std::string cmd = cmd0 + kernelstr[kernel_] + cmd1; // stick the selected kernel in the middle R_.parseEvalQ(cmd); // evaluate command -- generates new density plot imgfile_->setChanged(); // important: tells consumer that image has changed, forces refresh greeting_->setText("Finished request from " + this->environment().clientAddress() + " using " + this->environment().userAgent()) ; } WApplication *createApplication(const WEnvironment& env) { // You could read information from the environment to decide whether // the user has permission to start a new application // // We grab an instance of the embedded R. Note we can start only one, // so resource conflicts have to be managed (eg add mutexes etc) // return new DensityApp(env, RInside::instance()); } int main(int argc, char **argv) { RInside R(argc, argv); // create the one embedded R instance // Your main method may set up some shared resources, but should then // start the server application (FastCGI or httpd) that starts listening // for requests, and handles all of the application life cycles. // // The last argument to WRun specifies the function that will instantiate // new application objects. That function is executed when a new user surfs // to the Wt application, and after the library has negotiated browser // support. The function should return a newly instantiated application // object. return WRun(argc, argv, createApplication); } RInside/inst/examples/armadillo/0000755000176200001440000000000012453643755016364 5ustar liggesusersRInside/inst/examples/armadillo/cmake/0000755000176200001440000000000012257416630017434 5ustar liggesusersRInside/inst/examples/armadillo/cmake/CMakeLists.txt0000644000176200001440000001354012257416630022177 0ustar liggesuserscmake_minimum_required(VERSION 2.8.4) set (VERBOSE 1) set (SRC_DIR ${CMAKE_CURRENT_SOURCE_DIR}/..) execute_process(COMMAND R RHOME OUTPUT_VARIABLE R_HOME) file(GLOB sources ${SRC_DIR}/*.cpp) set(NUM_TRUNC_CHARS 2) set (RPATH "R") set (RSCRIPT_PATH "Rscript") if (CMAKE_HOST_WIN32) execute_process(COMMAND ${RSCRIPT_PATH} -e "cat(.Platform$r_arch)" OUTPUT_VARIABLE R_ARCH) execute_process(COMMAND R --arch ${R_ARCH} RHOME OUTPUT_VARIABLE R_HOME) string(REPLACE "\\" "/" R_HOME ${R_HOME}) set (RPATH ${R_HOME}/bin/R) endif() set (RCPPFLAGS_CMD " ${RPATH} " " CMD " " config " " --cppflags ") execute_process(COMMAND ${RPATH} CMD config --cppflags OUTPUT_VARIABLE RCPPFLAGS) if (CMAKE_HOST_WIN32) if (${RCPPFLAGS} MATCHES "[-][I]([^ ;])+") set (RCPPFLAGS ${CMAKE_MATCH_0}) endif() endif() string(SUBSTRING ${RCPPFLAGS} ${NUM_TRUNC_CHARS} -1 RCPPFLAGS) include_directories(${RCPPFLAGS}) execute_process(COMMAND ${RPATH} CMD config --ldflags OUTPUT_VARIABLE RLDFLAGS) string(LENGTH ${RLDFLAGS} RLDFLAGS_LEN) if (${RLDFLAGS} MATCHES "[-][L]([^ ;])+") string(SUBSTRING ${CMAKE_MATCH_0} ${NUM_TRUNC_CHARS} -1 RLDFLAGS_L) string(STRIP ${RLDFLAGS_L} RLDFLAGS_L ) link_directories(${RLDFLAGS_L} ) endif() if (${RLDFLAGS} MATCHES "[-][l]([^;])+") string(SUBSTRING ${CMAKE_MATCH_0} ${NUM_TRUNC_CHARS} -1 RLDFLAGS_l) string(STRIP ${RLDFLAGS_l} RLDFLAGS_l ) endif() execute_process(COMMAND ${RSCRIPT_PATH} -e "Rcpp:::CxxFlags()" OUTPUT_VARIABLE RCPPINCL) string(SUBSTRING ${RCPPINCL} ${NUM_TRUNC_CHARS} -1 RCPPINCL) include_directories(${RCPPINCL}) execute_process(COMMAND ${RSCRIPT_PATH} -e "Rcpp:::LdFlags()" OUTPUT_VARIABLE RCPPLIBS) execute_process(COMMAND ${RSCRIPT_PATH} -e "RInside:::CxxFlags()" OUTPUT_VARIABLE RINSIDEINCL) string(SUBSTRING ${RINSIDEINCL} ${NUM_TRUNC_CHARS} -1 RINSIDEINCL) include_directories(${RINSIDEINCL}) message(${RINSIDEINCL}) execute_process(COMMAND ${RSCRIPT_PATH} -e "RInside:::LdFlags()" OUTPUT_VARIABLE RINSIDELIBS) execute_process(COMMAND ${RSCRIPT_PATH} -e "RcppArmadillo:::CxxFlags()" OUTPUT_VARIABLE RCPPARMADILLOINCL) string(LENGTH ${RCPPARMADILLOINCL} INCLLENGTH) math(EXPR INCLLENGTH "${INCLLENGTH}-4") string(SUBSTRING ${RCPPARMADILLOINCL} 3 ${INCLLENGTH} RCPPARMADILLOINCL) include_directories(${RCPPARMADILLOINCL}) if (CMAKE_HOST_WIN32) string(LENGTH "libRcpp.a" lenRcppName) string(LENGTH ${RCPPLIBS} lenRcppFQName) math(EXPR RLibPathLen ${lenRcppFQName}-${lenRcppName}-1) string(SUBSTRING ${RCPPLIBS} 0 ${RLibPathLen} RCPPLIBS_L) link_directories(${RCPPLIBS_L}) math(EXPR RLibPathLen ${RLibPathLen}+1) string(SUBSTRING ${RCPPLIBS} ${RLibPathLen} -1 RCPPLIBS_l) #Remove the quotes string(SUBSTRING ${RINSIDELIBS} 1 -1 RINSIDELIBS) string(LENGTH ${RINSIDELIBS} lenRInsideFQNameLen) math(EXPR lenRInsideFQNameLen ${lenRInsideFQNameLen}-1) string(SUBSTRING ${RINSIDELIBS} 0 ${lenRInsideFQNameLen} RINSIDELIBS) string(LENGTH "libRInside.a" lenRInsideName) string(LENGTH ${RINSIDELIBS} lenRInsideFQName) math(EXPR RLibPathLen ${lenRInsideFQName}-${lenRInsideName}-1) string(SUBSTRING ${RINSIDELIBS} 0 ${RLibPathLen} RINSIDELIBS_L) math(EXPR RLibPathLen ${RLibPathLen}+1) string(SUBSTRING ${RINSIDELIBS} ${RLibPathLen} -1 RINSIDELIBS_l) link_directories(${RINSIDELIBS_L}) set ( BLAS_LIBS ${CMAKE_CURRENT_SOURCE_DIR}/libblas.lib) set ( LAPACK_LIBRARY ${CMAKE_CURRENT_SOURCE_DIR}/liblapack.lib) link_directories(${CMAKE_CURRENT_SOURCE_DIR}) else() if (${RCPPLIBS} MATCHES "[-][L]([^ ;])+") string(SUBSTRING ${CMAKE_MATCH_0} ${NUM_TRUNC_CHARS} -1 RCPPLIBS_L) link_directories(${RCPPLIBS_L} ) endif() if (${RCPPLIBS} MATCHES "[-][l][R]([^;])+") string(SUBSTRING ${CMAKE_MATCH_0} ${NUM_TRUNC_CHARS} -1 RCPPLIBS_l) endif() if (${RINSIDELIBS} MATCHES "[-][L]([^ ;])+") string(SUBSTRING ${CMAKE_MATCH_0} ${NUM_TRUNC_CHARS} -1 RINSIDELIBS_L) link_directories(${RINSIDELIBS_L}) endif() if (${RINSIDELIBS} MATCHES "[-][l][R]([^;])+") string(SUBSTRING ${CMAKE_MATCH_0} ${NUM_TRUNC_CHARS} -1 RINSIDELIBS_l) endif() # If the faster 'gold' linker is used, to avoid complaints about undefined symbol SET(CMAKE_FIND_LIBRARY_SUFFIXES_SAVED ${CMAKE_FIND_LIBRARY_SUFFIXES}) # Backup LIST(APPEND CMAKE_FIND_LIBRARY_SUFFIXES ".so.3") FIND_LIBRARY(BLAS_LIBRARY blas) SET(CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES_SAVED}) # Restore LIST(APPEND EXTRA_LIBRARIES ${BLAS_LIBRARY}) FIND_LIBRARY(LAPACK_LIBRARY lapack) endif() execute_process(COMMAND ${RPATH} CMD config CXXFLAGS OUTPUT_VARIABLE RCXXFLAGS) execute_process(COMMAND ${RPATH} CMD config BLAS_LIBS OUTPUT_VARIABLE RBLAS) execute_process(COMMAND ${RPATH} CMD config LAPACK_LIBS OUTPUT_VARIABLE RLAPACK) set(CMAKE_CXX_FLAGS "-W -Wall -pedantic -Wextra ${CMAKE_CXX_FLAGS}") if (CMAKE_BUILD_TYPE STREQUAL "DEBUG" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebugInfo" ) add_definitions("-DDEBUG") elseif ( CMAKE_BUILD_TYPE STREQUAL "RELEASE" ) add_definitions("-O3") endif() message ("cmake_cxx_flags" ${CMAKE_CXX_FLAGS}) foreach (next_SOURCE ${sources}) get_filename_component(source_name ${next_SOURCE} NAME_WE) add_executable( ${source_name} ${next_SOURCE} ) target_link_libraries(${source_name} ${RLDFLAGS_l}) target_link_libraries(${source_name} ${BLAS_LIBS}) target_link_libraries(${source_name} ${LAPACK_LIBS}) target_link_libraries(${source_name} ${RINSIDELIBS_l}) target_link_libraries(${source_name} ${RCPPLIBS_l}) target_link_libraries(${source_name} ${EXTRA_LIBRARIES}) target_link_libraries(${source_name} ${LAPACK_LIBRARY}) endforeach (next_SOURCE ${sources}) RInside/inst/examples/armadillo/cmake/WIN.readme.txt0000644000176200001440000000244312257416630022071 0ustar liggesusers Building these examples on Windows is a bit more difficult than on Linux. * Put R in the path: C:\R\R-2.1X.X\bin C:\R\R-2.1X.X\bin\i386 * Add required environment variables: R_HOME C:\R\R-2.1X.X CYGWIN nodosfilewarning * Then libpack and libblas for Windows needed to be obtained from: http://icl.cs.utk.edu/lapack-for-windows/lapack/index.html#libraries_mingw * The CMakeLists.txt files expect the liblapack.lib and libblas.lib files to be in the same directory as themselves for the Windows build. You can edit lines 7 and 8 of the the CMakeLists.txt files if they are not in this location. * I generally build in a 'build' directly below cmake: mkdir build cd build cmake -G "Unix Makefiles" ../. make To run these example there are further DLL dependencies required not installed by RTools: libgcc_s_dw2-1.dll libgfortran.dll libquadmath-0.dll liblapack.dll I was able to grab these by installing MinGW from: http://sourceforge.net/projects/mingw/files/MinGW/Base/gcc/Version4/ Use the version that matches the gcc version that is installed by RTools. Once installed, either add their location to the PATH, or copy them to either the same directory as the example executable, or put them in the windows/system32 folder. Peter peter dot aberline at gmail dot com RInside/inst/examples/armadillo/rinside_arma0.cpp0000644000176200001440000000121712257416630021576 0ustar liggesusers// -*- c-indent-level: 4; c-basic-offset: 4; indent-tabs-mode: nil; -*- // // Simple example using Armadillo classes // // Copyright (C) 2012 - 2013 Dirk Eddelbuettel and Romain Francois #include // for Armadillo as well as Rcpp #include // for the embedded R via RInside int main(int argc, char *argv[]) { RInside R(argc, argv); // create an embedded R instance std::string cmd = "diag(3)"; // create a Matrix in r arma::mat m = Rcpp::as(R.parseEval(cmd)); // parse, eval + return result std::cout << m << std::endl; // and use Armadillo i/o exit(0); } RInside/inst/examples/armadillo/GNUmakefile0000644000176200001440000000364312453643755020444 0ustar liggesusers## -*- mode: make; tab-width: 8; -*- ## ## Simple Makefile ## comment this out if you need a different version of R, ## and set set R_HOME accordingly as an environment variable R_HOME := $(shell R RHOME) sources := $(wildcard *.cpp) programs := $(sources:.cpp=) ## include headers and libraries for R RCPPFLAGS := $(shell $(R_HOME)/bin/R CMD config --cppflags) RLDFLAGS := $(shell $(R_HOME)/bin/R CMD config --ldflags) RBLAS := $(shell $(R_HOME)/bin/R CMD config BLAS_LIBS) RLAPACK := $(shell $(R_HOME)/bin/R CMD config LAPACK_LIBS) ## if you need to set an rpath to R itself, also uncomment #RRPATH := -Wl,-rpath,$(R_HOME)/lib ## include headers and libraries for Rcpp interface classes ## note that RCPPLIBS will be empty with Rcpp (>= 0.11.0) and can be omitted RCPPINCL := $(shell echo 'Rcpp:::CxxFlags()' | $(R_HOME)/bin/R --vanilla --slave) RCPPLIBS := $(shell echo 'Rcpp:::LdFlags()' | $(R_HOME)/bin/R --vanilla --slave) ## include headers and libraries for RInside embedding classes RINSIDEINCL := $(shell echo 'RInside:::CxxFlags()' | $(R_HOME)/bin/R --vanilla --slave) RINSIDELIBS := $(shell echo 'RInside:::LdFlags()' | $(R_HOME)/bin/R --vanilla --slave) ## RcppArmadillo headers RCPPARMAINCL := $(shell echo 'RcppArmadillo:::CxxFlags()' | $(R_HOME)/bin/R --vanilla --slave) ## compiler etc settings used in default make rules CXX := $(shell $(R_HOME)/bin/R CMD config CXX) CPPFLAGS := -Wall $(shell $(R_HOME)/bin/R CMD config CPPFLAGS) CXXFLAGS := $(RCPPFLAGS) $(RCPPINCL) $(RCPPARMAINCL) $(RINSIDEINCL) $(shell $(R_HOME)/bin/R CMD config CXXFLAGS) LDLIBS := $(RLDFLAGS) $(RRPATH) $(RBLAS) $(RLAPACK) $(RCPPLIBS) $(RINSIDELIBS) all: $(programs) @test -x /usr/bin/strip && strip $^ run: $(programs) @for p in $(programs); do echo; echo "Running $$p:"; ./$$p; done clean: rm -vf $(programs) rm -vrf *.dSYM runAll: for p in $(programs); do echo "Running $$p"; ./$$p; done RInside/inst/examples/armadillo/rinside_arma1.cpp0000644000176200001440000000171712257416630021604 0ustar liggesusers// -*- c-indent-level: 4; c-basic-offset: 4; indent-tabs-mode: nil; -*- // // Simple example using Armadillo on matrix data generated in R // // Copyright (C) 2012 - 2013 Dirk Eddelbuettel and Romain Francois #include // for Armadillo as well as Rcpp #include // for the embedded R via RInside int main(int argc, char *argv[]) { RInside R(argc, argv); // create an embedded R instance std::string cmd = "set.seed(42); matrix(rnorm(9),3,3)"; // create a random Matrix in r arma::mat m = Rcpp::as(R.parseEval(cmd)); // parse, eval + return result arma::mat n = m.t() * m; double nacc = arma::accu(n); double nrnk = arma::rank(n); m.print("Initial Matrix m"); // initial random matrix n.print("Product n = m' * m"); // product of m' * m std::cout << "accu(n) " << nacc << " " << "rank(n) " << nrnk << std::endl; // accu() and rank() exit(0); } RInside/inst/examples/standard/0000755000176200001440000000000015002010355016171 5ustar liggesusersRInside/inst/examples/standard/rinside_sample12.cpp0000644000176200001440000000152712257416630022062 0ustar liggesusers// -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; indent-tabs-mode: nil; -*- // // Simple example motivated by StackOverflow question on using sample() from C // // Copyright (C) 2012 Dirk Eddelbuettel and Romain Francois #include // for the embedded R via RInside int main(int argc, char *argv[]) { RInside R(argc, argv); // create an embedded R instance std::string cmd = "set.seed(123); sample(LETTERS[1:5], 10, replace=TRUE)"; Rcpp::CharacterVector res = R.parseEval(cmd); // parse, eval + return result for (int i=0; i(std::cout)); std::cout << std::endl; exit(0); } RInside/inst/examples/standard/rinside_sample14.cpp0000644000176200001440000000232312257416630022057 0ustar liggesusers// -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; indent-tabs-mode: nil; -*- // // Triggering errors, and surviving to tell the tale // // Copyright (C) 2012 Dirk Eddelbuettel and GPL'ed #include // for the embedded R via RInside int main(int argc, char *argv[]) { RInside R(argc, argv, false, false, true); // create an embedded R instance -- and interactive try { std::string cmd = "cat(doesNotExist))"; // simple parse error due to double "))" R.parseEvalQNT(cmd); // eval quietly, does not throw on error // parseEvalQ would throw on the error cmd = "cat(doesNotExist)"; // error, but surviving as we are in interactive mode R.parseEvalQ(cmd); // eval quietly, no error thrown // without try() we'd have an error and exit cmd = "cat(\"End of main part\\n\")"; R.parseEval(cmd); // eval the string, ignoring any returns } catch( std::exception &ex ) { std::cerr << "Exception caught: " << ex.what() << std::endl; } catch(...) { std::cerr << "C++ exception (unknown reason)" << std::endl; } std::cout << "All done, past catch()\n"; exit(0); } RInside/inst/examples/standard/rinside_test2.cpp0000644000176200001440000000102312257416630021466 0ustar liggesusers// -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; indent-tabs-mode: nil; -*- // // Show the search path to check if package methods is loaded // // Copyright (C) 2012 Dirk Eddelbuettel and GPL'ed #include // for the embedded R via RInside int main(int argc, char *argv[]) { RInside R(argc, argv); // create an embedded R instance std::string cmd = "print(search())"; R.parseEval(cmd); // eval the init string, ignoring any returns exit(0); } RInside/inst/examples/standard/rinside_sample10.cpp0000644000176200001440000000227012257416630022054 0ustar liggesusers// Simple example motivated by post from Wayne.Zhang@barclayscapital.com // to r-devel on 28 Jan 2011 // // Copyright (C) 2011 Dirk Eddelbuettel and Romain Francois #include // for the embedded R via RInside void show(const Rcpp::List & L) { // this function is cumbersome as we haven't defined << operators std::cout << "Showing list content:\n"; std::cout << "L[0] " << Rcpp::as(L[0]) << std::endl; std::cout << "L[1] " << Rcpp::as(L[1]) << std::endl; Rcpp::IntegerVector v = Rcpp::as(L[2]); std::cout << "L[2][0] " << v[0] << std::endl; std::cout << "L[2][1] " << v[1] << std::endl; } int main(int argc, char *argv[]) { // create an embedded R instance RInside R(argc, argv); Rcpp::List mylist(3); mylist[0] = 1; mylist[1] = 2.5; Rcpp::IntegerVector v(2); v[0] = 10; v[1] = 11; // with C++0x we could assign directly mylist[2] = v; show(mylist); R["myRlist"] = mylist; std::string r_code = "myRlist[[1]] = 42; myRlist[[2]] = 42.0; myRlist[[3]][2] = 42; myRlist"; Rcpp::List reslist = R.parseEval(r_code); show(reslist); exit(0); } RInside/inst/examples/standard/cmake/0000755000176200001440000000000012257416630017270 5ustar liggesusersRInside/inst/examples/standard/cmake/CMakeLists.txt0000644000176200001440000001130412257416630022027 0ustar liggesuserscmake_minimum_required(VERSION 2.8.4) set (VERBOSE 1) set (SRC_DIR ${CMAKE_CURRENT_SOURCE_DIR}/..) file(GLOB sources ${SRC_DIR}/*.cpp) set(NUM_TRUNC_CHARS 2) set (RPATH "R") set (RSCRIPT_PATH "Rscript") if (CMAKE_HOST_WIN32) execute_process(COMMAND ${RSCRIPT_PATH} -e "cat(.Platform$r_arch)" OUTPUT_VARIABLE R_ARCH) execute_process(COMMAND ${RPATH} --arch ${R_ARCH} RHOME OUTPUT_VARIABLE R_HOME) string(REPLACE "\\" "/" R_HOME ${R_HOME}) set (RPATH ${R_HOME}/bin/R) endif() set (RCPPFLAGS_CMD " ${RPATH} " " CMD " " config " " --cppflags ") execute_process(COMMAND ${RPATH} CMD config --cppflags OUTPUT_VARIABLE RCPPFLAGS) if (CMAKE_HOST_WIN32) if (${RCPPFLAGS} MATCHES "[-][I]([^ ;])+") set (RCPPFLAGS ${CMAKE_MATCH_0}) endif() endif() string(SUBSTRING ${RCPPFLAGS} ${NUM_TRUNC_CHARS} -1 RCPPFLAGS) include_directories(${RCPPFLAGS}) execute_process(COMMAND ${RPATH} CMD config --ldflags OUTPUT_VARIABLE RLDFLAGS) string(LENGTH ${RLDFLAGS} RLDFLAGS_LEN) if (${RLDFLAGS} MATCHES "[-][L]([^ ;])+") string(SUBSTRING ${CMAKE_MATCH_0} ${NUM_TRUNC_CHARS} -1 RLDFLAGS_L) string(STRIP ${RLDFLAGS_L} RLDFLAGS_L ) link_directories(${RLDFLAGS_L} ) endif() if (${RLDFLAGS} MATCHES "[-][l]([^;])+") string(SUBSTRING ${CMAKE_MATCH_0} ${NUM_TRUNC_CHARS} -1 RLDFLAGS_l) string(STRIP ${RLDFLAGS_l} RLDFLAGS_l ) endif() execute_process(COMMAND ${RSCRIPT_PATH} -e "Rcpp:::CxxFlags()" OUTPUT_VARIABLE RCPPINCL) string(SUBSTRING ${RCPPINCL} ${NUM_TRUNC_CHARS} -1 RCPPINCL) include_directories(${RCPPINCL}) execute_process(COMMAND ${RSCRIPT_PATH} -e "Rcpp:::LdFlags()" OUTPUT_VARIABLE RCPPLIBS) execute_process(COMMAND ${RSCRIPT_PATH} -e "RInside:::CxxFlags()" OUTPUT_VARIABLE RINSIDEINCL) string(SUBSTRING ${RINSIDEINCL} ${NUM_TRUNC_CHARS} -1 RINSIDEINCL) include_directories(${RINSIDEINCL}) execute_process(COMMAND ${RSCRIPT_PATH} -e "RInside:::LdFlags()" OUTPUT_VARIABLE RINSIDELIBS) if (CMAKE_HOST_WIN32) string(LENGTH "libRcpp.a" lenRcppName) string(LENGTH ${RCPPLIBS} lenRcppFQName) math(EXPR RLibPathLen ${lenRcppFQName}-${lenRcppName}-1) string(SUBSTRING ${RCPPLIBS} 0 ${RLibPathLen} RCPPLIBS_L) link_directories(${RCPPLIBS_L}) math(EXPR RLibPathLen ${RLibPathLen}+1) string(SUBSTRING ${RCPPLIBS} ${RLibPathLen} -1 RCPPLIBS_l) #Remove the quotes string(SUBSTRING ${RINSIDELIBS} 1 -1 RINSIDELIBS) string(LENGTH ${RINSIDELIBS} lenRInsideFQNameLen) math(EXPR lenRInsideFQNameLen ${lenRInsideFQNameLen}-1) string(SUBSTRING ${RINSIDELIBS} 0 ${lenRInsideFQNameLen} RINSIDELIBS) string(LENGTH "libRInside.a" lenRInsideName) string(LENGTH ${RINSIDELIBS} lenRInsideFQName) math(EXPR RLibPathLen ${lenRInsideFQName}-${lenRInsideName}-1) string(SUBSTRING ${RINSIDELIBS} 0 ${RLibPathLen} RINSIDELIBS_L) math(EXPR RLibPathLen ${RLibPathLen}+1) string(SUBSTRING ${RINSIDELIBS} ${RLibPathLen} -1 RINSIDELIBS_l) link_directories(${RINSIDELIBS_L}) else() if (${RCPPLIBS} MATCHES "[-][L]([^ ;])+") string(SUBSTRING ${CMAKE_MATCH_0} ${NUM_TRUNC_CHARS} -1 RCPPLIBS_L) link_directories(${RCPPLIBS_L} ) endif() if (${RCPPLIBS} MATCHES "[-][l][R]([^;])+") string(SUBSTRING ${CMAKE_MATCH_0} ${NUM_TRUNC_CHARS} -1 RCPPLIBS_l) endif() if (${RINSIDELIBS} MATCHES "[-][L]([^ ;])+") string(SUBSTRING ${CMAKE_MATCH_0} ${NUM_TRUNC_CHARS} -1 RINSIDELIBS_L) link_directories(${RINSIDELIBS_L}) endif() if (${RINSIDELIBS} MATCHES "[-][l][R]([^;])+") string(SUBSTRING ${CMAKE_MATCH_0} ${NUM_TRUNC_CHARS} -1 RINSIDELIBS_l) endif() endif() execute_process(COMMAND ${RPATH} CMD config CXXFLAGS OUTPUT_VARIABLE RCXXFLAGS) execute_process(COMMAND ${RPATH} CMD config BLAS_LIBS OUTPUT_VARIABLE RBLAS) execute_process(COMMAND ${RPATH} CMD config LAPACK_LIBS OUTPUT_VARIABLE RLAPACK) set(CMAKE_CXX_FLAGS "-W -Wall -pedantic -Wextra ${CMAKE_CXX_FLAGS}") if (CMAKE_BUILD_TYPE STREQUAL "DEBUG" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebugInfo" ) add_definitions("-DDEBUG") elseif ( CMAKE_BUILD_TYPE STREQUAL "RELEASE" ) add_definitions("-O3") endif() foreach (next_SOURCE ${sources}) get_filename_component(source_name ${next_SOURCE} NAME_WE) add_executable( ${source_name} ${next_SOURCE} ) target_link_libraries(${source_name} ${RLDFLAGS_l}) target_link_libraries(${source_name} ${BLAS_LIBS}) target_link_libraries(${source_name} ${LAPACK_LIBS}) target_link_libraries(${source_name} ${RINSIDELIBS_l}) target_link_libraries(${source_name} ${RCPPLIBS_l}) endforeach (next_SOURCE ${sources}) RInside/inst/examples/standard/rinside_sample6.cpp0000644000176200001440000000261512257416630022004 0ustar liggesusers// -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 8; -*- // // Showing off some of the templated conversion due to Rcpp // // Copyright (C) 2009 Dirk Eddelbuettel // Copyright (C) 2010 - 2011 Dirk Eddelbuettel and Romain Francois #include // for the embedded R via RInside int main(int argc, char *argv[]) { try { RInside R(argc, argv); // create an embedded R instance double d1 = 1.234; // scalar double R["d1"] = d1; // or R.assign(d1, "d1") std::vector d2; // vector of doubles d2.push_back(1.23); d2.push_back(4.56); R["d2"] = d2; // or R.assign(d2, "d2"); std::map< std::string, double > d3; // map of doubles d3["a"] = 7.89; d3["b"] = 7.07; R["d3"] = d3; // or R.assign(d3, "d3"); std::list< double > d4; // list of doubles d4.push_back(1.11); d4.push_back(4.44); R["d4"] = d4; // or R.assign(d4, "d4"); std::string txt = // now access in R "cat('\nd1=', d1, '\n'); print(class(d1));" "cat('\nd2=\n'); print(d2); print(class(d2));" "cat('\nd3=\n'); print(d3); print(class(d3));" "cat('\nd4=\n'); print(d4); print(class(d4));"; R.parseEvalQ(txt); } catch(std::exception& ex) { std::cerr << "Exception caught: " << ex.what() << std::endl; } catch(...) { std::cerr << "Unknown exception caught" << std::endl; } exit(0); } RInside/inst/examples/standard/rinside_interactive0.cpp0000644000176200001440000001311713055106033023017 0ustar liggesusers// -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 8; -*- // // Example of a planetary motion solver with interactive console // // Copyright (C) 2009 Dirk Eddelbuettel // Copyright (C) 2010 - 2017 Dirk Eddelbuettel and Romain Francois // Copyright (C) 2017 Dirk Eddelbuettel, Romain Francois and Łukasz Łaniewski-Wołłk // // GPL'ed #include // for the embedded R via RInside class Wrapper; // A planet. struct Planet { double x,y; double m; double vx, vy; }; // A gravity simulator class Solver { typedef std::vector Planets; Planets tab; double dt; double G; void Iteration() { for (Planets::iterator a=tab.begin(); a != tab.end(); a++) { for (Planets::iterator b=tab.begin(); b != a; b++) { double x = a->x - b->x; double y = a->y - b->y; double r = sqrt(x*x + y*y); double f = a->m * b->m * G / (r*r+1); double fx = f * x/r; double fy = f * y/r; a->vx -= dt * fx / a->m; a->vy -= dt * fy / a->m; b->vx += dt * fx / b->m; b->vy += dt * fy / b->m; } } for (Planets::iterator a=tab.begin(); a != tab.end(); a++) { a->x += dt * a->vx; a->y += dt * a->vy; } } public: Solver(int n): tab(n), dt(1.0e-4), G(1.0) { double v=0; for (Planets::iterator a=tab.begin(); a != tab.end(); a++) { a->x = sin(v); a->y = cos(v); a->m = 1; v += 3.0/n; } } void Iterate(int n) { for (int i=0;itab.begin(); a != s->tab.end(); a++) { x.push_back( a->x); y.push_back( a->y); m.push_back( a->m); vx.push_back(a->vx); vy.push_back(a->vy); } return Rcpp::DataFrame::create(Rcpp::Named("x") = x, Rcpp::Named("y") = y, Rcpp::Named("mass") = m, Rcpp::Named("Vx") = vx, Rcpp::Named("Vy") = vy); } void setData(Rcpp::DataFrame tab) { if ((size_t)tab.nrows() != s->tab.size()) { return; } Rcpp::NumericVector x = tab["x"]; Rcpp::NumericVector y = tab["y"]; Rcpp::NumericVector m = tab["mass"]; Rcpp::NumericVector vx = tab["Vy"]; Rcpp::NumericVector vy = tab["Vy"]; for (int i=0;itab[i].x = x[i]; s->tab[i].y = y[i]; s->tab[i].m = m[i]; s->tab[i].vx = vx[i]; s->tab[i].vy = vy[i]; } } double& G() { return s->G; } double& dt() { return s->dt; } }; // The function which is called when running Solver$... SEXP Dollar(Rcpp::XPtr obj, std::string name) { if (name == "data") { return obj->getData(); } else if (name == "G") { return Rcpp::NumericVector(1,obj->G()); } else if (name == "dt") { return Rcpp::NumericVector(1,obj->dt()); } else { return NULL; } } // The function which is called when assigning to Solver$... Rcpp::XPtr DollarAssign(Rcpp::XPtr obj, std::string name, SEXP v) { if (name == "data") { obj->setData(v); } else if (name == "G") { obj->G() = Rcpp::NumericVector(v)[0]; } else if (name == "dt") { obj->dt() = Rcpp::NumericVector(v)[0]; } return obj; } // The function listing the elements of Solver Rcpp::CharacterVector Names(Rcpp::XPtr obj) { Rcpp::CharacterVector ret; ret.push_back("data"); ret.push_back("G"); ret.push_back("dt"); return ret; } int main(int argc, char *argv[]) { Solver S(70); // Creating the gravity simulator RInside R(argc, argv, false, false, true); // Create an embedded R instance Rcpp::XPtr wr(new Wrapper(&S)); // Wrapping the solver wr.attr("class") = "Solver"; R["Solver"] = wr; // Adding the wrapped solver R["$.Solver"] = Rcpp::InternalFunction(& Dollar); // Adding the functions R["$<-.Solver"] = Rcpp::InternalFunction(& DollarAssign); R["names.Solver"] = Rcpp::InternalFunction(& Names); char type; do { std::cout << "Want to go interactive? [y/n]"; std::cin >> type; } while ( !std::cin.fail() && type!='y' && type!='n' ); if (type == 'y') { // Running an interactive R session std::cout << "Running an interactive R session. You can explore (and modify) the data in the 'Solver' object." << std::endl; std::cout << "[ You can finish the with Ctrl+D ]" << std::endl; R.parseEval("options(prompt = 'R console > ')"); R.parseEval("X11()"); R.repl() ; std::cout << "Finishing the interactive mode" << std::endl; R.parseEval("dev.off()"); } R.parseEval("X11()"); for (int i=0;i<2000;i++) { // Running the some 200'000 iterations in non-interactive mode S.Iterate(100); R.parseEval("P = Solver$data;"); R.parseEval("plot(P$x,P$y,cex=P$mass,asp=1,xlim=c(-5,5),ylim=c(-5,5),xlab='X',ylab='Y')"); } exit(0); } RInside/inst/examples/standard/rinside_test0.cpp0000644000176200001440000000203512276257676021506 0ustar liggesusers// -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 8; -*- // // Simple test that did not trigger the bug reported by Miguel Lechón // // Copyright (C) 2009 - 2014 Dirk Eddelbuettel and GPL'ed #include // for the embedded R via RInside int main(int argc, char *argv[]) { RInside R(argc, argv); // create an embedded R instance std::string txt = "Hello, world!\n";// assign a standard C++ string to 'txt' R["txt"] = txt; // assign string var to R variable 'txt' std::string evalstr = "cat(txt)"; for (int i=0; i<1e1; i++) { R.parseEvalQ(evalstr); // eval the init string, ignoring any returns } evalstr = "txt <- \"foo\\n\""; for (int i=0; i<1e1; i++) { R.parseEvalQ(evalstr); // eval the init string, ignoring any returns } evalstr = "cat(txt)"; for (int i=0; i<1e1; i++) { R.parseEvalQ(evalstr); // eval the init string, ignoring any returns } exit(0); } RInside/inst/examples/standard/rinside_sample1.cpp0000644000176200001440000000257612257416630022005 0ustar liggesusers// -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 8; -*- // // Simple example with data in C++ that is passed to R, processed and a result is extracted // // Copyright (C) 2009 Dirk Eddelbuettel // Copyright (C) 2010 - 2011 Dirk Eddelbuettel and Romain Francois // // GPL'ed #include // for the embedded R via RInside Rcpp::NumericMatrix createMatrix(const int n) { Rcpp::NumericMatrix M(n,n); for (int i=0; i= 0.11.0) and can be omitted RCPPINCL := $(shell echo 'Rcpp:::CxxFlags()' | $(R_HOME)/bin/R --vanilla --slave) RCPPLIBS := $(shell echo 'Rcpp:::LdFlags()' | $(R_HOME)/bin/R --vanilla --slave) ## include headers and libraries for RInside embedding classes RINSIDEINCL := $(shell echo 'RInside:::CxxFlags()' | $(R_HOME)/bin/R --vanilla --slave) RINSIDELIBS := $(shell echo 'RInside:::LdFlags()' | $(R_HOME)/bin/R --vanilla --slave) ## compiler etc settings used in default make rules CXX := $(shell $(R_HOME)/bin/R CMD config CXX) CPPFLAGS := -Wall $(shell $(R_HOME)/bin/R CMD config CPPFLAGS) CXXFLAGS := $(RCPPFLAGS) $(RCPPINCL) $(RINSIDEINCL) $(shell $(R_HOME)/bin/R CMD config CXXFLAGS) LDLIBS := $(RLDFLAGS) $(RRPATH) $(RBLAS) $(RLAPACK) $(RCPPLIBS) $(RINSIDELIBS) all: $(programs) @test -x /usr/bin/strip && strip $^ run: $(programs) @for p in $(programs); do echo; echo "Running $$p:"; ./$$p; done clean: rm -vf $(programs) rm -vrf *.dSYM runAll: for p in $(programs); do echo ""; echo ""; echo "Running $$p"; ./$$p; done RInside/inst/examples/standard/rinside_sample3.cpp0000644000176200001440000000301612257416630021775 0ustar liggesusers// -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 8; -*- // // Simple example for using lm() using the example from help(swiss) // // Copyright (C) 2009 Dirk Eddelbuettel // Copyright (C) 2010 Dirk Eddelbuettel and Romain Francois #include // for the embedded R via RInside #include int main(int argc, char *argv[]) { RInside R(argc, argv); // create an embedded R instance std::string txt = // load library, run regression, create summary "suppressMessages(require(stats));" "swisssum <- summary(lm(Fertility ~ . , data = swiss));" "print(swisssum)"; R.parseEvalQ(txt); // eval command, no return // evaluate R expressions, and assign directly into Rcpp types Rcpp::NumericMatrix M( (SEXP) R.parseEval("swcoef <- coef(swisssum)")); Rcpp::StringVector cnames( (SEXP) R.parseEval("colnames(swcoef)")); Rcpp::StringVector rnames( (SEXP) R.parseEval("rownames(swcoef)")); std::cout << "\n\nAnd now from C++\n\n\t\t\t"; for (int i=0; i // for the embedded R via RInside int main(int argc, char *argv[]) { RInside R(argc, argv); // create an embedded R instance R["x"] = 10 ; // assignment can be done directly via [] R["y"] = 20 ; R.parseEvalQ("z <- x + y") ; // R statement evaluation and result int sum = R["z"]; // retrieval via access using [] and implicit wrapper std::cout << "10 + 20 = " << sum << std::endl ; // we can also return the value directly sum = R.parseEval("x + y") ; std::cout << "10 + 20 = " << sum << std::endl ; exit(0); } RInside/inst/examples/standard/rinside_sample7.cpp0000644000176200001440000000172312257416630022004 0ustar liggesusers// -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 8; -*- // // Showing off some of the templated as<>() conversion from Rcpp // // Copyright (C) 2010 - 2011 Dirk Eddelbuettel and Romain Francois #include // for the embedded R via RInside int main(int argc, char *argv[]) { try { RInside R(argc, argv); // create an embedded R instance std::string txt; txt = "m <- 1.23"; double d1 = Rcpp::as< double >(R.parseEval(txt)); std::cout << "d1 " << d1 << std::endl; txt = "M <- 1.0 * 1:6"; std::vector d2 = Rcpp::as< std::vector< double > >(R.parseEval(txt)); std::cout << "d2[0] " << d2[0] << " d2[1] " << d2[1] << std::endl; } catch(std::exception& ex) { std::cerr << "Exception caught: " << ex.what() << std::endl; } catch(...) { std::cerr << "Unknown exception caught" << std::endl; } exit(0); } RInside/inst/examples/standard/rinside_callbacks1.cpp0000644000176200001440000000262112403436051022422 0ustar liggesusers// -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 8; -*- // // Simple example showing how to capture R's console output using callbacks // // Copyright (C) 2014 Christian Authmann // // GPL'ed #include // for the embedded R via RInside #if !defined(RINSIDE_CALLBACKS) int main(int argc, char *argv[]) { printf("This example requires RInside to be compiled and installed with RINSIDE_CALLBACKS defined\nSee inst/include/RInsideConfig.h\n"); exit(0); } #else class MyCallbacks : public Callbacks { public: // see inst/includes/Callbacks.h for a list of all overrideable methods virtual void WriteConsole( const std::string& line, int type ) { output_buffer << line << std::endl; }; virtual bool has_WriteConsole() { return true; }; std::string getConsoleOutput() { return output_buffer.str(); } private: std::ostringstream output_buffer; }; int main(int argc, char *argv[]) { MyCallbacks *callbacks = new MyCallbacks(); RInside R(argc, argv); // create an embedded R instance R.set_callbacks( callbacks ); R.parseEvalNT("print(\"Hello world\")"); std::string result = callbacks->getConsoleOutput(); printf("R said:\n%s\n", result.c_str()); exit(0); } #endif RInside/inst/examples/standard/rinside_callbacks0.cpp0000644000176200001440000000110412257416630022424 0ustar liggesusers// -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 8; -*- // // Simple example showing how to do the standard 'hello, world' using embedded R // // Copyright (C) 2009 Dirk Eddelbuettel // Copyright (C) 2010 Dirk Eddelbuettel and Romain Francois // // GPL'ed #include // for the embedded R via RInside int main(int argc, char *argv[]) { RInside R(argc, argv); // create an embedded R instance #if defined(RINSIDE_CALLBACKS) R.set_callbacks( new Callbacks() ); R.repl() ; #endif exit(0); } RInside/inst/examples/standard/rinside_sample15.cpp0000644000176200001440000000202712363742466022070 0ustar liggesusers// -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; indent-tabs-mode: nil; -*- // // Creating a lattice plot from RInside // cf http://stackoverflow.com/questions/24378223/saving-lattice-plots-with-rinside-and-rcpp/ // // Copyright (C) 2014 Dirk Eddelbuettel and GPL'ed #include // for the embedded R via RInside #include int main(int argc, char *argv[]) { // create an embedded R instance RInside R(argc, argv); // evaluate an R expression with curve() // because RInside defaults to interactive=false we use a file std::string cmd = "library(lattice); " "tmpf <- tempfile('xyplot', fileext='.png'); " "png(tmpf); " "print(xyplot(Girth ~ Height | equal.count(Volume), data=trees)); " "dev.off();" "tmpf"; // by running parseEval, we get the last assignment back, here the filename std::string tmpfile = R.parseEval(cmd); std::cout << "Can now use plot in " << tmpfile << std::endl; exit(0); } RInside/inst/examples/standard/rinside_sample13.cpp0000644000176200001440000000225412257416630022061 0ustar liggesusers// -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; indent-tabs-mode: nil; -*- // // Triggering errors, and surviving to tell the tale // // Copyright (C) 2012 Dirk Eddelbuettel and GPL'ed #include // for the embedded R via RInside int main(int argc, char *argv[]) { RInside R(argc, argv); // create an embedded R instance try { std::string cmd = "cat(doesNotExist))"; // simple parse error due to double "))" R.parseEvalQNT(cmd); // eval quietly, does not throw on error // parseEvalQ would throw on the error cmd = "try(cat(doesNotExist))"; // works also as the try() moderates R.parseEvalQ(cmd); // eval quietly, no error thrown // without try() we'd have an error and exit cmd = "cat(\"End of main part\\n\")"; R.parseEval(cmd); // eval the string, ignoring any returns } catch( std::exception &ex ) { std::cerr << "Exception caught: " << ex.what() << std::endl; } catch(...) { std::cerr << "C++ exception (unknown reason)" << std::endl; } std::cout << "All done, past catch()\n"; exit(0); } RInside/inst/examples/standard/rinside_sample11.cpp0000644000176200001440000000203712257416630022056 0ustar liggesusers// Simple example motivated by post from Paul Smith // to r-help on 06 Mar 2011 // // Copyright (C) 2011 - 2012 Dirk Eddelbuettel and Romain Francois #include // for the embedded R via RInside #include int main(int argc, char *argv[]) { // create an embedded R instance RInside R(argc, argv); // evaluate an R expression with curve() // because RInside defaults to interactive=false we use a file std::string cmd = "tmpf <- tempfile('curve'); " "png(tmpf); " "curve(x^2, -10, 10, 200); " "dev.off();" "tmpf"; // by running parseEval, we get the last assignment back, here the filename std::string tmpfile = R.parseEval(cmd); std::cout << "Could now use plot in " << tmpfile << std::endl; unlink(tmpfile.c_str()); // cleaning up // alternatively, by forcing a display we can plot to screen cmd = "x11(); curve(x^2, -10, 10, 200); Sys.sleep(30);"; // parseEvalQ evluates without assignment R.parseEvalQ(cmd); exit(0); } RInside/inst/examples/standard/rinside_sample2.cpp0000644000176200001440000000257012257416630022000 0ustar liggesusers// -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 8; -*- // // Simple example for the repeated r-devel mails by Abhijit Bera // // Copyright (C) 2009 Dirk Eddelbuettel // Copyright (C) 2010 - 2011 Dirk Eddelbuettel and Romain Francois #include // for the embedded R via RInside int main(int argc, char *argv[]) { try { RInside R(argc, argv); // create an embedded R instance std::string txt = "suppressMessages(library(fPortfolio))"; R.parseEvalQ(txt); // load library, no return value txt = "M <- as.matrix(SWX.RET); print(head(M)); M"; Rcpp::NumericMatrix M = R.parseEval(txt); // assign mat. M to NumericMatrix std::cout << "M has " << M.nrow() << " rows and " << M.ncol() << " cols" << std::endl; txt = "colnames(M)"; // assign columns names of M to ans and Rcpp::CharacterVector cnames = R.parseEval(txt); // into str.vec. cnames for (int i=0; i #include #include /* * We have a simple data type with two values. * * Just to make it less simple (and more educational), this class is not copyable, * preventing it from being used as a function parameter or return type. */ class Foo { public: Foo(int a, int b) : a(a), b(b) { } ~Foo() { } private: Foo(const Foo &f) : a(f.a), b(f.b) { throw "Cannot copy construct Foo"; } Foo &operator=(const Foo &f) { throw "Cannot copy assign Foo"; } public: int a, b; }; /* * We define converters between Foo and R objects, see * http://cran.r-project.org/web/packages/Rcpp/vignettes/Rcpp-extending.pdf * * These template declarations must be after RcppCommon.h and before Rcpp.h * The implementation can follow later, when all of Rcpp/Rinside is available. * * Since Foo is not copyable, we need a workaround. Instead of passing Foo * directly, we pass C++11's std::unique_ptr - which is movable. * Note that the older std::auto_ptr does not work. */ namespace Rcpp { template<> SEXP wrap(const Foo &f); template<> SEXP wrap(const std::unique_ptr &f); template<> std::unique_ptr as(SEXP sexp); } #include #include /* * After including Rcpp/Rinside, we can implement the converters. */ // An implementation for unique_ptr template<> SEXP Rcpp::wrap(const std::unique_ptr &f) { return Rcpp::wrap(*f); } // And an implementation for a non-wrapped object template<> SEXP Rcpp::wrap(const Foo &f) { Rcpp::List list; list["a"] = f.a; list["b"] = f.b; return Rcpp::wrap(list); } // Converting the R object back to a C++ object will always return a unique_ptr template<> std::unique_ptr Rcpp::as(SEXP sexp) { Rcpp::List list = Rcpp::as(sexp); int a = list["a"]; int b = list["b"]; // With c++14, we'd use std::make_unique(a, b) here return std::unique_ptr(new Foo(a, b)); } // C++ functions we wish to expose to R std::unique_ptr swapFoo(std::unique_ptr input) { return std::unique_ptr(new Foo(input->b, input->a)); } std::unique_ptr addFoo(std::unique_ptr foo1, std::unique_ptr foo2) { return std::unique_ptr(new Foo(foo1->a + foo2->a, foo1->b + foo2->b)); } /* * Let's also assume that we have some kind of data source. We want R scripts to be able * to query the database without actually exposing the database class. */ class FooDatabase { public: FooDatabase(int database_id) : database_id(database_id) { } // R scripts will want to call this.. std::unique_ptr queryFoo(int id) { return std::unique_ptr(new Foo(database_id, id)); } // ..but really should not be allowed call this. void destroyDatabase() { throw "boom!"; } private: int database_id; }; int main(int argc, char *argv[]) { // create an embedded R instance RInside R(argc, argv); // expose the "swapFoo" and "addFoo" functions in the global environment R["swapFoo"] = Rcpp::InternalFunction( &swapFoo ); R["addFoo"] = Rcpp::InternalFunction( &addFoo ); // We can also expose C++11's std::function, for example to grant access to these three "databases" FooDatabase db1(1), db2(2), db3(3); // All data from DB1 can be queried std::function< std::unique_ptr(int) > queryDB1 = std::bind(&FooDatabase::queryFoo, std::ref(db1), std::placeholders::_1); R["queryDB1"] = Rcpp::InternalFunction( queryDB1 ); // DB2 shall only be queried with id=42 std::function< std::unique_ptr() > queryDB2 = std::bind(&FooDatabase::queryFoo, std::ref(db2), 42); R["queryDB2"] = Rcpp::InternalFunction( queryDB2 ); // For DB3, let's do some more complicated permission checks. That's a good excuse to use a lambda. std::function< std::unique_ptr(int) > queryDB3 = [&db3] (int id) -> std::unique_ptr { if (id < 0 || id > 20) throw "id out of allowed range"; return db3.queryFoo(id); }; R["queryDB3"] = Rcpp::InternalFunction( queryDB3 ); std::unique_ptr result = R.parseEvalNT( "foo1 = queryDB1(20);" //"print(foo1);" // a=1, b=20 "foo2 = queryDB2();" //"print(foo2);" // a=2, b=42 "foo3 = queryDB3(10);" //"print(foo3);" // a=3, b=10 "foo1 = swapFoo(foo1);" //"print(foo1);" // a=20, b=1 "foo = addFoo(foo1, addFoo(foo2, foo3));" //"print(foo);" // a=25, b=53 "foo;" // return the object ); std::cout << " Got result a=" << result->a << ", b=" << result->b << std::endl; std::cout << " Expected a=25, b=53" << std::endl; } RInside/inst/examples/standard/rinside_sample4.cpp0000644000176200001440000000346712257416630022010 0ustar liggesusers// -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; indent-tabs-mode: nil; -*- // // Another simple example inspired by an r-devel mail by Abhijit Bera // // Copyright (C) 2009 Dirk Eddelbuettel // Copyright (C) 2010 Dirk Eddelbuettel and Romain Francois #include // for the embedded R via RInside #include int main(int argc, char *argv[]) { try { RInside R(argc, argv); // create an embedded R instance std::string txt = "suppressMessages(library(fPortfolio)); " "lppData <- 100 * LPP2005.RET[, 1:6]; " "ewSpec <- portfolioSpec(); " "nAssets <- ncol(lppData); "; R.parseEvalQ(txt); // prepare problem const double dvec[6] = { 0.1, 0.1, 0.1, 0.1, 0.3, 0.3 }; // choose any weights const std::vector w(dvec, &dvec[6]); R["weightsvec"] = w; // assign weights txt = "setWeights(ewSpec) <- weightsvec"; R.parseEvalQ(txt); // evaluate assignment txt = "ewPf <- feasiblePortfolio(data=lppData, spec=ewSpec, constraints=\"LongOnly\");" "print(ewPf); " "vec <- getCovRiskBudgets(ewPf@portfolio)"; Rcpp::NumericVector V( (SEXP) R.parseEval(txt) ); Rcpp::CharacterVector names( (SEXP) R.parseEval("names(vec)")); std::cout << "\n\nAnd now from C++\n\n"; for (int i=0; i // for the embedded R via RInside int main(int argc, char *argv[]) { RInside R(argc, argv); // create an embedded R instance R["txt"] = "Hello, world!\n"; // assign a char* (string) to 'txt' R.parseEvalQ("cat(txt)"); // eval the init string, ignoring any returns exit(0); } RInside/inst/examples/standard/rinside_sample16.cpp0000644000176200001440000000500012436366647022067 0ustar liggesusers// -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; indent-tabs-mode: nil; -*- // // Simple example showing how expose a C++ function with custom data types // This is a continuation of rinside_sample9.cpp // // Copyright (C) 2014 Christian Authmann #include /* * We have a simple data type with two values. */ class Foo { public: Foo(int a, int b) : a(a), b(b) { } ~Foo() { } // The compiler will add the default copy constructor, so this class is copyable. int a, b; }; /* * We define converters between Foo and R objects, see * http://cran.r-project.org/web/packages/Rcpp/vignettes/Rcpp-extending.pdf */ #include /* * These template declarations must be after RcppCommon.h and before Rcpp.h * The implementation can follow later, when all of Rcpp/Rinside is available. */ namespace Rcpp { template<> SEXP wrap(const Foo &f); template<> Foo as(SEXP sexp); } #include #include /* * After including Rcpp/Rinside, we can implement the converters. */ template<> SEXP Rcpp::wrap(const Foo &f) { Rcpp::List list; list["a"] = f.a; list["b"] = f.b; // Like all internal Rcpp datatypes, the List can be autoconverted to a SEXP, so we can just return it. // This is equivalent to: return Rcpp::wrap(list) return list; } template<> Foo Rcpp::as(SEXP sexp) { Rcpp::List list = Rcpp::as(sexp); // Note: This does not work when compiled using clang with Rcpp 0.11.2 and older return Foo( list["a"], list["b"] ); } // a c++ function we wish to expose to R Foo swapFoo(Foo &input) { Foo result(input.b, input.a); return result; } int main(int argc, char *argv[]) { // create an embedded R instance RInside R(argc, argv); // expose the "swapFoo" function in the global environment R["swapFoo"] = Rcpp::InternalFunction( &swapFoo ); // create a foo instance and expose it Foo f(0, 42); R["foo"] = f; // call it, getting another Foo object Foo result = R.parseEvalNT( //"print(foo);" // a=0, b=42 "foo$a = 12;" //"print(foo);" // a=12, b=42 "foo = swapFoo(foo);" //"print(foo);" // a=42, b=12 "foo;" // return the object ); std::cout << " Got result a=" << result.a << ", b=" << result.b << std::endl; std::cout << " Expected a=42, b=12" << std::endl; } RInside/inst/examples/standard/rinside_sample9.cpp0000644000176200001440000000153612357120440022000 0ustar liggesusers// -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 8; -*- // // Simple example showing how expose a C++ function -- no longer builds // // Copyright (C) 2010 Dirk Eddelbuettel and Romain Francois #include // for the embedded R via RInside // a c++ function we wish to expose to R std::string hello( std::string who ){ std::string result( "hello " ) ; result += who ; return result; } int main(int argc, char *argv[]) { // create an embedded R instance RInside R(argc, argv); // expose the "hello" function in the global environment R["hello"] = Rcpp::InternalFunction( &hello ) ; // call it and display the result std::string result = R.parseEvalNT("hello(\"world\")") ; std::cout << "hello( 'world') = " << result << std::endl ; exit(0); } RInside/inst/examples/standard/rinside_module_sample0.cpp0000644000176200001440000000206112365571075023343 0ustar liggesusers// -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 4; -*- // // Simple example showing how expose a C++ function // // Copyright (C) 2010 - 2012 Dirk Eddelbuettel and Romain Francois #include // for the embedded R via RInside // a c++ function we wish to expose to R const char* hello( std::string who ){ std::string result( "hello " ) ; result += who ; return result.c_str() ; } // RCPP_MODULE(bling){ // using namespace Rcpp ; // function( "hello", &hello ); // } int main(int argc, char *argv[]) { // create an embedded R instance -- and load Rcpp so that modules work RInside R(argc, argv, true); // load the bling module // R["bling"] = LOAD_RCPP_MODULE(bling) ; // call it and display the result Rcpp::Rcout << "** rinside_module_sample0 is currently disabled.\n"; if (FALSE) { std::string result = R.parseEval("bling$hello('world')") ; std::cout << "bling$hello( 'world') = '" << result << "'" << std::endl ; } exit(0); } RInside/inst/examples/standard/rinside_test1.cpp0000644000176200001440000000515712257416630021501 0ustar liggesusers// -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 8; -*- // // Simple test that did trigger the bug reported by Miguel Lechón // // Copyright (C) 2009 Dirk Eddelbuettel and GPL'ed #include // for the embedded R via RInside int main(int argc, char *argv[]) { RInside R(argc, argv); // create an embedded R instance std::string txt = "Hello, world!\n";// assign a standard C++ string to 'txt' R.assign( txt, "txt"); // assign string var to R variable 'txt' std::string evalstr = "txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; txt <- \"foo\\n\"; cat(txt)"; for (int i=0; i<1e1; i++) { R.parseEvalQ(evalstr); // eval the init string, ignoring any returns } exit(0); } RInside/inst/examples/standard/rinside_sample5.cpp0000644000176200001440000000210612257416630021776 0ustar liggesusers// -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 8; -*- // // Another simple example inspired by an r-devel mail by Martin Becker // // Copyright (C) 2009 Dirk Eddelbuettel // Copyright (C) 2010 - 2011 Dirk Eddelbuettel and Romain Francois #include // for the embedded R via RInside int main(int argc, char *argv[]) { try { RInside R(argc, argv); // create an embedded R instance std::string txt = "myenv <- new.env(hash=TRUE, size=NA)"; R.parseEvalQ(txt); // eval string quietly, no result txt = "is.environment(myenv)"; // logical value assigned Rcpp::LogicalVector V = R.parseEval(txt); // to logical vector std::cout << "We " << (V(0) ? "do" : "do not") << " have an environment." << std::endl; } catch(std::exception& ex) { std::cerr << "Exception caught: " << ex.what() << std::endl; } catch(...) { std::cerr << "Unknown exception caught" << std::endl; } exit(0); } RInside/inst/NEWS.Rd0000644000176200001440000003313015002010262013613 0ustar liggesusers\name{NEWS} \title{News for Package \pkg{RInside}} \newcommand{\ghpr}{\href{https://github.com/eddelbuettel/rinside/pull/#1}{##1}} \newcommand{\ghit}{\href{https://github.com/eddelbuettel/rinside/issues/#1}{##1}} \section{Changes in RInside version 0.2.19 (2025-04-22)}{ \itemize{ \item The qt example now supports Qt6 (Joris Goosen in \ghpr{54} closing \ghit{53}) \item CMake support was refined for more recent versions (Joris Goosen in \ghpr{55}) \item The sandboxed-server example now states more clearly that \code{RINSIDE_CALLBACKS} needs to be defined \item More routine update to package and continuous integration. \item Some now-obsolete checks for C++11 have been removed \item When parsing environment variables, use of double quotes is now supported`p } } \section{Changes in RInside version 0.2.18 (2023-02-01)}{ \itemize{ \item The random number initialization was updated as in R. \item The main REPL is not running via `run_Rmainloop()`. \item Small routine update to package and continuous integration. } } \section{Changes in RInside version 0.2.17 (2022-03-31)}{ \itemize{ \item A Windows-only patch for R 4.2.0 kindly provided by Tomas Kalibera was applied, and also conditioned on R (>= 4.2.0) \item Continuous Integration setup was updated and now uses \href{https://eddelbuettel.github.io/r-ci/}{r-ci}. \item Several updates were made to README.md (badges etc) and DESCRIPTION } } \section{Changes in RInside version 0.2.16 (2020-03-12)}{ \itemize{ \item RInside is now embeddable (with a reduced interface) from C applications thanks to Lance Bachmeier (who is now co-author) plus some polish by Dirk in \ghpr{43}) \item Added \code{R_SESSION_INIIALIZED} to list of excluded variables. \item Added simple diagnostics function to have a registered function. } } \section{Changes in RInside version 0.2.15 (2019-03-06)}{ \itemize{ \item Improved Windows build support by copying \code{getenv("R_HOME")} result and improving backslash handling in environemt variable setting (Jonathon Love in \ghpr{27} and \ghpr{28}) \item Improved Windows build support by quote-protecting \code{Rscript} path in \code{Makevars.win} (François-David Collin in \ghpr{33}) \item A URL was corrected in README.md (Zé Vinícius in \ghpr{34}). \item Temporary \code{SEXP} objects are handled more carefully at initialization to satisfy `rchk` (Dirk in \ghpr{36}) } } \section{Changes in RInside version 0.2.14 (2017-04-28)}{ \itemize{ \item Interactive mode can use readline REPL (Łukasz Łaniewski-Wołłk in \ghpr{25}, and Dirk in \ghpr{26}) \item Windows macros checks now uses \code{_WIN32} (Kevin Ushey in \ghpr{22}) \item The wt example now links with \code{libboost_system} \item The \code{Makevars} file is now more robist (Mattias Ellert in \ghpr{21}) \item A problem with empty environment variable definitions on Windows was addressed (Jeroen Ooms in \ghpr{17} addressing \ghit{16}) \item \code{HAVE_UINTPTR_T} is defined only if not already defined \item Travis CI is now driven via \code{run.sh} from our forked r-travis } } \section{Changes in RInside version 0.2.13 (2015-05-20)}{ \itemize{ \item Added workaround for a bug in R 3.2.0: by including the file \code{RInterface.h} only once we do not getting linker errors due to multiple definitions of \code{R_running_as_main_program} (which is now addressed in R-patched as well). \item Small improvements to the Travis CI script. } } \section{Changes in RInside version 0.2.12 (2015-01-27)}{ \itemize{ \item Several new examples have been added (with most of the work done by Christian Authmann): \itemize{ \item \code{standard/rinside_sample15.cpp} shows how to create a lattice plot (following a StackOverflow question) \item \code{standard/rinside_sample16.cpp} shows object wrapping, and exposing of C++ functions \item \code{standard/rinside_sample17.cpp} does the same via C++11 \item \code{sandboxed_servers/} adds an entire framework of client/server communication outside the main process (but using a subset of supported types) } \item \code{standard/rinside_module_sample9.cpp} was repaired following a fix to \code{InternalFunction} in \CRANpkg{Rcpp} \item For the seven example directories which contain a \code{Makefile}, the \code{Makefile} was renamed \code{GNUmakefile} to please \code{R CMD check} as well as the CRAN Maintainers. } } \section{Changes in RInside version 0.2.11 (2014-02-11)}{ \itemize{ \item Updated for \CRANpkg{Rcpp} 0.11.0: \itemize{ \item Updated initialization by assigning global environment via pointer only after R itself has been initialized -- with special thanks to Kevin Ushey for the fix \item Updated \code{DESCRIPTION} with \code{Imports:} instead of \code{Depends:} \item Added correspondiing \code{importFrom(Rcpp, evalCpp)} to \code{NAMESPACE} \item Noted in all \code{inst/examples/*/Makefile} that \CRANpkg{Rcpp} no longer requires a library argument, but left code for backwards compatibility in case 0.11.0 is not yet installed. } \item Added \code{--vanilla --slave} to default arguments for R initialization \item Added a few more explicit \code{#include} statements in the \code{qt} example which Qt 5.1 now appears to require -- with thanks to Spencer Behling for the patch \item Added new MPI example with worker functions and RInside instance, kindly contributed by Nicholas Pezolano and Martin Morgan } } \section{Changes in RInside version 0.2.10 (2012-12-05)}{ \itemize{ \item Adjusted to change in R which requires turning checking of the stack limit off in order to allow for access from multiple threads as in the Wt examples. As there are have been no side-effects, this is enabled by default on all platforms (with the exception of Windows). \item Added new \sQuote{threads} example directory with a simple example based on a Boost mutex example. \item Disabled two examples (passing an external function down) which do not currently work; external pointer use should still work. } } \section{Changes in RInside version 0.2.9 (2012-11-04)}{ \itemize{ \item Applied (modified) patch by Theodore Lytras which lets RInside recover from some parsing errors and makes RInside applications more tolerant of errors \item Added non-throwing variants of parseEval() and parseEvalQ() \item Modified Qt and Wt examples of density estimation applications to be much more resilient to bad user input \item On Windows, have RInside use R's get_R_HOME() function to get R_HOME value from registry if not set by user \item Added note to examples/standard/Makefile.win that R_HOME may need to be set to run the executables -- so either export your local value, or re-install RInside from source to have it reflected in the library build of libRinside \item Updated CMake build support for standard, armadillo and eigen \item Improved CMake builds of examples/standard, examples/eigen and examples/armadillo by detecting architecture } } \section{Changes in RInside version 0.2.8 (2012-09-07)}{ \itemize{ \item Added CMake build support for armadillo and eigen examples, once again kindly contributed by Peter Aberline \item Corrected Windows package build to always generate a 64 bit static library too \item Updated package build to no longer require configure / configure.win to update the two header file supplying compile-time information; tightened build dependencies on headers in Makevars / Makevars.win \item Improved examples/standard/Makefile.win by detecting architecture } } \section{Changes in RInside version 0.2.7 (2012-08-12)}{ \itemize{ \item New fifth examples subdirectory 'armadillo' with two new examples showing how to combine \CRANpkg{RInside} with \CRANpkg{RcppArmadillo} \item New sixth examples subdirectory 'eigen' with two new examples showing how to combine \CRANpkg{RInside} with \CRANpkg{RcppEigen} \item Prettified the Wt example 'web application' with CSS use, also added and XML file with simple headers and description text \item New example rinside_sample12 motivated by StackOverflow question on using \code{sample()} from C \item Added CMake build support on Windows for the examples } } \section{Changes in RInside version 0.2.6 (2012-01-11)}{ \itemize{ \item Correct Windows initialization by not using Rprintf in internal console writer, with thanks to both James Bates and John Brzustowski \item Update RNG seeding (used by tmpnam et al) to same scheme used by R since 2.14.0: blending both millisecond time and process id \item Added CMake build support for all four example directories as kindly provided by Peter Aberline; this helps when writing RInside code inside of IDEs such as Eclipse, KDevelop or Code::Blocks \item Small update to standard examples Makefile for Windows permitting to explicitly set i386 or x64 as a build architecture } } \section{Changes in RInside version 0.2.5 (2011-12-07)}{ \itemize{ \item Applied (somewhat simplified) patch by James Bates which restores RInside to working on Windows -- with a big Thank You! to James for fixing a long-standing bug we inadvertendly introduced right after 0.2.0 almost two years ago \item New example embedding R inside a Wt (aka Webtoolkit, pronounced 'witty') application, mirroring the previous Qt application \item Qt example qtdensity now uses the new svg() device in base R; removed test for cairoDevice package as well as fallback png code \item Very minor fix to qmake.pro file for Qt app correcting link order } } \section{Changes in RInside version 0.2.4 (2011-04-24)}{ \itemize{ \item Minor code cleanups in initialization code \item New example embedding R inside a Qt application, along with pro file for Qt's qmake providing a complete simple C++ GUI application \item New examples rinside_sample\{10,11\} based on questions on the r-help and r-devel mailing list \item Some improvements and simplifications throughout examples/standard as well as examples/mpi/ \item Added this NEWS files -- with entries below summarised from ChangeLog and the corresponding blog posts } } \section{Changes in RInside version 0.2.3 (2010-08-06)}{ \itemize{ \item New example rinside_sample9 on how to expose C++ to embedded R \item New example rinside_module_sample0 to show module access from RInside \item Simplified rinside_sample3 and rinside_sample4 \item Some code cleanup to help Solaris builds \item Implicit use of new Proxy class with operator T(), see rinside_sample8 } } \section{Changes in RInside version 0.2.2 (2010-03-22)}{ \itemize{ \item New operator[](string) lets RInside act as proxy to R's global environment so that we can R["x"] = 10 to assign; all the actual work is done by Rcpp::Environment \item No longer ship doxygen-generated docs in build \item Use std::string for all arguments inside throw() to help Windows build \item Default to static linking on OS X and Windows just like Rcpp does \item parseEval() now returns SEXP and has just a string argument for more functional use; it and void sibbling parseEvalQ() now throw exections \item rinside_sample\{2,4,5\} updated accordingly \item Two new 'R inside an MPI app' examples contributed by Jianping Hua \item Also added two C++ variants of the C examples for RInside and MPI \item rinside_sample8 updated with parseEval changes \item Internal MemBuf class simplified via STL std::string \item Autoload simplied via the new Rcpp API \item Added default constructor for RInside \item Retire assign(vector >) via template specialisation \item Include Rcpp.h; switch to Rf_ prefixed R API to avoid Redefine macros \item Windows version currently segfaults on startup } } \section{Changes in RInside version 0.2.1 (2010-01-06)}{ \itemize{ \item Startup now defaults to FALSE, no longer call Rf_KillAllDevices \item Some minor build and code fixes for Windows } } \section{Changes in RInside version 0.2.0 (2009-12-20)}{ \itemize{ \item Initial Windows support, with thanks to Richard Holbrey for both the initial push and a setenv() implementation \item Added Makefile.win for build with the MinGW toolchain to src/ and examples/ \item Some improvements to destructor per example in Writing R Extensions \item New rinside_sample5 based on r-devel post } } \section{Changes in RInside version 0.1.1 (2009-02-19)}{ \itemize{ \item The examples/ Makefile now sets $R_HOME via 'R RHOME', and also employs $R_ARCH for arch-dependent headers -- with thanks for Jeff, Jan and Simon \item Added THANKS file to give recognition to those who helped RInside along \item Added rinside_sample4 as another example based on an r-devel question } } \section{Changes in RInside version 0.1.0 (2009-02-19)}{ \itemize{ \item Initial CRAN release \item Improved build process \item Added doxygen generated documentation \item Added two more example } } \section{Changes in RInside version 0.0.1 (2009-07-19)}{ \itemize{ \item Corrected error in memory buffer class with thanks to Miguel Lechón for a finding the issue and sending a patch \item Added two regression test examples to demonstrate bug and fix \item Minor code cleanups \item Initial version in SVN at R-Forge } } RInside/README.md0000644000176200001440000000555514624177331013110 0ustar liggesusers## RInside: Easy embedding of R inside C++ (and C) [![CI](https://github.com/eddelbuettel/rinside/workflows/ci/badge.svg)](https://github.com/eddelbuettel/rinside/actions?query=workflow%3Aci) [![License](https://img.shields.io/badge/license-GPL%20%28%3E=%202%29-brightgreen.svg?style=flat)](https://www.gnu.org/licenses/gpl-2.0.html) [![CRAN](https://www.r-pkg.org/badges/version/RInside)](https://cran.r-project.org/package=RInside) [![Dependencies](https://tinyverse.netlify.app/badge/RInside)](https://cran.r-project.org/package=RInside) [![Debian package](https://img.shields.io/debian/v/r-cran-rinside/sid?color=brightgreen)](https://packages.debian.org/sid/r-cran-rinside) [![Downloads](https://cranlogs.r-pkg.org/badges/RInside?color=brightgreen)](https://cran.r-project.org/package=RInside) [![Last Commit](https://img.shields.io/github/last-commit/eddelbuettel/rinside)](https://github.com/eddelbuettel/rinside) ### About The RInside package provides a few classes for seamless embedding of [R](https://www.r-project.org) inside of C++ applications by relying on [Rcpp](https://www.rcpp.org/). ### Examples Provided with the package itself are nine subdirectories with examples: from more than a dozen basic command-line examples (in directory `standard`) to graphical user-interfaces (using both [Qt](https://www.qt.io/) and Wt), linear algebra with [Armadillo](https://arma.sourceforge.net/) and [Eigen](https://eigen.tuxfamily.org/index.php?title=Main_Page), parallel computing with MPI to a sandboxed server, and (since release 0.2.16) a simple (and more limited) interface for embedding insice C applications. The simplest example (modulo its header) is [examples/standard/rinside_sample0.cpp](inst/examples/standard/rinside_sample0.cpp) ```c++ #include // for the embedded R via RInside int main(int argc, char *argv[]) { RInside R(argc, argv); // create an embedded R instance R["txt"] = "Hello, world!\n"; // assign a char* (string) to 'txt' R.parseEvalQ("cat(txt)"); // eval the init string, ignoring any returns exit(0); } ``` The [Qt example directory](https://github.com/eddelbuettel/rinside/tree/master/inst/examples/qt) produces this application for showing how to use R (to estimate densities) inside a C++ executable (providing the GUI): ![](https://github.com/eddelbuettel/rinside/blob/master/local/qtdensitySVG.png) The code is portable across operating systems. Similar, the [Wt example directory](https://github.com/eddelbuettel/rinside/tree/master/inst/examples/wt) contains this C++-based web application doing the same: ![](https://github.com/eddelbuettel/rinside/blob/master/local/wtdensity.png) ### See Also The [RInside](https://dirk.eddelbuettel.com/code/rinside.html) web page has some more details. ### Authors Dirk Eddelbuettel, Romain Francois, and Lance Bachmeier ### License GPL (>= 2) RInside/man/0000755000176200001440000000000012257416630012370 5ustar liggesusersRInside/man/RInside-package.Rd0000644000176200001440000000075712257416630015616 0ustar liggesusers\name{RInside-package} \alias{RInside-package} \alias{RInside} \docType{package} \title{Embedding R in C++ applications} \description{The \pkg{RInside} package makes it easier to embed R in your C++ applications. There is no code you would execute directly from the \code{R} environment. Rather, you write \code{C++} programs that embed \code{R} which is illustrated by some the included examples. } \author{Dirk Eddelbuettel and Romain Francois} \keyword{programming} \keyword{interface} RInside/DESCRIPTION0000644000176200001440000000422015002022042013276 0ustar liggesusersPackage: RInside Title: C++ Classes to Embed R in C++ (and C) Applications Version: 0.2.19 Date: 2025-04-22 Authors@R: c(person("Dirk", "Eddelbuettel", role = c("aut", "cre"), email = "edd@debian.org", comment = c(ORCID = "0000-0001-6419-907X")), person("Romain", "Francois", role = "aut", comment = c(ORCID = "0000-0002-2444-4226")), person("Lance", "Bachmeier", role = "ctb")) Description: C++ classes to embed R in C++ (and C) applications A C++ class providing the R interpreter is offered by this package making it easier to have "R inside" your C++ application. As R itself is embedded into your application, a shared library build of R is required. This works on Linux, OS X and even on Windows provided you use the same tools used to build R itself. Numerous examples are provided in the nine subdirectories of the examples/ directory of the installed package: standard, 'mpi' (for parallel computing), 'qt' (showing how to embed 'RInside' inside a Qt GUI application), 'wt' (showing how to build a "web-application" using the Wt toolkit), 'armadillo' (for 'RInside' use with 'RcppArmadillo'), 'eigen' (for 'RInside' use with 'RcppEigen'), and 'c_interface' for a basic C interface and 'Ruby' illustration. The examples use 'GNUmakefile(s)' with GNU extensions, so a GNU make is required (and will use the 'GNUmakefile' automatically). 'Doxygen'-generated documentation of the C++ classes is available at the 'RInside' website as well. Imports: Rcpp LinkingTo: Rcpp URL: https://github.com/eddelbuettel/rinside/, https://dirk.eddelbuettel.com/code/rinside.html License: GPL (>= 2) BugReports: https://github.com/eddelbuettel/rinside/issues MailingList: Please send questions and comments regarding RInside to rcpp-devel@lists.r-forge.r-project.org NeedsCompilation: yes Packaged: 2025-04-22 21:58:05 UTC; edd Author: Dirk Eddelbuettel [aut, cre] (), Romain Francois [aut] (), Lance Bachmeier [ctb] Maintainer: Dirk Eddelbuettel Repository: CRAN Date/Publication: 2025-04-22 23:20:02 UTC