[rkward-cvs] rkward/rkward/rbackend rcommand.cpp,1.6,1.7 rcommand.h,1.14,1.15 rembed.cpp,1.21,1.22 rembed.h,1.8,1.9 rembedinternal.cpp,1.20,1.21 rembedinternal.h,1.12,1.13 rinterface.cpp,1.26,1.27
Thomas Friedrichsmeier
tfry at users.sourceforge.net
Fri Sep 23 14:29:49 UTC 2005
- Previous message: [rkward-cvs] rkward/rkward/rbackend/rpackages/rkward/R internal.R,1.17,1.18
- Next message: [rkward-cvs] rkward/rkward/rbackend rcommand.h,1.15,1.16 rembed.cpp,1.22,1.23 rembed.h,1.9,1.10 rinterface.cpp,1.27,1.28 rthread.cpp,1.17,1.18 rthread.h,1.14,1.15
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
Update of /cvsroot/rkward/rkward/rkward/rbackend
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv30667/rkward/rbackend
Modified Files:
rcommand.cpp rcommand.h rembed.cpp rembed.h rembedinternal.cpp
rembedinternal.h rinterface.cpp
Log Message:
Finished moving away from file-sinks to more direct method of retrieving output. Unfortunately, there is no way, yet, to reliably identify warning messages
Index: rembed.cpp
===================================================================
RCS file: /cvsroot/rkward/rkward/rkward/rbackend/rembed.cpp,v
retrieving revision 1.21
retrieving revision 1.22
diff -C2 -d -r1.21 -r1.22
*** rembed.cpp 18 Sep 2005 15:17:54 -0000 1.21
--- rembed.cpp 23 Sep 2005 14:29:47 -0000 1.22
***************
*** 32,35 ****
--- 32,39 ----
#include "../debug.h"
+ // static
+ //bool REmbedInternal::next_output_is_error = false;
+ //bool REmbedInternal::output_is_warning = false;
+
REmbed::REmbed (RThread *thread) : REmbedInternal() {
RK_TRACE (RBACKEND);
***************
*** 46,63 ****
}
! void REmbed::handleSubstackCall (char **call, int call_length) {
RK_TRACE (RBACKEND);
! thread->doSubstack (call, call_length);
}
/*
! char **REmbed::handleGetValueCall (char **call, int call_length, int *reply_length) {
RK_TRACE (RBACKEND);
! return thread->fetchValue (call, call_length, reply_length);
! }*/
void REmbed::handleStandardCallback (RCallbackArgs *args) {
RK_TRACE (RBACKEND);
- if (args->type == RCallbackArgs::RWriteConsole) qDebug ("Write console: '%s'", *(args->chars_a));
thread->doStandardCallback (args);
}
--- 50,115 ----
}
! void REmbed::handleOutput (char *buf, int buf_length) {
RK_TRACE (RBACKEND);
!
! if (!buf_length) return;
! /* if (REmbedInternal::next_output_is_error) {
! REmbedInternal::next_output_is_error = false;
! return;
! }*/
! if (!thread->current_command) return;
!
! ROutput *out = new ROutput;
! out->type = ROutput::Output;
! out->output = QString (buf);
!
! thread->current_command->output_list.append (out);
! thread->current_command->status |= RCommand::HasOutput;
! // TODO: pass a signal to the thread for real-time update of output
!
! RK_DO (qDebug ("output '%s'", buf), RBACKEND, DL_DEBUG);
}
+
/*
! void REmbed::handleCondition (char **call, int call_length) {
! RK_TRACE (RBACKEND);
!
! RK_ASSERT (call_length >= 2);
! if (!call_length) return;
!
! //REmbedInternal::next_output_is_error = true;
! qDebug ("condition '%s', message '%s'", call[0], call[1]);
! } */
!
! void REmbed::handleError (char **call, int call_length) {
RK_TRACE (RBACKEND);
!
! if (!call_length) return;
!
! // Unfortunately, errors still get printed to the output. We try this crude method for the time being:
! thread->current_command->output_list.last ()->type = ROutput::Error;
! thread->current_command->status |= RCommand::HasError;
!
! /* // for now we ignore everything but the first string.
! ROutput *out = new ROutput;
! out->type = ROutput::Error;
! out->output = QString (call[0]);
!
! thread->current_command->output_list.append (out);
! thread->current_command->status |= RCommand::HasError; */
! // TODO: pass a signal to the thread for real-time update of output
!
! //REmbedInternal::next_output_is_error = true;
! RK_DO (qDebug ("error '%s'", call[0]), RBACKEND, DL_DEBUG);
! }
!
! void REmbed::handleSubstackCall (char **call, int call_length) {
! RK_TRACE (RBACKEND);
! thread->doSubstack (call, call_length);
! }
void REmbed::handleStandardCallback (RCallbackArgs *args) {
RK_TRACE (RBACKEND);
thread->doStandardCallback (args);
}
***************
*** 99,106 ****
runCommandInternal (command + "))\n", &error);
if (error) status |= OtherFail;
! runCommandInternal ("sink (\"" + RKSettingsModuleLogfiles::filesPath () + "/r_out\")\n", &error);
! if (error) status |= SinkFail;
! runCommandInternal ("sink (file (\"" +RKSettingsModuleLogfiles::filesPath () +"/r_err\", \"w\"), FALSE, \"message\")\n", &error);
if (error) status |= SinkFail;
runCommandInternal ("options (htmlhelp=TRUE); options (browser=\"dcop " + kapp->dcopClient ()->appId () + " rkwardapp openHTMLHelp \")", &error);
if (error) status |= OtherFail;
--- 151,158 ----
runCommandInternal (command + "))\n", &error);
if (error) status |= OtherFail;
! runCommandInternal ("options (error=quote (.rk.do.error ()))\n", &error);
if (error) status |= SinkFail;
+ /* runCommandInternal (".rk.init.handlers ()\n", &error);
+ if (error) status |= SinkFail; */
runCommandInternal ("options (htmlhelp=TRUE); options (browser=\"dcop " + kapp->dcopClient ()->appId () + " rkwardapp openHTMLHelp \")", &error);
if (error) status |= OtherFail;
***************
*** 109,122 ****
outfile_offset = 0;
errfile_offset = 0;
!
! outfile.setName (RKSettingsModuleLogfiles::filesPath () + "/r_out");
! if (!outfile.open (IO_ReadOnly)) {
! if (error) status |= SinkFail;
! }
! errfile.setName (RKSettingsModuleLogfiles::filesPath () + "/r_err");
! if (!errfile.open (IO_ReadOnly)) {
! if (error) status |= SinkFail;
! }
!
return status;
}
--- 161,165 ----
outfile_offset = 0;
errfile_offset = 0;
!
return status;
}
***************
*** 124,128 ****
void REmbed::runCommand (RCommand *command) {
RK_TRACE (RBACKEND);
!
if (command->type () & RCommand::EmptyCommand) return;
--- 167,171 ----
void REmbed::runCommand (RCommand *command) {
RK_TRACE (RBACKEND);
!
if (command->type () & RCommand::EmptyCommand) return;
***************
*** 171,192 ****
}
if (command->type () & RCommand::DirectToOutput) {
! runCommandInternal ("sink ()\n", &error);
! }
!
! QString temp = "";
! while (!outfile.atEnd ()) {
! outfile.readLine (temp, 2048);
! command->_output.append (temp);
! command->status |= RCommand::HasOutput;
}
! temp = "";
! while (!errfile.atEnd ()) {
! errfile.readLine (temp, 2048);
! command->_error.append (temp);
! command->status |= RCommand::HasError;
}
-
- RK_DO (if (error) qDebug ("- error message was: '%s'", command->error ().latin1 ()), RBACKEND, DL_WARNING);
}
--- 214,225 ----
}
+ RKWardRError dummy;
if (command->type () & RCommand::DirectToOutput) {
! runCommandInternal ("sink ()\n", &dummy);
}
! if (error) {
! RK_DO (qDebug ("- error message was: '%s'", command->error ().latin1 ()), RBACKEND, DL_WARNING);
! // runCommandInternal (".rk.init.handlers ()\n", &dummy);
}
}
Index: rinterface.cpp
===================================================================
RCS file: /cvsroot/rkward/rkward/rkward/rbackend/rinterface.cpp,v
retrieving revision 1.26
retrieving revision 1.27
diff -C2 -d -r1.26 -r1.27
*** rinterface.cpp 14 Sep 2005 16:32:25 -0000 1.26
--- rinterface.cpp 23 Sep 2005 14:29:47 -0000 1.27
***************
*** 129,133 ****
if (command->status & RCommand::Canceled) {
command->status |= RCommand::HasError;
! command->_error.append ("--- interrupted ---");
if (running_command_canceled) {
RK_ASSERT (command == running_command_canceled);
--- 129,136 ----
if (command->status & RCommand::Canceled) {
command->status |= RCommand::HasError;
! ROutput *out = new ROutput;
! out->type = ROutput::Error;
! out->output = ("--- interrupted ---");
! command->output_list.append (out);
if (running_command_canceled) {
RK_ASSERT (command == running_command_canceled);
Index: rembed.h
===================================================================
RCS file: /cvsroot/rkward/rkward/rkward/rbackend/rembed.h,v
retrieving revision 1.8
retrieving revision 1.9
diff -C2 -d -r1.8 -r1.9
*** rembed.h 12 Sep 2005 17:09:59 -0000 1.8
--- rembed.h 23 Sep 2005 14:29:47 -0000 1.9
***************
*** 60,68 ****
Note that you should call initialize only once in a application */
int initialize ();
!
/** this function is public for technical reasons, only. Don't use except from REmbedInternal! Called from REmbedInternal when the R backend
places a call to the frontend. The call will be directly passed up to RThread::doSubstack (). @see REmbedInternal::handleSubstackCall () */
void handleSubstackCall (char **call, int call_length);
- //char **handleGetValueCall (char **call, int call_length, int *reply_length);
/** this function is public for technical reasons, only. Don't use except from REmbedInternal! Called from REmbedInternal when the R backend
--- 60,79 ----
Note that you should call initialize only once in a application */
int initialize ();
!
! /** this function is public for technical reasons, only. Don't use except from REmbedInternal! Called from REmbedInternal when the R backend
! generates standard output. @see REmbedInternal::handleOutput () */
! void handleOutput (char *buf, int buf_length);
!
! /** this function is public for technical reasons, only. Don't use except from REmbedInternal! Called from REmbedInternal when the R backend
! signals a condition. @see REmbedInternal::handleCondition () */
! // void handleCondition (char **call, int call_length);
!
! /** this function is public for technical reasons, only. Don't use except from REmbedInternal! Called from REmbedInternal when the R backend
! reports an error. @see REmbedInternal::handleError () */
! void handleError (char **call, int call_length);
!
/** this function is public for technical reasons, only. Don't use except from REmbedInternal! Called from REmbedInternal when the R backend
places a call to the frontend. The call will be directly passed up to RThread::doSubstack (). @see REmbedInternal::handleSubstackCall () */
void handleSubstackCall (char **call, int call_length);
/** this function is public for technical reasons, only. Don't use except from REmbedInternal! Called from REmbedInternal when the R backend
Index: rembedinternal.h
===================================================================
RCS file: /cvsroot/rkward/rkward/rkward/rbackend/rembedinternal.h,v
retrieving revision 1.12
retrieving revision 1.13
diff -C2 -d -r1.12 -r1.13
*** rembedinternal.h 14 Sep 2005 16:32:25 -0000 1.12
--- rembedinternal.h 23 Sep 2005 14:29:47 -0000 1.13
***************
*** 115,122 ****
static void processX11Events ();
/** The main callback from R to rkward. Since we need QStrings and stuff to handle the requests, this is only a pure virtual function. The real
implementation is in REmbed::handleSubstackCall () */
virtual void handleSubstackCall (char **call, int call_length) = 0;
- //virtual char **handleGetValueCall (char **call, int call_length, int *reply_length) = 0;
/** This second callback handles R standard callbacks. The difference to the first one is, that these are typically required to finish within the same
--- 115,130 ----
static void processX11Events ();
+ /** This gets called, on normal R output (R_WriteConsole). Used to get at output. */
+ virtual void handleOutput (char *buf, int buf_length) = 0;
+
+ /** This gets called, when R reports warnings/messages. Used to get at warning-output. */
+ // virtual void handleCondition (char **call, int call_length) = 0;
+
+ /** This gets called, when R reports an error (override of options ("error") in R). Used to get at error-output. */
+ virtual void handleError (char **call, int call_length) = 0;
+
/** The main callback from R to rkward. Since we need QStrings and stuff to handle the requests, this is only a pure virtual function. The real
implementation is in REmbed::handleSubstackCall () */
virtual void handleSubstackCall (char **call, int call_length) = 0;
/** This second callback handles R standard callbacks. The difference to the first one is, that these are typically required to finish within the same
***************
*** 128,131 ****
--- 136,144 ----
/** only one instance of this class may be around. This pointer keeps the reference to it, for interfacing to from C to C++ */
static REmbedInternal *this_pointer;
+
+ /** Flags used to classify output. */
+ // static bool output_is_warning;
+ /** Flags used to classify output. */
+ // static bool next_output_is_error;
private:
// can't declare this as part of the class, as it would confuse REmbed
Index: rembedinternal.cpp
===================================================================
RCS file: /cvsroot/rkward/rkward/rkward/rbackend/rembedinternal.cpp,v
retrieving revision 1.20
retrieving revision 1.21
diff -C2 -d -r1.20 -r1.21
*** rembedinternal.cpp 19 Sep 2005 20:10:21 -0000 1.20
--- rembedinternal.cpp 23 Sep 2005 14:29:47 -0000 1.21
***************
*** 70,78 ****
void RWriteConsole (char *buf, int buflen) {
! RCallbackArgs args;
args.type = RCallbackArgs::RWriteConsole;
args.chars_a = &buf;
args.int_a = buflen;
! REmbedInternal::this_pointer->handleStandardCallback (&args);
}
--- 70,79 ----
void RWriteConsole (char *buf, int buflen) {
! /* RCallbackArgs args;
args.type = RCallbackArgs::RWriteConsole;
args.chars_a = &buf;
args.int_a = buflen;
! REmbedInternal::this_pointer->handleStandardCallback (&args); */
! REmbedInternal::this_pointer->handleOutput (buf, buflen);
}
***************
*** 157,161 ****
REmbedInternal::this_pointer->handleStandardCallback (&args);
! // default impelementation seems to return 1 if nfile <= 0, else 1. No idea, what for. see unix/std-sys.c
return (nfile <= 0);
}
--- 158,162 ----
REmbedInternal::this_pointer->handleStandardCallback (&args);
! // default implementation seems to return 1 if nfile <= 0, else 1. No idea, what for. see unix/std-sys.c
return (nfile <= 0);
}
***************
*** 171,175 ****
/// ############## R Standard callback overrides END ####################
-
REmbedInternal::REmbedInternal() {
RKGlobals::empty_char = strdup ("");
--- 172,175 ----
***************
*** 187,190 ****
--- 187,192 ----
// connect R standard callback to our own functions. Important: Don't do so, before our own versions are ready to be used!
+ R_Outputfile = NULL;
+ R_Consolefile = NULL;
ptr_R_Suicide = RSuicide;
ptr_R_ShowMessage = RShowMessage; // when exactly does this ever get used?
***************
*** 281,292 ****
return strings;
}
/*
! SEXP getValueCall (SEXP call) {
int count;
char **strings = extractStrings (call, &count);
! int reply_length;
! REmbedInternal::this_pointer->handleGetValueCall (strings, count, &reply_length);
! return call;
! }*/
SEXP doSubstackCall (SEXP call) {
--- 283,312 ----
return strings;
}
+
+ void deleteStrings (char **strings, int count) {
+ for (int i= (count-1); i >=0; --i) {
+ delete (strings[i]);
+ }
+ delete [] strings;
+ }
+
+ SEXP doError (SEXP call) {
+ extern int R_ShowErrorMessages;
+ if (R_ShowErrorMessages) {
+ int count;
+ char **strings = extractStrings (call, &count);
+ REmbedInternal::this_pointer->handleError (strings, count);
+ deleteStrings (strings, count);
+ }
+ return R_NilValue;
+ }
+
/*
! SEXP doCondition (SEXP call) {
int count;
char **strings = extractStrings (call, &count);
! REmbedInternal::this_pointer->handleCondition (strings, count);
! return R_NilValue;
! } */
SEXP doSubstackCall (SEXP call) {
***************
*** 294,297 ****
--- 314,318 ----
char **strings = extractStrings (call, &count);
REmbedInternal::this_pointer->handleSubstackCall (strings, count);
+ deleteStrings (strings, count);
return R_NilValue;
}
***************
*** 311,315 ****
R_CallMethodDef callMethods [] = {
! //{ "rk.get.value", (DL_FUNC) &getValueCall, 1 },
{ "rk.do.command", (DL_FUNC) &doSubstackCall, 1 },
{ 0, 0, 0 }
--- 332,337 ----
R_CallMethodDef callMethods [] = {
! // { "rk.do.condition", (DL_FUNC) &doCondition, 1 },
! { "rk.do.error", (DL_FUNC) &doError, 1 },
{ "rk.do.command", (DL_FUNC) &doSubstackCall, 1 },
{ 0, 0, 0 }
Index: rcommand.h
===================================================================
RCS file: /cvsroot/rkward/rkward/rkward/rbackend/rcommand.h,v
retrieving revision 1.14
retrieving revision 1.15
diff -C2 -d -r1.14 -r1.15
*** rcommand.h 27 Apr 2005 17:11:28 -0000 1.14
--- rcommand.h 23 Sep 2005 14:29:47 -0000 1.15
***************
*** 23,26 ****
--- 23,27 ----
#include <qobject.h>
#include <qptrlist.h>
+ #include <qvaluelist.h>
class RCommandReceiver;
***************
*** 61,64 ****
--- 62,77 ----
};
+ /** this struct is used to store the R output to an RCommand. The RCommand basically keeps a list of ROutputString (s). The difference to a normal
+ QString is, that additionally we store information on whether the output was "normal", "warning", or an "error". */
+ struct ROutput {
+ enum ROutputType {
+ Output, /**< normal output */
+ Warning, /**< R warning */
+ Error /**< R error */
+ };
+ ROutputType type;
+ QString output;
+ };
+
/*
struct RGetValueRequest {
***************
*** 121,128 ****
int id () { return _id; };
/* TODO: Adjust these two functions to allow re-getting of output and error-messages from logs */
! /** @returns the output of the command, if any (e.g. "[1] 1" for "print (1)"). @see RCommand::succeeded @see RCommand::hasOutput */
! QString output () { return _output; };
/** @returns the error message given by R, if any. @see RCommand::failed @see RCommand::hasError */
! QString error () { return _error; };
/** Types of commands (potentially more to come), bitwise or-able,
although partially exclusive. See \ref UsingTheInterfaceToR for a overview of what these are used for. TODO: find out, why Canceled is in here, and document that fact. */
--- 134,145 ----
int id () { return _id; };
/* TODO: Adjust these two functions to allow re-getting of output and error-messages from logs */
! /** @returns the full output of the command, i.e. all "regular" output, warning messages, and errors, in the order they were encountered. @see RCommand::output @see RCommand::error @see RCommand::warnings */
! QString fullOutput ();
! /** @returns the "regular" (ROutput::Output) output of the command, if any (e.g. "[1] 1" for "print (1)"). @see RCommand::succeeded @see RCommand::hasOutput */
! QString output ();
! /** @returns the warning message(s) given by R, if any. @see RCommand::output @see RCommand::error */
! QString warnings ();
/** @returns the error message given by R, if any. @see RCommand::failed @see RCommand::hasError */
! QString error ();
/** Types of commands (potentially more to come), bitwise or-able,
although partially exclusive. See \ref UsingTheInterfaceToR for a overview of what these are used for. TODO: find out, why Canceled is in here, and document that fact. */
***************
*** 145,148 ****
--- 162,166 ----
HasOutput=4, /**< command has a string output retrievable via RCommand::output () */
HasError=8, /**< command has an error-message retrievable via RCommand::error () */
+ HasWarnings=16, /**< command has warning-message(s) retrievable via RCommand::warnings () */
ErrorIncomplete=512, /**< backend rejected command as being incomplete */
ErrorSyntax=1024, /**< backend rejected command as having a syntax error */
***************
*** 188,193 ****
/** internal function will be called by the backend, as the command gets passed through. Takes care of sending this command (back) to its receiver */
void finished ();
! QString _output;
! QString _error;
QString _command;
char **string_data;
--- 206,210 ----
/** internal function will be called by the backend, as the command gets passed through. Takes care of sending this command (back) to its receiver */
void finished ();
! QValueList<ROutput*> output_list;
QString _command;
char **string_data;
Index: rcommand.cpp
===================================================================
RCS file: /cvsroot/rkward/rkward/rkward/rbackend/rcommand.cpp,v
retrieving revision 1.6
retrieving revision 1.7
diff -C2 -d -r1.6 -r1.7
*** rcommand.cpp 14 Sep 2004 23:34:01 -0000 1.6
--- rcommand.cpp 23 Sep 2005 14:29:47 -0000 1.7
***************
*** 52,55 ****
--- 52,60 ----
delete real_data;
delete integer_data;
+
+ for (QValueList<ROutput*>::iterator it = output_list.begin (); it != output_list.end (); ++it) {
+ delete (*it);
+ }
+ // The output_list itself is cleared automatically
}
***************
*** 61,62 ****
--- 66,113 ----
}
}
+
+ QString RCommand::error () {
+ RK_TRACE (RBACKEND);
+
+ QString ret;
+ for (QValueList<ROutput*>::const_iterator it = output_list.begin (); it != output_list.end (); ++it) {
+ if ((*it)->type == ROutput::Error) {
+ ret.append ((*it)->output);
+ }
+ }
+ return ret;
+ }
+
+ QString RCommand::output () {
+ RK_TRACE (RBACKEND);
+
+ QString ret;
+ for (QValueList<ROutput*>::const_iterator it = output_list.begin (); it != output_list.end (); ++it) {
+ if ((*it)->type == ROutput::Output) {
+ ret.append ((*it)->output);
+ }
+ }
+ return ret;
+ }
+
+ QString RCommand::warnings () {
+ RK_TRACE (RBACKEND);
+
+ QString ret;
+ for (QValueList<ROutput*>::const_iterator it = output_list.begin (); it != output_list.end (); ++it) {
+ if ((*it)->type == ROutput::Warning) {
+ ret.append ((*it)->output);
+ }
+ }
+ return ret;
+ }
+
+ QString RCommand::fullOutput () {
+ RK_TRACE (RBACKEND);
+
+ QString ret;
+ for (QValueList<ROutput*>::const_iterator it = output_list.begin (); it != output_list.end (); ++it) {
+ ret.append ((*it)->output);
+ }
+ return ret;
+ }
- Previous message: [rkward-cvs] rkward/rkward/rbackend/rpackages/rkward/R internal.R,1.17,1.18
- Next message: [rkward-cvs] rkward/rkward/rbackend rcommand.h,1.15,1.16 rembed.cpp,1.22,1.23 rembed.h,1.9,1.10 rinterface.cpp,1.27,1.28 rthread.cpp,1.17,1.18 rthread.h,1.14,1.15
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
More information about the rkward-tracker
mailing list