RInside/0000755000175100001440000000000012527104742011631 5ustar hornikusersRInside/inst/0000755000175100001440000000000012527102432012600 5ustar hornikusersRInside/inst/examples/0000755000175100001440000000000012436367153014432 5ustar hornikusersRInside/inst/examples/sandboxed_server/0000755000175100001440000000000012453643755017773 5ustar hornikusersRInside/inst/examples/sandboxed_server/server/0000755000175100001440000000000012436367153021275 5ustar hornikusersRInside/inst/examples/sandboxed_server/server/rinside_callbacks.h0000644000175100001440000000273612436367153025112 0ustar hornikusersclass 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/server/rinsideserver.h0000644000175100001440000000417112436367153024335 0ustar hornikusers/* * 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/rinsideserver.cpp0000644000175100001440000001606412436367153024674 0ustar hornikusers/* * 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/internalfunction_clone.h0000644000175100001440000000521012436367153026206 0ustar hornikusers#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/GNUmakefile0000644000175100001440000000512112453643755022044 0ustar hornikusers## -*- 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/example_server.cpp0000644000175100001440000002076612436367153023527 0ustar hornikusers/* * 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 #if !defined(RCPP_USING_CXX11) #error "Rcpp didn't detect C++11 support (RCPP_USING_CXX11 is not defined)" #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/common/0000755000175100001440000000000012436367153021257 5ustar hornikusersRInside/inst/examples/sandboxed_server/common/binarystream.h0000644000175100001440000001370612436367153024137 0ustar hornikusers/* * 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/typeid.h0000644000175100001440000001017612436367153022733 0ustar hornikusers/* * 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/sandboxed_server/common/constants.h0000644000175100001440000000213712436367153023447 0ustar hornikusers/* * 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/binarystream.cpp0000644000175100001440000001045312436367153024466 0ustar hornikusers/* * 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/client/0000755000175100001440000000000012436367153021245 5ustar hornikusersRInside/inst/examples/sandboxed_server/client/rinsideclient.h0000644000175100001440000000515012436367153024253 0ustar hornikusers/* * 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/callback_helper.h0000644000175100001440000000636312436367153024521 0ustar hornikusers/* * 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/client/rinsideclient.cpp0000644000175100001440000000643512436367153024615 0ustar hornikusers/* * 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/example_client.cpp0000644000175100001440000001623012436367153023466 0ustar hornikusers/* * 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/datatypes/0000755000175100001440000000000012436367153021765 5ustar hornikusersRInside/inst/examples/sandboxed_server/datatypes/foo_rcpp_wrapper_declarations.h0000644000175100001440000000017212436367153030235 0ustar hornikusers#pragma once namespace Rcpp { // Foo template<> SEXP wrap(const Foo &foo); template<> Foo as(SEXP sexp); } RInside/inst/examples/sandboxed_server/datatypes/foo.h0000644000175100001440000000131312436367153022717 0ustar hornikusers#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/bar_rcpp_wrapper_declarations.h0000644000175100001440000000017412436367153030220 0ustar hornikusers#pragma once namespace Rcpp { // Bar template<> SEXP wrap(const Bar &bar); template<> Bar as(SEXP sexp); } RInside/inst/examples/sandboxed_server/datatypes/bar_rcpp_wrapper_definitions.h0000644000175100001440000000076712436367153030073 0ustar hornikusers#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/foo.cpp0000644000175100001440000000067212436367153023261 0ustar hornikusers #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/datatypes/bar.cpp0000644000175100001440000000056312436367153023241 0ustar hornikusers#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/foo_rcpp_wrapper_definitions.h0000644000175100001440000000113512436367153030100 0ustar hornikusers#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.h0000644000175100001440000000136412436367153022706 0ustar hornikusers#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/threads/0000755000175100001440000000000012453643755016070 5ustar hornikusersRInside/inst/examples/threads/GNUmakefile0000644000175100001440000000330512453643755020143 0ustar hornikusers ## 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.cpp0000644000175100001440000000200712257416630020206 0ustar hornikusers// -*- 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/qt/0000755000175100001440000000000012525657424015060 5ustar hornikusersRInside/inst/examples/qt/qtdensity.cpp0000644000175100001440000001350112257416630017602 0ustar hornikusers// -*- 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" 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(buttonClicked(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); QRegExp rx1(" #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.pro0000644000175100001440000000451212525657236017631 0ustar hornikusers## -*- mode: Makefile; 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 ## ## This file can be used across operating systems as qmake selects appropriate ## values as needed, as do the R and R-related calls below. See the thread at ## http://thread.gmane.org/gmane.comp.lang.r.rcpp/4376/focus=4402 ## for discussion specific to Windows. ## ## Copyright (C) 2012 Dirk Eddelbuettel and Romain Francois ## build an app based on the one headers and two source files TEMPLATE = app HEADERS = qtdensity.h SOURCES = qtdensity.cpp main.cpp ## beyond the default configuration, also use SVG graphics QT += svg ## comment this out if you need a different version of R, ## and set set R_HOME accordingly as an environment variable R_HOME = $$system(R RHOME) #message("R_HOME is" $$R_HOME) ## include headers and libraries for R RCPPFLAGS = $$system($$R_HOME/bin/R CMD config --cppflags) RLDFLAGS = $$system($$R_HOME/bin/R CMD config --ldflags) RBLAS = $$system($$R_HOME/bin/R CMD config BLAS_LIBS) RLAPACK = $$system($$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 = $$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/qtdensity.h0000644000175100001440000000277412257416630017261 0ustar hornikusers// -*- 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/mpi/0000755000175100001440000000000012453643755015223 5ustar hornikusersRInside/inst/examples/mpi/rinside_mpi_sample4.cpp0000644000175100001440000000640312257416630021651 0ustar hornikusers// -*- 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_sample1.cpp0000644000175100001440000000552012257416630021645 0ustar hornikusers// -*- 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/mpi/rinside_mpi_sample2.cpp0000644000175100001440000000216112257416630021644 0ustar hornikusers// -*- 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/0000755000175100001440000000000012257416630016273 5ustar hornikusersRInside/inst/examples/mpi/cmake/CMakeLists.txt0000644000175100001440000000645012257416630021040 0ustar hornikuserscmake_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/rinside_mpi_sample3.cpp0000644000175100001440000000542412257416630021652 0ustar hornikusers// -*- 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/GNUmakefile0000644000175100001440000000366612453643755017310 0ustar hornikusers## -*- 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_sample0.cpp0000644000175100001440000000231012257416630021636 0ustar hornikusers// -*- 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/wt/0000755000175100001440000000000012453643755015070 5ustar hornikusersRInside/inst/examples/wt/wtdensity.cpp0000644000175100001440000002045712257416630017626 0ustar hornikusers// -*- 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/0000755000175100001440000000000012257416630016140 5ustar hornikusersRInside/inst/examples/wt/cmake/CMakeLists.txt0000644000175100001440000000626112257416630020705 0ustar hornikuserscmake_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/GNUmakefile0000644000175100001440000000463612453643755017153 0ustar hornikusers ## 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 ## 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/wtdensityPlain.cpp0000644000175100001440000001754512257416630020616 0ustar hornikusers// -*- 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/wt/wtdensity.css0000644000175100001440000000051212257416630017622 0ustar hornikusersbody, 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/wtdensity.xml0000644000175100001440000000443412257416630017641 0ustar hornikusers
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/armadillo/0000755000175100001440000000000012453643755016402 5ustar hornikusersRInside/inst/examples/armadillo/cmake/0000755000175100001440000000000012257416630017452 5ustar hornikusersRInside/inst/examples/armadillo/cmake/WIN.readme.txt0000644000175100001440000000244312257416630022107 0ustar hornikusers 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/cmake/CMakeLists.txt0000644000175100001440000001354012257416630022215 0ustar hornikuserscmake_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/GNUmakefile0000644000175100001440000000364312453643755020462 0ustar hornikusers## -*- 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.cpp0000644000175100001440000000171712257416630021622 0ustar hornikusers// -*- 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/armadillo/rinside_arma0.cpp0000644000175100001440000000121712257416630021614 0ustar hornikusers// -*- 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/standard/0000755000175100001440000000000012527102432016216 5ustar hornikusersRInside/inst/examples/standard/rinside_sample4.cpp0000644000175100001440000000346712257416630022026 0ustar hornikusers// -*- 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 // 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_sample12.cpp0000644000175100001440000000152712257416630022100 0ustar hornikusers// -*- 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_sample15.cpp0000644000175100001440000000202712363742466022106 0ustar hornikusers// -*- 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_callbacks1.cpp0000644000175100001440000000262112403436051022440 0ustar hornikusers// -*- 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_sample14.cpp0000644000175100001440000000232312257416630022075 0ustar hornikusers// -*- 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_sample10.cpp0000644000175100001440000000227012257416630022072 0ustar hornikusers// 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/rinside_sample17.cpp0000644000175100001440000001310212436366647022110 0ustar hornikusers// -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; indent-tabs-mode: nil; -*- // // More elaborate examples for exposing functions using C++11 // // Copyright (C) 2014 Christian Authmann #include #include #if !defined(RCPP_USING_CXX11) int main(int argc, char *argv[]) { std::cout << "This example requires a c++11 compatible compiler. Upgrade your compiler and/or add the -std=c++11 compiler option.\n"; exit(0); } #elif RCPP_VERSION < Rcpp_Version(0,11,3) int main(int argc, char *argv[]) { std::cout << "This example requires Rcpp 0.11.3 or later. Upgrade Rcpp and recompile this example.\n"; exit(0); } #else #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; } #endif RInside/inst/examples/standard/rinside_sample16.cpp0000644000175100001440000000500012436366647022105 0ustar hornikusers// -*- 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_sample6.cpp0000644000175100001440000000261512257416630022022 0ustar hornikusers// -*- 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/cmake/0000755000175100001440000000000012257416630017306 5ustar hornikusersRInside/inst/examples/standard/cmake/CMakeLists.txt0000644000175100001440000001130412257416630022045 0ustar hornikuserscmake_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/GNUmakefile0000644000175100001440000000364512453643755020320 0ustar hornikusers## -*- 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 := $(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) ## 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_sample5.cpp0000644000175100001440000000210612257416630022014 0ustar hornikusers// -*- 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/examples/standard/rinside_sample13.cpp0000644000175100001440000000225412257416630022077 0ustar hornikusers// -*- 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/Makefile.win0000644000175100001440000000516512257416630020471 0ustar hornikusers## -*- mode: makefile; tab-width: 8; -*- ## ## Simple Makefile for Windows ## ## Note that the libRInside library encodes the value of R_HOME found ## at compilation. So if you use the CRAN package of RInside, its value ## may not correspond to where you have R installed. One quick fix is ## export the appropriate value of R_HOME, eg ony my work machine ## set R_HOME=C:\opt\R-current ## The other is to re-install RInside from source on your machine. ## Either one should allow you to actually run the binaries created ## with this Makefile ## This version is fairly directly derived from the Unix versions ## You may have to set R_HOME manually if this does not work ## It requires Rtools in the path -- as does all R package building R_HOME := $(shell R RHOME | sed -e "s|\\\\|\/|g") ## You may have to set this to one of the two values below to enforce a particular ## architecture in case the autodetection in the next line does not work correctly R_ARCH := --arch $(shell echo 'cat(.Platform$$r_arch)' | R --vanilla --slave) ##R_ARCH := --arch i386 ##R_ARCH := --arch x64 ## You may need to set R_LIBS_USER if Rcpp or RInside are installed where R does not see them by default #R_LIBS_USER := "C:/myRstuff/library" sources := $(wildcard *.cpp) programs := $(sources:.cpp=) ## include headers and libraries for R RCPPFLAGS := $(shell $(R_HOME)/bin/R $(R_ARCH) CMD config --cppflags) RLDFLAGS := $(shell $(R_HOME)/bin/R $(R_ARCH) CMD config --ldflags) RBLAS := $(shell $(R_HOME)/bin/R $(R_ARCH) CMD config BLAS_LIBS) RLAPACK := $(shell $(R_HOME)/bin/R $(R_ARCH) CMD config LAPACK_LIBS) ## include headers and libraries for Rcpp interface classes RCPPINCL := $(shell echo 'Rcpp:::CxxFlags()' | $(R_HOME)/bin/R $(R_ARCH) --vanilla --slave) RCPPLIBS := $(shell echo 'Rcpp:::LdFlags()' | $(R_HOME)/bin/R $(R_ARCH) --vanilla --slave) ## include headers and libraries for RInside embedding classes RINSIDEINCL := $(shell echo 'RInside:::CxxFlags()' | $(R_HOME)/bin/R $(R_ARCH) --vanilla --slave) RINSIDELIBS := $(shell echo 'RInside:::LdFlags()' | $(R_HOME)/bin/R $(R_ARCH) --vanilla --slave) ## compiler etc settings used in default make rules CXX := $(shell $(R_HOME)/bin/R $(R_ARCH) CMD config CXX) CPPFLAGS := -Wall $(shell $(R_HOME)/bin/R $(R_ARCH) CMD config CPPFLAGS) CXXFLAGS := $(RCPPFLAGS) $(RCPPINCL) $(RINSIDEINCL) $(shell $(R_HOME)/bin/R $(R_ARCH) CMD config CXXFLAGS) LDFLAGS = -s LDLIBS := $(RLDFLAGS) $(RBLAS) $(RLAPACK) $(RINSIDELIBS) $(RCPPLIBS) CC := $(shell $(R_HOME)/bin/R $(R_ARCH) CMD config CXX) all : $(programs) clean: rm -vf $(programs) checkR: echo "R is at $(R_HOME)" RInside/inst/examples/standard/rinside_sample0.cpp0000644000175100001440000000117612257416630022015 0ustar hornikusers// -*- 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 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_sample7.cpp0000644000175100001440000000172312257416630022022 0ustar hornikusers// -*- 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_sample3.cpp0000644000175100001440000000301612257416630022013 0ustar hornikusers// -*- 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 // 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_callbacks0.cpp0000644000175100001440000000110412257416630022442 0ustar hornikusers// -*- 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_sample1.cpp0000644000175100001440000000257612257416630022023 0ustar hornikusers// -*- 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 // 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_test0.cpp0000644000175100001440000000203512276257676021524 0ustar hornikusers// -*- 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_test1.cpp0000644000175100001440000000515712257416630021517 0ustar hornikusers// -*- 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_test2.cpp0000644000175100001440000000102312257416630021504 0ustar hornikusers// -*- 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_sample9.cpp0000644000175100001440000000153612357120440022016 0ustar hornikusers// -*- 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_sample2.cpp0000644000175100001440000000257012257416630022016 0ustar hornikusers// -*- 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= 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/eigen/rinside_eigen0.cpp0000644000175100001440000000120612257416630021104 0ustar hornikusers// -*- 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/rinside_eigen1.cpp0000644000175100001440000000173012257416630021107 0ustar hornikusers// -*- 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/NEWS.Rd0000644000175100001440000002422312462023531013646 0ustar hornikusers\name{NEWS} \title{News for Package 'RInside'} \newcommand{\cpkg}{\href{http://CRAN.R-project.org/package=#1}{\pkg{#1}}} \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 \cpkg{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 \cpkg{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 \cpkg{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 \cpkg{RInside} with \cpkg{RcppArmadillo} \item New sixth examples subdirectory 'eigen' with two new examples showing how to combine \cpkg{RInside} with \cpkg{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/inst/THANKS0000644000175100001440000000203712276557475013543 0ustar hornikusers 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/include/0000755000175100001440000000000012525661231014230 5ustar hornikusersRInside/inst/include/RInside.h0000644000175100001440000000636612276206473015757 0ustar hornikusers// -*- 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 - 2013 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(); #ifdef RINSIDE_CALLBACKS void set_callbacks(Callbacks* callbacks_) ; void repl() ; #endif }; #endif RInside/inst/include/Callbacks.h0000644000175100001440000000452712257416630016273 0ustar hornikusers// -*- 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/MemBuf.h0000644000175100001440000000230712257416630015561 0ustar hornikusers// -*- 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/RInsideConfig.h0000644000175100001440000000171712257416630017075 0ustar hornikusers// 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/RInsideCommon.h0000644000175100001440000000375412525661231017120 0ustar hornikusers// -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; indent-tabs-mode: nil; -*- // // RInsideCommon.h: R/C++ interface class library -- Easier R embedding into C++ // // Copyright (C) 2010 - 2011 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 // 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 #define HAVE_UINTPTR_T #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/src/0000755000175100001440000000000012525661231012417 5ustar hornikusersRInside/src/Makevars0000644000175100001440000000345112527102432014111 0ustar hornikusers## -*- 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 . 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) $(ALL_LIBS) @if test -e "/usr/bin/install_name_tool"; then /usr/bin/install_name_tool -id $(R_PACKAGE_DIR)/lib$(R_ARCH)/$(USERLIB) $(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.cpp0000644000175100001440000000274412527102432014300 0ustar hornikusers// -*- 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/setenv/0000755000175100001440000000000012257416630013726 5ustar hornikusersRInside/src/setenv/setenv.c0000644000175100001440000000455112527102432015373 0ustar hornikusers// -*- 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; 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/tools/0000755000175100001440000000000012257416630013562 5ustar hornikusersRInside/src/tools/RInsideAutoloads.r0000755000175100001440000000161612257416630017165 0ustar hornikusers#!/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.r0000755000175100001440000000105112257416630016607 0ustar hornikusers#!/usr/bin/r -q # # This owes a lot to littler.R in the littler sources ExcludeVars <- c("R_SESSION_TMPDIR","R_HISTFILE") IncludeVars <- Sys.getenv() IncludeVars <- IncludeVars[grep("^R_",names(IncludeVars),perl=TRUE)] if (.Platform$OS.type == "windows") { IncludeVars <- gsub("\\\\", "/", IncludeVars, perl=TRUE) } cat(" const char *R_VARS[] = {\n") for (i in 1:length(IncludeVars)){ if (names(IncludeVars)[i] %in% ExcludeVars) next cat(' "',names(IncludeVars)[i],'","',IncludeVars[i],'",\n',sep='') } cat(" NULL\n };\n") RInside/src/tools/unix2dos.r0000644000175100001440000000050712257416630015522 0ustar hornikusers ## 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/Makevars.win0000644000175100001440000000355012527102432014705 0ustar hornikusers## -*- 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/RInside.cpp0000644000175100001440000003766712527102432014476 0ustar hornikusers// -*- 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 - 2015 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; #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 static int myReadConsole(const char *prompt, char *buf, int len, int addtohistory) { fputs(prompt, stdout); fflush(stdout); if (fgets(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", "--no-readline", "--silent", "--vanilla", "--slave"}; int R_argc = sizeof(R_argv) / sizeof(R_argv[0]); 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 Rst.rhome = getenv("R_HOME"); // which is set above as part of R_VARS 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"); Rf_eval(Rf_lang2(suppressMessagesSymbol, Rf_lang2(requireSymbol, Rf_mkString("Rcpp"))), R_GlobalEnv); } 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); unsigned int seed = ((uint64_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; } /* 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 } void RInside::repl(){ R_ReplDLLinit(); while( R_ReplDLLdo1() > 0 ) {} } #endif RInside/NAMESPACE0000644000175100001440000000003312274334216013044 0ustar hornikusers importFrom(Rcpp, evalCpp) RInside/R/0000755000175100001440000000000012257416630012034 5ustar hornikusersRInside/R/RInsidePaths.R0000644000175100001440000000604612257416630014522 0ustar hornikusers ## 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()) } ## 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/R/zzz.R0000644000175100001440000000010512257416630013010 0ustar hornikusers#.First.lib <- function(lib, pkg) { # cat("Loaded RInside.\n") #} RInside/README.md0000644000175100001440000000226112525662033013111 0ustar hornikusers## RInside [![Build Status](https://travis-ci.org/eddelbuettel/rinside.svg)](https://travis-ci.org/eddelbuettel/rinside) [![License](http://img.shields.io/badge/license-GPL%20%28%3E=%202%29-brightgreen.svg?style=flat)](http://www.gnu.org/licenses/gpl-2.0.html) [![Downloads](http://cranlogs.r-pkg.org/badges/RInside?color=brightgreen)](http://cran.rstudio.com/package=RInside) Easy embedding of R inside C++ ### About The RInside package provides a few classes for seamless embedding of [R](http://www.r-project.org) inside of C++ applications by relying on [Rcpp](http://www.rcpp.org). Provided with the package itself are eight subdirectories with examples: from more than a dozen basic command-line examples (in directory `standard`) to graphical user-interfaces (using both [Qt](http://www.qt.io) and [Wt](http://www.webtoolkit.eu/wt)), linear algebra with [Armadillo](http://arma.sf.net) and [Eigen](http://eigen.tuxfamily.org/index.php?title=Main_Page), parallel computing with MPI to a sandboxed server. ### See Also The [RInside](http://dirk.eddelbuettel.com/code/rinside.html) web page has some more details. ### Authors Dirk Eddelbuettel and Romain Francois ### License GPL (>= 2) RInside/MD50000644000175100001440000001645612527104742012155 0ustar hornikusers41f69cadb1e439eea15dd55dd8806b75 *ChangeLog 791eb9c16e21ed69004591e710142b19 *DESCRIPTION 721b51fcc45ba3c8ff2290bc8f55f890 *NAMESPACE 6cc655a76514542527d297ddf6d64e31 *R/RInsidePaths.R 221b942b14cc416f187593b9a662d970 *R/zzz.R fb3f2916fcfccd5fcef22ee87d8d83dd *README.md 3957781126f406fe956fc87441173ce0 *cleanup a354953bc638adfe8fb1143a2428eb67 *cleanup.win 6dfc48dbae965bfa0252f4739b6362ae *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 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 48368301a02a909fbe41e8909e4ef465 *inst/examples/qt/README 605fbc24a171e4a168c2e47dd6f1520e *inst/examples/qt/cmake/CMakeLists.txt 6f76c08d0b895f250b52d19cf85630ed *inst/examples/qt/main.cpp ae117c46fb726e9c51dff253a103565e *inst/examples/qt/qtdensity.cpp 5f7fbd7ce902c4b23d73d3816df1dd8b *inst/examples/qt/qtdensity.h 49f086d0d9a4521bda8b9f28c2c4e01b *inst/examples/qt/qtdensity.pro 72b08213ee496cf2ad16b03660e3df62 *inst/examples/sandboxed_server/GNUmakefile 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 67863fecc8fdc91bbf062c816e7da4be *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 2ea1628c2ce8eda399613f87a8fff0af *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 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 3b658d159e82d4e8cdc3c2002b6f344f *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 83d0dc4471d8136db31b4d4ebdee881e *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 b00fc9ddeddb13051d95b6e5de5e2751 *inst/include/RInside.h e2bf5d17fea0155140de69d86efcaaa3 *inst/include/RInsideCommon.h 193ebd47832d03c444c3f4d516915062 *inst/include/RInsideConfig.h 9bba313d3c86b9a8038d44704366bee2 *man/RInside-package.Rd 1932ad7bf383cf7bc600f0cf03214d1e *src/Makevars dae114d711c1c6c1b0fc72c58312c483 *src/Makevars.win c47d49883a572ae1efcc3f075875f8af *src/MemBuf.cpp fafaf221c06ec2630d26b106bacabc3e *src/RInside.cpp c76997e46f501a21ce9a12a127452a7d *src/setenv/setenv.c e0953bcb1cf6e7732945551f24f7b207 *src/tools/RInsideAutoloads.r 0de3cd168362e5020723217c61485b35 *src/tools/RInsideEnvVars.r 595752b43220c0d19c9f2e2d755bb5c8 *src/tools/unix2dos.r RInside/DESCRIPTION0000644000175100001440000000316312527104742013342 0ustar hornikusersPackage: RInside Title: C++ Classes to Embed R in C++ Applications Version: 0.2.13 Date: 2015-05-20 Author: Dirk Eddelbuettel and Romain Francois Maintainer: Dirk Eddelbuettel Description: C++ classes to embed R in C++ applications The 'RInside' packages makes it easier to have "R inside" your C++ application by providing a C++ wrapper class providing the R interpreter. . 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 eight 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') and eigen (for 'RInside' use with 'RcppEigen'). The example 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. Depends: R (>= 2.10.0) Imports: Rcpp (>= 0.11.0) LinkingTo: Rcpp URL: http://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: 2015-05-20 12:59:06.680335 UTC; edd Repository: CRAN Date/Publication: 2015-05-20 15:19:30 RInside/ChangeLog0000644000175100001440000006270012527100234013400 0ustar hornikusers2015-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/man/0000755000175100001440000000000012257416630012406 5ustar hornikusersRInside/man/RInside-package.Rd0000644000175100001440000000075712257416630015634 0ustar hornikusers\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/cleanup0000755000175100001440000000044512257416630013213 0ustar hornikusers 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 && rm -f *~ cd ../../.. done RInside/cleanup.win0000644000175100001440000000027412257416630014004 0ustar hornikusers 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 -