[Rd] Question on parsing R code from C
Hi all, I am facing the necessity to parse R code from C-side. As a first approximation the goal would be a re-implementation of the R shell (not Rgui). I read the document at http://cran.r-project.org/doc/manuals/R-exts.html section 5.12, and the related source code example. I have some questions: 1. I need to declare the types and function signatures that I am going to use for this task without having to actually include the R headers. Can I safely declare SEXP according to the following ? typedef struct SEXP *unknwn_handle; More in general, is there a reference document for the C API (listing function signatures, and type definitions) ? 2. If the parsed R code of the working implementation contain commands like plot(), will the opportune windows pop-up as if I were using the R shell (on both windows and unix systems) ? 3. What initialization do I need to perform to be in exactly the same starting state as if I had executed the R shell with the --vanilla option? Any help or feedback is appreciated. Thank you. Kind regard __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
Re: [Rd] Question on parsing R code from C
Simon Urbanek r-project.org> writes: > I'm not sure I understand this really - it doesn't define SEXP. I would > expect something like > > typedef void *SEXP; > > Which may work for declarations. Note, however, that for the actual code you'll need to include the headers anyway. Thanks for the prompt reply! It's my understanding that using opaque pointers to hide implementation is fine (as long as they are not de-referenced nor the size of the actual struct is needed). I actually come out with the tentative typedef by looking at the sources, but I got confused by some conditional pre-processor directives so I was searching for confirmation. For the actual code I can just declare the types (even opaques depending on the use) and function signatures that I strictly need by hand as long as I am doing it correctly (after all that's what is inside the headers, among with the stuff I don't need). > http://r.research.att.com/man/R-exts.html is the documentation and the > headers (Rinternals.h > mainly) is the canonical reference. Understood, thanks. > > 2. If the parsed R code of the working implementation contain commands like > > plot(), will the opportune windows pop-up as if I were using the R shell > > (on > > both windows and unix systems) ? > > > > It depends on your settings - plot() uses whatever graphics device you tell > it to use, so plot() doesn't > decide about that. If you use the proper interactive graphics device *and* make sure you're serving the > REPL then it may work. Beware of interactions with your other parts, though, since you are responsible for > ensuring that it works. I admit I am quite lost here, is there any code I can look at for examples? :P > BTW: you subject has absolutely nothing to do with your question - your'e asking about embedding R ;) H I may be excused because I copy and pasted the title of section 5.12 (which seemed most relevant for what I wanted to achieve) :-) Cheers __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
Re: [Rd] Question on parsing R code from C
Simon Urbanek r-project.org> writes: > Except that you don't know what are macros, inlined functions and actual functions. If you are careful you > can possibly fall back to external functions but, obviously, your code will > be less efficient. I would > still prefer including Rinternals.h - you must have a *really* good reason to not do so ;) Hmmm yes there are good motives (I am not completely unreasonable, yet :P) but I could probably cope with it if there is no other way. Regarding the rest of the e-mail, please let me be clearer on what my goal is. I would need a function to create and initialize an R state, a function to close the state, and a function (R_ParseVector?) that takes as input the R state and a string (containing R code), evaluates the code and return an "error code" (error, incomplete, done) plus (eventually) a string containing the output of the computation. In my application I do not have any UI elements (it's console based), but I would like calls to plot in R (and other functions using the graphic device) to function as they would under R.exe (on windows), i.e. have persistent windows popped up which you can resize ecc ecc. I naively thought that these graphic capabilities came automatically with the R_ParseVector via some threading techniques. Thanks for all your comments! Cheers __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
Re: [Rd] Question on parsing R code from C
First of all thanks a lot to you both for all the replies, they have been of great help to me! I got the basic embedding running, however I still have some issues to solve in order to complete the interface to R I am working on: 1. I initialize with Rf_initEmbeddR(). - Is there a way to have more than one R "state" (per single thread)? Or is everything necessarily global? - I also read somewhere that the fpu settings may be touched. Is there a way to make sure that this is not the case? Is this related to fpu_setup()? 2. I create a string and parse it via Rf_mkString() and R_parseVector() (yes I protect/un-protect the SEXPs). - Is it possible to obtain the precise error message, like "unexpected symbol in..." (as would be reported by R.exe) in case of error as a const char* string? - If I pass a wrongly escaped string (for instance 'ggsave("C:\gtest.png")', please notice the missing \) I get on stderr: Error '\g' is an unrecognized escape and I get a crash. This does not happen if for instance i try to parse 'rnorm(10a10)' in which case I get the error flag and the NULL ptr return. I suspect I need to initialize something / set a callback to avoid this but I am not sure... 3. I eval with R_tryEvalSilent(). - Again, is it possible to obtain the precise error message in case of evaluation error as would be reported from R.exe? 4. Regarding the returned result of evaluation. - What is the correct way to obtain a const char* string representing the result as would be "printed" in the R shell by executing a command (for instance "summary(c(1,2,3))") ? - Why is the return type (as reported from typeof in R and TYPEOF in C) of "summary(c(1,2,3))" a double? Any help / feedback on these issues would be greatly appreciated. Thanks again. __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
Re: [Rd] Question on parsing R code from C
Simon Urbanek r-project.org> writes: > AFAIR you have to evaluate parse(text=...) for that, there is no C-level access to parser errors. Yes that did it, thanks! > If you get a crash, you're not setting up you R correctly. If your R quits then you are in non-interactive mode > and you didn't setup an error handler. I am really getting a crash for strings with incorrect escapes like when evaluating: parse(text='ggsave("C:\test.png")') Using R.exe does not result in a crash. It's really puzzling that all the other parse errors (like rnorm(10a10)) or evaluation errors (like idontexists(10)) correctly results in an error string an no crash. Code that executes correctly works fine as well. Do you have any suggestion on what may be causing the issue? I am initializing R with: Rf_initEmbeddedR passing progsname, --vanilla and --slave And I am parsing/evaluating with: Rf_mkString (protected) passing capture.output(eval(parse(text=""))) (I also tried with allocVector + Rf_mkChar with no difference) Followed by: R_ParseVector(r_cmd, -1, parse_err, R_NilValue) (protected) with r_cmd given by the SEXP returned above And by: R_tryEvalSilent(VECTOR_ELT(r_expr,i), R_GlobalEnv, eval_err) (protected) iterating along r_expr which is given by the SEXP returned above. I don't perform any other operation at all. R_Interactive is true. > I prefer using Rf_eval() and try(..., silent=TRUE) - you can check on the class of the result to see if there > was an error. I actually find it easier (less code) to use R_tryEvalSilent followed by R_curErrorBuf in case of error. Are they going to be deprecated? > BTW: you are asking a lot of questions the are answered in the Rserve FAQ (since what you do is exactly what > Rserve provides) so you may want to have a quick look: > http://rforge.net/Rserve/faq.html Thanks a lot, that helped as well! Plotting works as well but after the window is created it "freezes", cannot be closed without passing "dev.off()" command. I understand this is expected behavior and that it cannot be changed using Rf_initEmbeddedR and Rf_endEmbeddedR. The only problem I am having (aside from the wrongly escaped string crashes) is that if I call: Rf_initEmbeddedR (to open the global R state) followed by Rf_endEmbeddedR (to close the global R state) and then I try to open the global state again with Rf_initEmbeddedR I get: "Lost warning messages" on stderr and calling other R functions result in hang. What am I doing wrong? Thanks a lot for all the suggestions so far, I have made a lot of progress. __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
Re: [Rd] Question on parsing R code from C
Simon Urbanek r-project.org> writes: > Not without seeing the actual code. (And details such as which platform > you're on). > Note that setup_Rmainloop() is the last to set the SETJMP context target so you should make sure the stack is > still present after it finished (i.e. you can't call it from a sub-function - which Rf_initEmbeddedR > does) otherwise error without an enclosing context will crash. Or to put it other way round, create a > context around your parse/eval code (probably the easiest way to do that is > to use R_ToplevelExec). I will try to produce the exact code I am using (at the moment it embedded in other code you would not be interested in), platforms are Windows XP and Windows7-64. Some points: 1. Actually R_tryEvalSilent (and R_tryEval) calls R_ToplevelExec. Moreover if the problem is linked to the SETJMP (which I do not know much about unfortunately, my background is C++) it's my understanding that it should manifest itself even for other parse and evaluation errors. Instead the problem arise if and only if I pass a wrongly escaped string. I.e. rnorm(10a10) does not result in a crash. Is the R code doing something differently in this specific case? 2. My code is almost exactly the same as: http://stackoverflow.com/questions/2463437/r-from-c-simplest-possible- helloworld/2464479#2464479 skipping the EXAMPLE 1 part and passing the capture.output(eval(parse(text=" "))) string to R_tryEval in EXAMPLE 2. Cheers, __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel