Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
TRInterface.cxx
Go to the documentation of this file.
1 /*************************************************************************
2  * Copyright (C) 2013-2014, Omar Andres Zapata Mesa *
3  * All rights reserved. *
4  * *
5  * For the licensing terms see $ROOTSYS/LICENSE. *
6  * For the list of contributors see $ROOTSYS/README/CREDITS. *
7  *************************************************************************/
8 #include<TRInterface.h>
9 #include"TRCompletion.h"
10 #include<vector>
11 
12 extern "C"
13 {
14 #include <stdio.h>
15 #include <stdlib.h>
16 }
17 #include<TRint.h>
18 
19 using namespace ROOT::R;
20 ClassImp(TRInterface);
21 
22 static ROOT::R::TRInterface *gR = nullptr;
23 static Bool_t statusEventLoop;
24 
25 TRInterface::TRInterface(const Int_t argc, const Char_t *argv[], const Bool_t loadRcpp, const Bool_t verbose,
26  const Bool_t interactive)
27  : TObject()
28 {
29  if (RInside::instancePtr()) throw std::runtime_error("Can only have one TRInterface instance");
30  fR = new RInside(argc, argv, loadRcpp, verbose, interactive);
31 
32  //Installing the readline callbacks for completion in the
33  //method Interactive
34  rcompgen_rho = R_FindNamespace(Rf_mkString("utils"));
35  RComp_assignBufferSym = Rf_install(".assignLinebuffer");
36  RComp_assignStartSym = Rf_install(".assignStart");
37  RComp_assignEndSym = Rf_install(".assignEnd");
38  RComp_assignTokenSym = Rf_install(".assignToken");
39  RComp_completeTokenSym = Rf_install(".completeToken");
40  RComp_getFileCompSym = Rf_install(".getFileComp");
41  RComp_retrieveCompsSym = Rf_install(".retrieveCompletions");
42  rl_attempted_completion_function = R_custom_completion;
43  statusEventLoop = kFALSE;
44  std::string osname = Eval("Sys.info()['sysname']");
45  //only for linux/mac windows is not supported by ROOT yet.
46  if (osname == "Linux") {
47  Execute("options(device='x11')");
48  } else {
49  Execute("options(device='quartz')");
50  }
51 
52 }
53 
54 TRInterface::~TRInterface()
55 {
56  statusEventLoop = kFALSE;
57  if (th) delete th;
58  if (fR) delete fR;
59  if (gR == this) gR = nullptr;
60 }
61 
62 //______________________________________________________________________________
63 Int_t TRInterface::Eval(const TString &code, TRObject &ans)
64 {
65  SEXP fans;
66 
67  Int_t rc = kFALSE;
68  try {
69  rc = fR->parseEval(code.Data(), fans);
70  } catch (Rcpp::exception &__ex__) {
71  Error("Eval", "%s", __ex__.what());
72  forward_exception_to_r(__ex__) ;
73  } catch (...) {
74  Error("Eval", "Can execute the requested code: %s", code.Data());
75  }
76  ans = fans;
77  ans.SetStatus((rc == 0) ? kTRUE : kFALSE);
78  return rc;
79 }
80 
81 //______________________________________________________________________________
82 void TRInterface::Execute(const TString &code)
83 {
84  try {
85 
86  fR->parseEvalQ(code.Data());
87  } catch (Rcpp::exception &__ex__) {
88  Error("Execute", "%s", __ex__.what());
89  forward_exception_to_r(__ex__) ;
90  } catch (...) {
91  Error("Execute", "Can execute the requested code: %s", code.Data());
92  }
93 }
94 
95 //______________________________________________________________________________
96 TRObject TRInterface::Eval(const TString &code)
97 {
98 // Execute R code.
99 //The RObject result of execution is returned in TRObject
100 
101  SEXP ans;
102 
103  int rc = kFALSE;
104  try {
105  rc = fR->parseEval(code.Data(), ans);
106  } catch (Rcpp::exception &__ex__) {
107  Error("Eval", "%s", __ex__.what());
108  forward_exception_to_r(__ex__) ;
109  } catch (...) {
110  Error("Eval", "Can execute the requested code: %s", code.Data());
111  }
112 
113  return TRObject(ans, (rc == 0) ? kTRUE : kFALSE);
114 }
115 
116 
117 void TRInterface::SetVerbose(Bool_t status)
118 {
119  //verbose mode shows you all the procedures in stdout/stderr
120  //very important to debug and to see the results.
121  fR->setVerbose(status);
122 }
123 
124 //______________________________________________________________________________
125 TRInterface::Binding TRInterface::operator[](const TString &name)
126 {
127  return Binding(this, name);
128 }
129 
130 //______________________________________________________________________________
131 void TRInterface::Assign(const TRFunctionExport &obj, const TString &name)
132 {
133  fR->assign(*obj.f, name.Data());
134 }
135 
136 //______________________________________________________________________________
137 void TRInterface::Assign(const TRDataFrame &obj, const TString &name)
138 {
139  //This method lets you pass c++ functions to R environment.
140  fR->assign(obj.df, name.Data());
141 }
142 
143 //______________________________________________________________________________
144 void TRInterface::Interactive()
145 {
146  while (kTRUE) {
147  Char_t *line = readline("[r]:");
148  if (!line) continue;
149  if (std::string(line) == ".q") break;
150  Execute(line);
151  if (*line) add_history(line);
152  free(line);
153  }
154 }
155 
156 
157 //______________________________________________________________________________
158 TRInterface *TRInterface::InstancePtr()
159 {
160  if (!gR) {
161  const Char_t *R_argv[] = {"rootr", "--gui=none", "--no-save", "--no-readline",
162  "--silent", "--vanilla", "--slave"};
163  gR = new TRInterface(7, R_argv, true, false, false);
164  }
165  gR->ProcessEventsLoop();
166  return gR;
167 }
168 
169 //______________________________________________________________________________
170 TRInterface &TRInterface::Instance()
171 {
172  return *TRInterface::InstancePtr();
173 }
174 
175 //______________________________________________________________________________
176 Bool_t TRInterface::IsInstalled(TString pkg)
177 {
178  TString cmd = "is.element('" + pkg + "', installed.packages()[,1])";
179  return fR->parseEval(cmd.Data());
180 }
181 
182 //______________________________________________________________________________
183 Bool_t TRInterface::Require(TString pkg)
184 {
185  TString cmd = "require('" + pkg + "',quiet=TRUE)";
186  return fR->parseEval(cmd.Data());
187 }
188 
189 //______________________________________________________________________________
190 Bool_t TRInterface::Install(TString pkg, TString repos)
191 {
192  TString cmd = "install.packages('" + pkg + "',repos='" + repos + "',dependencies=TRUE)";
193  fR->parseEval(cmd.Data());
194  return IsInstalled(pkg);
195 }
196 
197 
198 #undef _POSIX_C_SOURCE
199 #include <R_ext/eventloop.h>
200 
201 //______________________________________________________________________________
202 void TRInterface::ProcessEventsLoop()
203 {
204  if (!statusEventLoop) {
205  th = new TThread([](void */*args */) {
206  while (statusEventLoop) {
207  fd_set *fd;
208  Int_t usec = 10000;
209  fd = R_checkActivity(usec, 0);
210  R_runHandlers(R_InputHandlers, fd);
211  if (gSystem) gSystem->Sleep(100);
212  }
213  });
214  statusEventLoop = kTRUE;
215  th->Run();
216  }
217 }