[rkward-cvs] SF.net SVN: rkward:[3197] trunk/rkward

tfry at users.sourceforge.net tfry at users.sourceforge.net
Fri Nov 19 13:06:39 UTC 2010


Revision: 3197
          http://rkward.svn.sourceforge.net/rkward/?rev=3197&view=rev
Author:   tfry
Date:     2010-11-19 13:06:38 +0000 (Fri, 19 Nov 2010)

Log Message:
-----------
Merge 2010_10_18_backend_restructuring_branch

Modified Paths:
--------------
    trunk/rkward/ChangeLog
    trunk/rkward/rkward/agents/showedittextfileagent.cpp
    trunk/rkward/rkward/agents/showedittextfileagent.h
    trunk/rkward/rkward/core/rfunctionobject.cpp
    trunk/rkward/rkward/core/rfunctionobject.h
    trunk/rkward/rkward/core/rkrownames.cpp
    trunk/rkward/rkward/core/rkrownames.h
    trunk/rkward/rkward/core/rkvariable.cpp
    trunk/rkward/rkward/core/rkvariable.h
    trunk/rkward/rkward/core/robject.cpp
    trunk/rkward/rkward/core/robject.h
    trunk/rkward/rkward/main.cpp
    trunk/rkward/rkward/plugin/rkcomponentproperties.cpp
    trunk/rkward/rkward/rbackend/CMakeLists.txt
    trunk/rkward/rkward/rbackend/rcommand.cpp
    trunk/rkward/rkward/rbackend/rcommand.h
    trunk/rkward/rkward/rbackend/rcommandstack.cpp
    trunk/rkward/rkward/rbackend/rcommandstack.h
    trunk/rkward/rkward/rbackend/rdata.cpp
    trunk/rkward/rkward/rbackend/rdata.h
    trunk/rkward/rkward/rbackend/rinterface.cpp
    trunk/rkward/rkward/rbackend/rinterface.h
    trunk/rkward/rkward/rbackend/rksignalsupport.cpp
    trunk/rkward/rkward/rbackend/rksignalsupport.h
    trunk/rkward/rkward/rbackend/rkstructuregetter.cpp
    trunk/rkward/rkward/rbackend/rkstructuregetter.h
    trunk/rkward/rkward/rbackend/rpackages/rkward/R/internal.R
    trunk/rkward/rkward/rkglobals.cpp
    trunk/rkward/rkward/rkglobals.h
    trunk/rkward/rkward/rkward.cpp
    trunk/rkward/rkward/rkward.h
    trunk/rkward/rkward/scriptbackends/rkcomponentscripting.cpp
    trunk/rkward/rkward/settings/rksettingsmoduler.cpp
    trunk/rkward/rkward/settings/rksettingsmoduler.h
    trunk/rkward/rkward/windows/rkcommandeditorwindow.cpp
    trunk/rkward/rkward/windows/rkcommandeditorwindow.h
    trunk/rkward/rkward/windows/rkcommandlog.cpp
    trunk/rkward/rkward/windows/rkcommandlog.h
    trunk/rkward/rkward/windows/rkhelpsearchwindow.cpp
    trunk/rkward/rkward/windows/rkhelpsearchwindow.h
    trunk/rkward/rkward/windows/rkworkplace.cpp
    trunk/rkward/rkward/windows/rkworkplace.h

Added Paths:
-----------
    trunk/rkward/rkward/rbackend/rkbackendtransmitter.cpp
    trunk/rkward/rkward/rbackend/rkbackendtransmitter.h
    trunk/rkward/rkward/rbackend/rkfrontendtransmitter.cpp
    trunk/rkward/rkward/rbackend/rkfrontendtransmitter.h
    trunk/rkward/rkward/rbackend/rkrbackend.cpp
    trunk/rkward/rkward/rbackend/rkrbackend.h
    trunk/rkward/rkward/rbackend/rkrbackendprotocol_backend.cpp
    trunk/rkward/rkward/rbackend/rkrbackendprotocol_backend.h
    trunk/rkward/rkward/rbackend/rkrbackendprotocol_frontend.cpp
    trunk/rkward/rkward/rbackend/rkrbackendprotocol_frontend.h
    trunk/rkward/rkward/rbackend/rkrbackendprotocol_shared.cpp
    trunk/rkward/rkward/rbackend/rkrbackendprotocol_shared.h
    trunk/rkward/rkward/rbackend/rkrsupport.cpp
    trunk/rkward/rkward/rbackend/rkrsupport.h
    trunk/rkward/rkward/rbackend/rktransmitter.cpp
    trunk/rkward/rkward/rbackend/rktransmitter.h

Removed Paths:
-------------
    trunk/rkward/rkward/rbackend/rembedinternal.cpp
    trunk/rkward/rkward/rbackend/rembedinternal.h
    trunk/rkward/rkward/rbackend/rthread.cpp
    trunk/rkward/rkward/rbackend/rthread.h

Property Changed:
----------------
    trunk/rkward/
    trunk/rkward/debian/


Property changes on: trunk/rkward
___________________________________________________________________
Modified: svn:mergeinfo
   - /branches/release_branch_0.5.4:3098-3102,3127
   + /branches/2010_10_18_backend_restructuring_branch:3130-3196
/branches/release_branch_0.5.4:3098-3102,3127

Modified: trunk/rkward/ChangeLog
===================================================================
--- trunk/rkward/ChangeLog	2010-11-19 12:42:13 UTC (rev 3196)
+++ trunk/rkward/ChangeLog	2010-11-19 13:06:38 UTC (rev 3197)
@@ -1,6 +1,7 @@
 - Fixed: Did not respect system settings for tooltip background color in some styles
 - Fixed: Installation would continue, seemingly successfully, even if R support libraries could not be installed
 - Fixed: Function argument hints would sometimes persist after closing a script window
+- Fixed: Would fail to analyse structure of ReferenceClass-objects
 - Fixed: "Vector" mode in "Paste special" action did not work correctly
 - Attempt to save workspace on crashes		TODO: detect recovery-file at startup, and offer to load it.
 - Also try to relay SIGABRT and SIGILL to the proper signal handlers


Property changes on: trunk/rkward/debian
___________________________________________________________________
Modified: svn:mergeinfo
   - /branches/release_branch_0.5.4:3098-3102
/branches/release_branch_0.5.4/debian:3098-3102
   + /branches/2010_10_18_backend_restructuring_branch/debian:3130-3196
/branches/release_branch_0.5.4:3098-3102
/branches/release_branch_0.5.4/debian:3098-3102

Modified: trunk/rkward/rkward/agents/showedittextfileagent.cpp
===================================================================
--- trunk/rkward/rkward/agents/showedittextfileagent.cpp	2010-11-19 12:42:13 UTC (rev 3196)
+++ trunk/rkward/rkward/agents/showedittextfileagent.cpp	2010-11-19 13:06:38 UTC (rev 3197)
@@ -19,6 +19,7 @@
 
 #include <klocale.h>
 #include <kdialog.h>
+#include <kmessagebox.h>
 
 #include <qlabel.h>
 #include <qlayout.h>
@@ -27,17 +28,17 @@
 
 #include "../windows/rkcommandeditorwindow.h"
 #include "../rbackend/rinterface.h"
-#include "../rbackend/rembedinternal.h"
+#include "../rbackend/rkrbackendprotocol_frontend.h"
 #include "../windows/rkworkplace.h"
 #include "../rkglobals.h"
 #include "../rkward.h"
 
 #include "../debug.h"
 
-ShowEditTextFileAgent::ShowEditTextFileAgent (RCallbackArgs *args, const QString &text, const QString &caption) : QObject (RKWardMainWindow::getMain ()) {
+ShowEditTextFileAgent::ShowEditTextFileAgent (RBackendRequest *request, const QString &text, const QString &caption) : QObject (RKWardMainWindow::getMain ()) {
 	RK_TRACE (APP);
 
-	ShowEditTextFileAgent::args = args;
+	ShowEditTextFileAgent::request = request;
 
 	dialog = new KDialog (0);
 
@@ -56,7 +57,7 @@
 
 	dialog->setButtonText (KDialog::Ok, i18n ("Done"));
 
-	connect (dialog, SIGNAL (finished ()), this, SLOT (done ()));
+	connect (dialog, SIGNAL (finished ()), this, SLOT (deleteLater ()));
 
 	// do it
 	dialog->show ();
@@ -65,38 +66,23 @@
 
 ShowEditTextFileAgent::~ShowEditTextFileAgent () {
 	RK_TRACE (APP);
+
+	RKRBackendProtocolFrontend::setRequestCompleted (request);
+	dialog->deleteLater ();
 }
 
 // static
-void ShowEditTextFileAgent::showEditFiles (RCallbackArgs *args) {
+void ShowEditTextFileAgent::showEditFiles (RBackendRequest *request) {
 	RK_TRACE (APP);
-	if (!args) return;
+	if (!request) return;
 
-	QString caption;
-	QString message;
-	QString message_snip1 = i18n (" For that reason processing has been stopped for now. Press the \"Done\"-button, or close this dialog once you think it is safe to resume.\n\n");
-	QString message_snip2 = i18n ("The file(s) have been opened in text-windows. The following is a list of the file(s) in question:\n\n");
-
-	QStringList files = args->params["files"].toStringList ();
-	QStringList titles = args->params["titles"].toStringList ();
-	QString wtitle = args->params["wtitle"].toString ();
+	QStringList files = request->params["files"].toStringList ();
+	QStringList titles = request->params["titles"].toStringList ();
+	QString wtitle = request->params["wtitle"].toString ();
 	int count = files.count ();
 	RK_ASSERT (titles.count () == count);
 
-	QString bad_files_list;
-	bool r_highlighting = false;
-	bool read_only = true;
-	if (args->type == RCallbackArgs::RShowFiles) {
-		caption = i18n ("Showing file(s)");
-		message = i18n ("A command running in the R-engine wants you to see one or more file(s). RKWard can not determine, whether it is safe to continue processing R commands, before you have read the file(s) in question.") + message_snip1 + message_snip2;
-	} else if (args->type == RCallbackArgs::REditFiles) {
-		caption = i18n ("Edit file(s)");
-		message = i18n ("A command running in the R-engine wants you to edit one or more file(s). RKWard can not determine, whether it is safe to continue processing R commands, before you have read/edited (and saved) the file(s) in question.") + message_snip1 + message_snip2;
-
-		r_highlighting = true;
-		read_only = false;
-	}
-
+	QStringList display_titles;
 	for (int n = 0; n < count; ++n) {
 		QString title;
 		if (!titles[n].isEmpty ()) title = titles[n];
@@ -105,41 +91,31 @@
 			if (!title.isEmpty ()) title.prepend (": ");
 			title.prepend (wtitle);
 		}
-
-		message.append (title + "\n");
-
-		bool ok = RKWorkplace::mainWorkplace ()->openScriptEditor (KUrl::fromLocalFile (files[n]), QString (), r_highlighting, read_only, title);
-
-		if (!ok)  {
-			bad_files_list.append ("- ").append (title).append (" (").append (files[n]).append (")\n");
-		}
+		display_titles.append (title);
 	}
 
-	if (!bad_files_list.isEmpty ()) {
-		message.append (i18n ("\n\nThe following of the above files were not readable and have not been opened:\n\n"));
-		message.append (bad_files_list);
-	}
+	bool r_highlighting = false;
+	bool read_only = true;
+	bool delete_files = false;
+	if (request->type == RBackendRequest::ShowFiles) {
+		RK_ASSERT (!request->synchronous);
 
-	new ShowEditTextFileAgent (args, message, caption);
-}
+		KMessageBox::informationList (RKWardMainWindow::getMain (), i18n ("A command running in the R-engine wants you to see the following file(s):\n"), display_titles, i18n ("Showing file(s)"), "show_files");
 
-void ShowEditTextFileAgent::done () {
-	RK_TRACE (APP);
-	dialog->deleteLater ();
+		delete_files = request->params["delete"].toBool ();
+		RKRBackendProtocolFrontend::setRequestCompleted (request);
+	} else if (request->type == RBackendRequest::EditFiles) {
+		new ShowEditTextFileAgent (request, i18n ("A command running in the R-engine wants you to edit one or more file(s). Please look at these files, edit them as appriopriate, and save them. When done, press the \"Done\"-button, or close this dialog to resume.\n\n") + display_titles.join ("\n"), i18n ("Edit file(s)"));
 
-	QStringList files = args->params["files"].toStringList ();
-	if ((args->type == RCallbackArgs::RShowFiles) && args->params["delete"].toBool ()) {
-		for (int n = 0; n < files.count (); ++n) {
-			RK_ASSERT (QFile::remove (QString (files[n])));
-		}
+		r_highlighting = true;
+		read_only = false;
+	} else {
+		RK_ASSERT (false);
 	}
 
-	MUTEX_LOCK;
-	// this line is what causes the backend-thread to resume processing:
-	args->done = true;
-	MUTEX_UNLOCK;
-
-	deleteLater ();
+	// do this last, as it may produce error messages, if some of the files could not be opened.
+	for (int n = 0; n < count; ++n) {
+		RKWorkplace::mainWorkplace ()->openScriptEditor (KUrl::fromLocalFile (files[n]), QString (), r_highlighting, read_only, display_titles[n], delete_files);
+	}
 }
 
-#include "showedittextfileagent.moc"

Modified: trunk/rkward/rkward/agents/showedittextfileagent.h
===================================================================
--- trunk/rkward/rkward/agents/showedittextfileagent.h	2010-11-19 12:42:13 UTC (rev 3196)
+++ trunk/rkward/rkward/agents/showedittextfileagent.h	2010-11-19 13:06:38 UTC (rev 3197)
@@ -2,7 +2,7 @@
                           showedittextfileagent  -  description
                              -------------------
     begin                : Tue Sep 13 2005
-    copyright            : (C) 2005 by Thomas Friedrichsmeier
+    copyright            : (C) 2005, 2010 by Thomas Friedrichsmeier
     email                : tfry at users.sourceforge.net
  ***************************************************************************/
 
@@ -20,7 +20,7 @@
 
 #include <qobject.h>
 
-struct RCallbackArgs;
+struct RBackendRequest;
 class KDialog;
 
 /** The purpose of this agent is to display text files for showing and/or editing on request of the R backend. Technically speaking, it gets invoked, whenever the standard R callbacks (ptr_)R_ShowFiles, (ptr_)R_EditFiles, or (ptr_)R_EditFile are called. While the task of simply opening such files for display/editing is rather simple, there is one slightly more difficult issue involved (and hence this class to handle it): In standard R, all these calls are blocking further processing, until the user has closed the shown/edited files. In some cases this may be necessary (for instance if R wants to use with the edited files immediately), in some cases this is an unnecessary nuisance (such as when R simply wants to display a help page or some other purely informational text).
@@ -32,24 +32,20 @@
 @author Thomas Friedrichsmeier
 */
 class ShowEditTextFileAgent : public QObject {
-	Q_OBJECT
 public:
 /** constructor. Do not use directly. Use the static showEditFiles () instead.
 @param args The corresponding RCallbackArgs-record
 @param text Text to display in the dialog. */
-	ShowEditTextFileAgent (RCallbackArgs *args, const QString &text, const QString &caption);
+	ShowEditTextFileAgent (RBackendRequest *request, const QString &text, const QString &caption);
 
-/** destructor */
+/** destructor. Called when the user presses the done button (or closes the notification dialog). Resumes processing in the backend, deletes the agent */
 	~ShowEditTextFileAgent ();
 
 /** This gets called by RInterface, in order to show/edit the files in question. The RCallbackArgs-struct is passed in raw form, and only this function sorts
 out, what exactly needs to be done. Note that this is a static member. It will take care of creating/deleting an agent on its own. */
-	static void showEditFiles (RCallbackArgs *args);
-public slots:
-/** this slot gets called, when the user presses the done button (or closes the notification dialog). Resumes processing in the backend, deletes the agent */
-	void done ();
+	static void showEditFiles (RBackendRequest *request);
 private:
-	RCallbackArgs *args;
+	RBackendRequest *request;
 	KDialog *dialog;
 };
 

Modified: trunk/rkward/rkward/core/rfunctionobject.cpp
===================================================================
--- trunk/rkward/rkward/core/rfunctionobject.cpp	2010-11-19 12:42:13 UTC (rev 3196)
+++ trunk/rkward/rkward/core/rfunctionobject.cpp	2010-11-19 13:06:38 UTC (rev 3197)
@@ -25,10 +25,6 @@
 RFunctionObject::RFunctionObject (RContainerObject *parent, const QString &name) : RObject (parent, name) {
 	RK_TRACE (OBJECTS);
 	type = Function;
-
-	argcount = 0;
-	argnames = 0;
-	argvalues = 0;
 }
 
 RFunctionObject::~RFunctionObject () {
@@ -39,7 +35,7 @@
 	RK_TRACE (OBJECTS);
 
 	QString ret;
-	for (unsigned int i = 0; i < argcount; ++i) {
+	for (int i = 0; i < argnames.size (); ++i) {
 		if (i) ret.append (", ");
 		ret.append (argnames[i]);
 		if (!argvalues[i].isEmpty ()) {
@@ -70,38 +66,17 @@
 	RData *argnames_data = new_data->getStructureVector ()[5];
 	RData *argvalues_data = new_data->getStructureVector ()[6];
 
-	unsigned int new_arglen = argnames_data->getDataLength (); 
 	RK_ASSERT (argnames_data->getDataType () == RData::StringVector);
 	RK_ASSERT (argvalues_data->getDataType () == RData::StringVector);
 
-	RK_ASSERT (new_arglen == argvalues_data->getDataLength ());
-	QString *new_argnames = argnames_data->getStringVector ();
-	QString *new_argvalues = argvalues_data->getStringVector ();
-	argnames_data->detachData ();
-	argvalues_data->detachData ();
+	QStringList new_argnames = argnames_data->getStringVector ();
+	QStringList new_argvalues = argvalues_data->getStringVector ();
+	RK_ASSERT (new_argnames.size () == new_argvalues.size ());
 
-	bool changed = false;
-	if (new_arglen != argcount) {
-		changed = true;
-	} else {
-		for (unsigned int i = 0; i < new_arglen; ++i) {
-			if (argnames[i] != new_argnames[i]) {
-				changed = true;
-				break;
-			}
-
-			if (argvalues[i] != new_argvalues[i]) {
-				changed = true;
-				break;
-			}
-		}
+	if ((new_argnames != argnames) || (new_argvalues != argvalues)) {
+		argnames = new_argnames;
+		argvalues = new_argvalues;
+		return true;
 	}
-
-	argcount = new_arglen;
-	delete [] argnames;
-	delete [] argvalues;
-	argnames = new_argnames;
-	argvalues = new_argvalues;
-
-	return changed;
+	return false;
 }

Modified: trunk/rkward/rkward/core/rfunctionobject.h
===================================================================
--- trunk/rkward/rkward/core/rfunctionobject.h	2010-11-19 12:42:13 UTC (rev 3196)
+++ trunk/rkward/rkward/core/rfunctionobject.h	2010-11-19 13:06:38 UTC (rev 3197)
@@ -36,9 +36,8 @@
 	bool updateStructure (RData *new_data);
 	QString printArgs () const;
 protected:
-	unsigned int argcount;
-	QString *argnames;
-	QString *argvalues;
+	QStringList argnames;
+	QStringList argvalues;
 	bool updateArguments (RData *new_data);
 };
 

Modified: trunk/rkward/rkward/core/rkrownames.cpp
===================================================================
--- trunk/rkward/rkward/core/rkrownames.cpp	2010-11-19 12:42:13 UTC (rev 3196)
+++ trunk/rkward/rkward/core/rkrownames.cpp	2010-11-19 13:06:38 UTC (rev 3197)
@@ -214,7 +214,7 @@
 	lockSyncing (false);
 }
 
-void RKRowNames::setCharacterFromR (int from_row, int to_row, QString *data) {
+void RKRowNames::setCharacterFromR (int from_row, int to_row, const QStringList &data) {
 	RK_TRACE (OBJECTS);
 
 	is_sequential_up_to_row = -1;

Modified: trunk/rkward/rkward/core/rkrownames.h
===================================================================
--- trunk/rkward/rkward/core/rkrownames.h	2010-11-19 12:42:13 UTC (rev 3196)
+++ trunk/rkward/rkward/core/rkrownames.h	2010-11-19 13:06:38 UTC (rev 3197)
@@ -43,7 +43,7 @@
 	void insertRows (int row, int count);
 protected:
 /** Reimplemented to disable duplicate checks during the setText() calls within */
-	void setCharacterFromR (int from_row, int to_row, QString *data);
+	void setCharacterFromR (int from_row, int to_row, const QStringList &data);
 /** Reimplemented to assume sequential row number on initialization */
 	void beginEdit ();
 private:

Modified: trunk/rkward/rkward/core/rkvariable.cpp
===================================================================
--- trunk/rkward/rkward/core/rkvariable.cpp	2010-11-19 12:42:13 UTC (rev 3196)
+++ trunk/rkward/rkward/core/rkvariable.cpp	2010-11-19 13:06:38 UTC (rev 3197)
@@ -19,7 +19,6 @@
 #include <qstringlist.h>
 #include "float.h"
 #include "math.h"
-#include "limits.h"
 
 #include "rcontainerobject.h"
 #include "robjectlist.h"
@@ -158,13 +157,13 @@
 			setNumericFromR (0, getLength () - 1, cdata->getRealVector ());
 		} else if (cdata->getDataType () == RData::IntVector) {
 			unsigned int len = getLength ();
-			double *dd = new double[len];
+			QVector<double> dd;
+			dd.reserve (len);
 			for (unsigned int i = 0; i < len; ++i) {
-				if (cdata->getIntVector ()[i] == INT_MIN) dd[i] = NAN;
+				if (RInterface::isNaInt (cdata->getIntVector ()[i])) dd[i] = NAN;
 				else dd[i] = (double) cdata->getIntVector ()[i];
 			}
 			setNumericFromR (0, getLength () - 1, dd);
-			delete [] dd;
 		}
 
 		// now set the invalid fields (only if they are still NAs in the R data)
@@ -206,7 +205,7 @@
 void RKVariable::setLength (int len) {
 	RK_TRACE (OBJECTS);
 	RK_ASSERT (!getLength ());	// should only be called once
-	RK_ASSERT (dimensions);
+	RK_ASSERT (!dimensions.isEmpty ());
 
 	dimensions[0] = len;
 }
@@ -514,9 +513,10 @@
 	return getText (row);
 }
 
-void RKVariable::setNumericFromR (int from_row, int to_row, double *numdata) {
+void RKVariable::setNumericFromR (int from_row, int to_row, const QVector<double> &numdata) {
 	RK_TRACE (OBJECTS);
 	RK_ASSERT (to_row < getLength ());
+	RK_ASSERT ((to_row - from_row) < numdata.size ());
 
 	if (getDataType () == DataCharacter) {
 		RK_ASSERT (false);		// asserting false to catch cases of this use for now. it's not really a problem, though
@@ -575,9 +575,10 @@
 	return ret;
 }
 
-void RKVariable::setCharacterFromR (int from_row, int to_row, QString *txtdata) {
+void RKVariable::setCharacterFromR (int from_row, int to_row, const QStringList &txtdata) {
 	RK_TRACE (OBJECTS);
 	RK_ASSERT (to_row < getLength ());
+	RK_ASSERT ((to_row - from_row) < txtdata.size ());
 
 	lockSyncing (true);
 	int i=0;

Modified: trunk/rkward/rkward/core/rkvariable.h
===================================================================
--- trunk/rkward/rkward/core/rkvariable.h	2010-11-19 12:42:13 UTC (rev 3196)
+++ trunk/rkward/rkward/core/rkvariable.h	2010-11-19 13:06:38 UTC (rev 3197)
@@ -130,9 +130,9 @@
 /** Discards pending unsynced changes. */
 	void discardUnsyncedChanges ();
 /** like setNumeric, but sets chars. If internalStorage () is numeric, attempts to convert the given strings to numbers. I.e. the function behaves essentially like setText (), but operates on a range of cells. Code may assume that all data comes directly from R, is entirely valid in R. */
-	virtual void setCharacterFromR (int from_row, int to_row, QString *data);
+	virtual void setCharacterFromR (int from_row, int to_row, const QStringList &data);
 /** set numeric values in the given range. Assumes you provide enough values for the range. If internalStorage is String, all values will be converted to strings, so you should use this function only, if you know you are dealing with a numeric object. Code may assume that all data comes directly from R, is entirely valid in R. */
-	void setNumericFromR (int from_row, int to_row, double *data);
+	void setNumericFromR (int from_row, int to_row, const QVector<double> &data);
 /** reimplemented from RObject to change the internal data storage mode, if the var is being edited */
 	bool updateType (RData *new_data);
 /** Extended from RObject::EditData to actually contain data. */

Modified: trunk/rkward/rkward/core/robject.cpp
===================================================================
--- trunk/rkward/rkward/core/robject.cpp	2010-11-19 12:42:13 UTC (rev 3196)
+++ trunk/rkward/rkward/core/robject.cpp	2010-11-19 13:06:38 UTC (rev 3197)
@@ -33,6 +33,10 @@
 
 #include "../debug.h"
 
+namespace RObjectPrivate {
+	QVector<qint32> dim_null (1, 0);
+}
+
 RObject::RObject (RContainerObject *parent, const QString &name) {
 	RK_TRACE (OBJECTS);
 	
@@ -40,18 +44,12 @@
 	RObject::name = name;
 	type = 0;
 	meta_map = 0;
-	classnames = 0;
-	num_classes = 0;
-	dimensions = new int[1];	// safe initialization
-	dimensions[0] = 0;
-	num_dimensions = 0;
+	dimensions = RObjectPrivate::dim_null;	// safe initialization
 }
 
 RObject::~RObject () {
 	RK_TRACE (OBJECTS);
 
-	delete [] dimensions;
-	delete [] classnames;
 	cancelOutstandingCommands ();
 }
 
@@ -139,11 +137,11 @@
 	}
 
 	if (isType (Container | Variable)) {
-		if (num_dimensions == 1) {
+		if (dimensions.size () == 1) {
 			ret.append ("<br><b>" + i18n ("Length: ") + QString::number (dimensions[0]));
-		} else if (num_dimensions > 1) {
+		} else if (dimensions.size () > 1) {
 			ret.append ("<br><b>" + i18n ("Dimensions: "));
-			for (unsigned int i=0; i < num_dimensions; ++i) {
+			for (int i=0; i < dimensions.size (); ++i) {
 				if (i) ret.append (", ");
 				ret.append (QString::number (dimensions[i]));
 			}
@@ -191,25 +189,13 @@
 
 QString RObject::makeClassString (const QString &sep) const {
 	RK_TRACE (OBJECTS);
-	QString ret;
-	bool first = true;
-	for (unsigned int i=0; i < numClasses (); ++i) {
-		if (first) first = false;
-		else ret.append (sep);
-		ret.append (getClassName (i));
-	}
-	return ret;
+	return (classnames.join (sep));
 }
 
 bool RObject::inherits (const QString &class_name) const {
 	RK_TRACE (OBJECTS);
 
-	for (unsigned int i=0; i < numClasses (); ++i) {
-		if (getClassName (i) == class_name) {
-			return true;
-		}
-	}
-	return false;
+	return (classnames.contains (class_name));
 }
 
 QString RObject::makeChildName (const QString &short_child_name, bool) const {
@@ -402,25 +388,12 @@
 
 	bool change = false;
 
-	unsigned int new_len = new_data->getDataLength ();
-	QString *new_classes = new_data->getStringVector ();
-	new_data->detachData ();
-
-	if (numClasses () != new_len) {
+	QStringList new_classes = new_data->getStringVector ();
+	if (new_classes != classnames) {
 		change = true;
-	} else {
-		for (unsigned int cn=0; cn < numClasses (); ++cn) {
-			if (classnames[cn] != new_classes[cn]) {
-				change = true;
-				break;
-			}
-		}
+		classnames = new_classes;
 	}
 
-	num_classes = new_len;
-	delete [] classnames;
-	classnames = new_classes;
-
 	return change;
 }
 
@@ -462,27 +435,19 @@
 	RK_ASSERT (new_data->getDataLength () >= 1);
 	RK_ASSERT (new_data->getDataType () == RData::IntVector);
 
-	bool changed = false;
-
-	unsigned int new_len = new_data->getDataLength ();
-	int *new_dimensions = new_data->getIntVector ();
-	new_data->detachData ();
-
-	if (num_dimensions != new_len) {
-		changed = true;
-	} else {
-		for (unsigned int d=0; d < num_dimensions; ++d) {
-			if (dimensions[d] != new_dimensions[d]) {
-				changed = true;
-				break;
+	QVector<qint32> new_dimensions = new_data->getIntVector ();
+	if (new_dimensions != dimensions) {
+		if (new_dimensions.isEmpty ()) {
+			if (dimensions != RObjectPrivate::dim_null) {
+				dimensions = RObjectPrivate::dim_null;
+				return true;
 			}
+		} else {
+			dimensions = new_dimensions;
+			return true;
 		}
 	}
-	delete [] dimensions;
-	num_dimensions = new_len;
-	dimensions = new_dimensions;
-
-	return true;
+	return false;
 }
 
 void RObject::rename (const QString &new_short_name) {

Modified: trunk/rkward/rkward/core/robject.h
===================================================================
--- trunk/rkward/rkward/core/robject.h	2010-11-19 12:42:13 UTC (rev 3196)
+++ trunk/rkward/rkward/core/robject.h	2010-11-19 13:06:38 UTC (rev 3197)
@@ -118,17 +118,14 @@
 	void rename (const QString &new_short_name);
 	void remove (bool removed_in_workspace);
 
-	unsigned int numClasses () const { return num_classes; };
-	QString getClassName (int index) const { return classnames[index]; };
+	const QStringList &classNames () const { return classnames; };
 	QString makeClassString (const QString &sep) const;
 /** @param class_name the name of the class to check for
 @returns true, if the object has (among others) the given class, false otherwise */
 	bool inherits (const QString &class_name) const;
 
-/** get number of dimensions. For simplicity, In RKWard each object is considered to have at least one dimension (but that dimension may be 0 in length) */
-	unsigned int numDimensions () const { return num_dimensions; };
-/** get the length of the given dimension. The object is guaranteed to have at least 1 dimension, so calling getDimension (0) is always safe */
-	int getDimension (int index) const { return dimensions[index]; };
+/** get vector of dimensions. For simplicity, In RKWard each object is considered to have at least one dimension (but that dimension may be 0 in length) */
+	const QVector<qint32> &getDimensions () const { return dimensions; };
 /** short hand for getDimension (0). Meaningful for one-dimensional objects */
 	int getLength () const { return dimensions[0]; };
 
@@ -195,10 +192,8 @@
 	RContainerObject *parent;
 	QString name;
 	int type;
-	int *dimensions;
-	unsigned int num_dimensions;
-	QString *classnames;
-	unsigned int num_classes;
+	QVector<qint32> dimensions;
+	QStringList classnames;
 
 	virtual QString makeChildBaseName (const QString &short_child_name) const;
 

Modified: trunk/rkward/rkward/main.cpp
===================================================================
--- trunk/rkward/rkward/main.cpp	2010-11-19 12:42:13 UTC (rev 3196)
+++ trunk/rkward/rkward/main.cpp	2010-11-19 13:06:38 UTC (rev 3197)
@@ -56,6 +56,7 @@
 #include <ktemporaryfile.h>
 
 #include <qstring.h>
+#include <QMutex>
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -77,16 +78,19 @@
 int RK_Debug_Level = 0;
 int RK_Debug_Flags = ALL;
 int RK_Debug_CommandStep = 0;
+QMutex RK_Debug_Mutex;
 
 static KCmdLineOptions options;
 
 void RKDebugMessageOutput (QtMsgType type, const char *msg) {
+	RK_Debug_Mutex.lock ();
 	if (type == QtFatalMsg) {
 		fprintf (stderr, "%s\n", msg);
 	}
 	RKSettingsModuleDebug::debug_file->write (msg);
 	RKSettingsModuleDebug::debug_file->write ("\n");
 	RKSettingsModuleDebug::debug_file->flush ();
+	RK_Debug_Mutex.unlock ();
 }
 
 int main(int argc, char *argv[]) {
@@ -101,7 +105,6 @@
 	options.add ("debug-level <level>", ki18n ("Verbosity of debug messages (0-5)"), "2");
 	options.add ("debug-flags <flags>", ki18n ("Mask for components to debug (see debug.h)"), "8191");
 	options.add ("debugger <command>", ki18n ("Debugger (enclose any debugger arguments in single quotes ('') together with the command)"), "");
-	options.add ("disable-stack-check", ki18n ("Disable R C stack checking"), 0);
 	options.add ("+[File]", ki18n ("R workspace file to open"), 0);
 
 	KAboutData aboutData("rkward", QByteArray (), ki18n ("RKWard"), VERSION, ki18n ("Frontend to the R statistics language"), KAboutData::License_GPL, ki18n ("(c) 2002, 2004, 2005, 2006, 2007, 2008, 2009, 2010"), KLocalizedString (), "http://rkward.sf.net", "rkward-devel at lists.sourceforge.net");
@@ -147,7 +150,6 @@
 	if (args->count ()) {
 		stoptions->initial_url = KUrl (args->makeURL (args->arg (0).toLatin1()));
 	}
-	stoptions->no_stack_check = args->isSet ("disable-stack-check");
 	stoptions->evaluate = args->getOption ("evaluate");
 
 	RKWardApplication app;

Modified: trunk/rkward/rkward/plugin/rkcomponentproperties.cpp
===================================================================
--- trunk/rkward/rkward/plugin/rkcomponentproperties.cpp	2010-11-19 12:42:13 UTC (rev 3196)
+++ trunk/rkward/rkward/plugin/rkcomponentproperties.cpp	2010-11-19 13:06:38 UTC (rev 3197)
@@ -744,7 +744,7 @@
 
 	// first check dimensionality
 	if (dims > 0) {
-		if ((int) object->numDimensions () != dims) return false;
+		if (object->getDimensions ().size () != dims) return false;
 	}
 	int olength = object->getLength ();
 	if ((min_length > 0) && (olength < min_length)) return false;

Modified: trunk/rkward/rkward/rbackend/CMakeLists.txt
===================================================================
--- trunk/rkward/rkward/rbackend/CMakeLists.txt	2010-11-19 12:42:13 UTC (rev 3196)
+++ trunk/rkward/rkward/rbackend/CMakeLists.txt	2010-11-19 13:06:38 UTC (rev 3197)
@@ -8,25 +8,67 @@
 
 INCLUDE_DIRECTORIES( ${R_INCLUDEDIR} ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ${KDE4_INCLUDE_DIR} ${QT_INCLUDES}  )
 
-########### next target ###############
+SET (
+	rbackend_shared_SRCS
+	rkrbackendprotocol_shared.cpp
+	rdata.cpp
+)
 
-SET(
-	rbackend_STAT_SRCS
-	rembedinternal.cpp
+SET (
+	rbackend_backend_SRCS
+	rkrbackend.cpp
+	rkpthreadsupport.cpp
+	rksignalsupport.cpp
+	rklocalesupport.cpp
+	rkrsupport.cpp
+	rkstructuregetter.cpp
+	rkrbackendprotocol_backend.cpp
+)
+
+SET (
+	rbackend_frontend_SRCS
 	rinterface.cpp
-	rthread.cpp
 	rcommand.cpp
 	rcommandreceiver.cpp
 	rcommandstack.cpp
-	rdata.cpp
-	rkpthreadsupport.cpp
-	rksignalsupport.cpp
-	rklocalesupport.cpp
+	rkrbackendprotocol_frontend.cpp
 )
 
+SET(RBACKEND_SPLIT 1)
+IF(RBACKEND_SPLIT)
+	SET (
+		rbackend_FRONTEND_SRCS
+		${rbackend_frontend_SRCS}
+		${rbackend_shared_SRCS}
+		rkfrontendtransmitter.cpp
+		rktransmitter.cpp
+	)
+	QT4_AUTOMOC(${rbackend_FRONTEND_SRCS})
+	ADD_LIBRARY(rbackend STATIC ${rbackend_FRONTEND_SRCS})
+	TARGET_LINK_LIBRARIES(rbackend ${CMAKE_THREAD_LIBS_INIT})
 
-QT4_AUTOMOC(${rbackend_STAT_SRCS})
+	SET (
+		rbackend_BACKEND_SRCS
+		${rbackend_backend_SRCS}
+		${rbackend_shared_SRCS}
+		rkbackendtransmitter.cpp
+		rktransmitter.cpp
+	)
+	QT4_AUTOMOC(${rbackend_BACKEND_SRCS})
+	ADD_DEFINITIONS (-DRKWARD_SPLIT_PROCESS)
+	KDE4_ADD_EXECUTABLE(rkward.rbackend ${rbackend_BACKEND_SRCS})
+	TARGET_LINK_LIBRARIES(rkward.rbackend ${R_USED_LIBS} ${CMAKE_THREAD_LIBS_INIT} ${KDE4_KDECORE_LIBS})
+	LINK_DIRECTORIES(${R_SHAREDLIBDIR})
+ELSE(RBACKEND_SPLIT)
+	SET (
+		rbackend_ALL_SRCS
+		${rbackend_frontend_SRCS}
+		${rbackend_shared_SRCS}
+		${rbackend_backend_SRCS}
+	)
 
-ADD_LIBRARY(rbackend STATIC ${rbackend_STAT_SRCS})
-TARGET_LINK_LIBRARIES(rbackend ${R_USED_LIBS} ${CMAKE_THREAD_LIBS_INIT})
-LINK_DIRECTORIES(${R_SHAREDLIBDIR})
+	QT4_AUTOMOC(${rbackend_ALL_SRCS})
+	ADD_LIBRARY(rbackend STATIC ${rbackend_ALL_SRCS})
+	TARGET_LINK_LIBRARIES(rbackend ${R_USED_LIBS} ${CMAKE_THREAD_LIBS_INIT})
+	LINK_DIRECTORIES(${R_SHAREDLIBDIR})
+ENDIF(RBACKEND_SPLIT)

Modified: trunk/rkward/rkward/rbackend/rcommand.cpp
===================================================================
--- trunk/rkward/rkward/rbackend/rcommand.cpp	2010-11-19 12:42:13 UTC (rev 3196)
+++ trunk/rkward/rkward/rbackend/rcommand.cpp	2010-11-19 13:06:38 UTC (rev 3197)
@@ -19,12 +19,11 @@
 #include "rcommandreceiver.h"
 #include "rinterface.h"
 #include "../windows/rkcommandlog.h"
+#include "rkrbackendprotocol_shared.h"
 
 #include "../debug.h"
 #include "../rkglobals.h"
 
-#define MAX_RECEIVERS 3
-
 RCommandBase::RCommandBase (bool is_chain) {
 	is_command_chain = is_chain;
 	RCommandBase::parent = 0;
@@ -57,10 +56,11 @@
 	if (_command.isEmpty ()) _type |= EmptyCommand;
 	status = 0;
 	_rk_equiv = rk_equiv;
-	RCommand::receivers = new RCommandReceiver* [MAX_RECEIVERS];
-	num_receivers = 0;
-	addReceiver (receiver);
-	addReceiver (RKCommandLog::getLog ());
+	for (int i = 0; i < MAX_RECEIVERS_PER_RCOMMAND; ++i) receivers[i] = 0;
+	if (!(type & Internal)) {
+		addReceiver (receiver);
+		addReceiver (RKCommandLog::getLog ());
+	}
 }
 
 RCommand::~RCommand(){
@@ -69,7 +69,6 @@
 	for (QList<ROutput*>::const_iterator it = output_list.constBegin (); it != output_list.constEnd (); ++it) {
 		delete (*it);
 	}
-	delete [] receivers;
 	// The output_list itself is cleared automatically
 }
 
@@ -78,13 +77,15 @@
 
 	if (!receiver) return;
 
-	if (num_receivers >= MAX_RECEIVERS) {
-		RK_DO (qDebug ("Too many receivers for command"), RBACKEND, DL_ERROR);
-		return;
+	for (int i = 0; i < MAX_RECEIVERS_PER_RCOMMAND; ++i) {
+		if (receivers[i] == 0) {
+			receivers[i] = receiver;
+			receiver->addCommand (this);
+			return;
+		}
 	}
 
-	receivers[num_receivers++] = receiver;
-	receiver->addCommand (this);
+	RK_DO (qDebug ("Too many receivers for command"), RBACKEND, DL_ERROR);
 }
 
 void RCommand::removeReceiver (RCommandReceiver *receiver) {
@@ -92,27 +93,21 @@
 
 	if (!receiver) return;
 
-	RCommandReceiver **newlist = new RCommandReceiver* [MAX_RECEIVERS];
-	int num_new_receivers = 0;
-	for (int i=0; i < num_receivers; ++i) {
-		if (receivers[i] != receiver) {
-			newlist[num_new_receivers++] = receivers[i];
+	for (int i = 0; i < MAX_RECEIVERS_PER_RCOMMAND; ++i) {
+		if (receivers[i] == receiver) {
+			receivers[i] = 0;
+			return;
 		}
 	}
 
-	if (num_new_receivers == num_receivers) {
-		RK_DO (qDebug ("Was not a receiver in RCommand::removeReceiver"), RBACKEND, DL_WARNING);
-	}
-
-	delete [] receivers;
-	receivers = newlist;
-	num_receivers = num_new_receivers;
+	RK_DO (qDebug ("Was not a receiver in RCommand::removeReceiver: %p", receiver), RBACKEND, DL_WARNING);
 }
 
 void RCommand::finished () {
 	RK_TRACE (RBACKEND);
 
-	for (int i=0; i < num_receivers; ++i) {
+	for (int i=0; i < MAX_RECEIVERS_PER_RCOMMAND; ++i) {
+		if (receivers[i] == 0) continue;
 		receivers[i]->delCommand (this);
 		receivers[i]->rCommandDone (this);
 	}
@@ -121,7 +116,8 @@
 void RCommand::newOutput (ROutput *output) {
 	RK_TRACE (RBACKEND);
 
-	for (int i=0; i < num_receivers; ++i) {
+	for (int i=0; i < MAX_RECEIVERS_PER_RCOMMAND; ++i) {
+		if (receivers[i] == 0) continue;
 		receivers[i]->newOutput (this, output);
 	}
 }
@@ -171,3 +167,26 @@
 	}
 	return ret;
 }
+
+void RCommand::mergeAndDeleteProxy (RCommandProxy *proxy) {
+	RK_TRACE (RBACKEND);
+
+	RK_ASSERT (proxy);
+	RK_ASSERT (proxy->id == _id);
+	RK_ASSERT (proxy->type == _type);
+
+	status = proxy->status;
+	swallowData (*proxy);
+	delete proxy;
+}
+
+RCommandProxy* RCommand::makeProxy () const {
+	RK_TRACE (RBACKEND);
+	RK_ASSERT (status == 0);	// Initialization from an already touched command is not a real problem, but certainly no expected usage
+	RK_ASSERT (getDataType () == RData::NoData);
+
+	RCommandProxy *ret = new RCommandProxy (_command, _type);
+	ret->id = _id,
+	ret->status = status;
+	return ret;
+}

Modified: trunk/rkward/rkward/rbackend/rcommand.h
===================================================================
--- trunk/rkward/rkward/rbackend/rcommand.h	2010-11-19 12:42:13 UTC (rev 3196)
+++ trunk/rkward/rkward/rbackend/rcommand.h	2010-11-19 13:06:38 UTC (rev 3197)
@@ -2,7 +2,7 @@
                           rcommand.h  -  description
                              -------------------
     begin                : Mon Nov 11 2002
-    copyright            : (C) 2002, 2006, 2007, 2009 by Thomas Friedrichsmeier
+    copyright            : (C) 2002, 2006, 2007, 2009, 2010 by Thomas Friedrichsmeier
     email                : tfry at users.sourceforge.net
  ***************************************************************************/
 
@@ -25,8 +25,11 @@
 
 #include "rdata.h"
 
+#define MAX_RECEIVERS_PER_RCOMMAND 3
+
 class RCommandReceiver;
 class RCommand;
+class RCommandProxy;
 class RCommandChain;
 
 /** Base class for RCommand and RCommandChain, to make it possible to store both in the same list */
@@ -73,24 +76,6 @@
 
 typedef QList<ROutput*> ROutputList;
 
-/*
-struct RGetValueRequest {
-private:
-friend class RInterface;
-friend class RThread;
-	char **call;
-	int call_length;
-};
-
-struct RGetValueReply {
-private:
-friend class RInterface;
-friend class RThread;
-	char **reply;
-	int reply_length;
-};
-*/
-
 /** For introductory information on using RCommand, see \ref UsingTheInterfaceToR 
 
 	This class is used to encapsulate an R-command, so it can be easily identified
@@ -110,7 +95,6 @@
 	kept around very long, so they should not be a memory issue.
   *@author Thomas Friedrichsmeier
   */
-  
 class RCommand : public RData, public RCommandBase {
 public:
 /** constructs an RCommand.
@@ -120,7 +104,7 @@
 @param receiver The RCommandReceiver this command should be passed on to, when finished.
 @param flags A freely assignable integer, that you can use to identify what the command was all about. Only the RCommandReceiver handling the results will have to know what exactly the flags mean.
 */
-	explicit RCommand (const QString &command, int type = 0, const QString &rk_equiv = QString::null, RCommandReceiver *receiver=0, int flags=0);
+	explicit RCommand (const QString &command, int type, const QString &rk_equiv = QString::null, RCommandReceiver *receiver=0, int flags=0);
 /** destructor. Note: you should not delete RCommands manually. This is done in RInterface. TODO: make protected */
 	~RCommand();
 /** @returns the type as specified in RCommand::RCommand */
@@ -153,6 +137,7 @@
 		Sync=16,		/**< Command is used to sync data to or from R-space. Typically used in the editor classes */
 		EmptyCommand=32,		/**< Command is empty and will not be processed (an empty command may be used as a "marker") */
 		Console=64,	/**< Command originated in the console. These commands will get some extra treatment in RKwatch */
+		Internal=128,	/**< Command is meant to be used in the backend, only. Do not use outside rbackend classes! */
 		GetIntVector=512,			/**< Try to fetch result as an array of integers */
 		GetStringVector=1024,	/**< Try to fetch result as an array of chars */
 		GetRealVector=2048,		/**< Try to fetch result as an array of doubles */
@@ -201,8 +186,11 @@
 	ROutputList &getOutput () { return output_list; };
 /** modify the command string. DO NOT CALL THIS after the command has been submitted! */
 	void setCommand (const QString &command) { _command = command; };
+
+/** creates a proxy for this RCommand */
+	RCommandProxy* makeProxy () const;
+	void mergeAndDeleteProxy (RCommandProxy *proxy);
 private:
-friend class RThread;
 friend class RInterface;
 friend class RCommandStack;
 friend class RCommandStackModel;
@@ -214,12 +202,11 @@
 	QString _command;
 	int _type;
 	int _flags;
-	int status;
+	int status;  
 	QString _rk_equiv;
 	int _id;
 	static int next_id;
-	int num_receivers;
-	RCommandReceiver **receivers;
+	RCommandReceiver *receivers[MAX_RECEIVERS_PER_RCOMMAND];
 };
 
 #endif

Modified: trunk/rkward/rkward/rbackend/rcommandstack.cpp
===================================================================
--- trunk/rkward/rkward/rbackend/rcommandstack.cpp	2010-11-19 12:42:13 UTC (rev 3196)
+++ trunk/rkward/rkward/rbackend/rcommandstack.cpp	2010-11-19 13:06:38 UTC (rev 3197)
@@ -95,11 +95,9 @@
 	RK_TRACE (RBACKEND);
 
 	if (RK_Debug_CommandStep) {
-		MUTEX_UNLOCK;
 		QTime t;
 		t.start ();
 		while (t.elapsed () < RK_Debug_CommandStep) {}
-		MUTEX_LOCK;
 	}
 
 	clearFinishedChains ();
@@ -199,13 +197,6 @@
 
 	static_model = this;
 	listeners = 0;
-	have_mutex_lock = false;
-
-	connect (this, SIGNAL (itemAboutToBeAdded(RCommandBase*)), this, SLOT (relayItemAboutToBeAdded(RCommandBase*)), Qt::BlockingQueuedConnection);
-	connect (this, SIGNAL (itemAdded()), this, SLOT (relayItemAdded()), Qt::BlockingQueuedConnection);
-	connect (this, SIGNAL (itemAboutToBeRemoved(RCommandBase*)), this, SLOT (relayItemAboutToBeRemoved(RCommandBase*)), Qt::BlockingQueuedConnection);
-	connect (this, SIGNAL (itemRemoved()), this, SLOT (relayItemRemoved()), Qt::BlockingQueuedConnection);
-	connect (this, SIGNAL (itemChanged(RCommandBase*)), this, SLOT (relayItemChanged(RCommandBase*)), Qt::BlockingQueuedConnection);
 }
 
 RCommandStackModel::~RCommandStackModel () {
@@ -217,7 +208,6 @@
 
 void RCommandStackModel::addListener () {
 	RK_TRACE (RBACKEND);
-	lockMutex ();	// this should make sure, a listener is not added in the middle of a beginRowsXXX and endRowsXXX signal pair
 
 	++listeners;
 }
@@ -226,13 +216,12 @@
 	RK_TRACE (RBACKEND);
 
 	--listeners;
-	if (!listeners) unlockMutex ();
+	RK_ASSERT (listeners >= 0);
 }
 
 QModelIndex RCommandStackModel::index (int row, int column, const QModelIndex& parent) const {
 	RK_ASSERT (listeners > 0);
 	RK_TRACE (RBACKEND);
-	lockMutex ();
 
 	RCommandBase* index_data = 0;
 
@@ -264,7 +253,6 @@
 QModelIndex RCommandStackModel::parent (const QModelIndex& child) const {
 	RK_ASSERT (listeners);
 	RK_TRACE (RBACKEND);
-	lockMutex ();
 
 	RCommandBase* index_data;
 	if (!child.isValid()) {
@@ -289,7 +277,6 @@
 int RCommandStackModel::rowCount (const QModelIndex& parent) const {
 	RK_ASSERT (listeners);
 	RK_TRACE (RBACKEND);
-	lockMutex ();
 
 	if (!parent.isValid ()) return 1;
 
@@ -315,7 +302,6 @@
 int RCommandStackModel::columnCount (const QModelIndex&) const {
 	RK_ASSERT (listeners);
 	RK_TRACE (RBACKEND);
-	lockMutex ();
 
 	return NUM_COLS;
 }
@@ -323,7 +309,6 @@
 QVariant RCommandStackModel::data (const QModelIndex& index, int role) const {
 	RK_ASSERT (listeners);
 	RK_TRACE (RBACKEND);
-	lockMutex ();
 
 	if (!index.isValid ()) return QVariant ();
 	RK_ASSERT (index.model () == this);
@@ -377,7 +362,6 @@
 Qt::ItemFlags RCommandStackModel::flags (const QModelIndex& index) const {
 	RK_ASSERT (listeners);
 	RK_TRACE (RBACKEND);
-	lockMutex ();
 
 	if (!index.isValid ()) return 0;
 	RK_ASSERT (index.model () == this);
@@ -392,7 +376,6 @@
 QVariant RCommandStackModel::headerData (int section, Qt::Orientation orientation, int role) const {
 	RK_ASSERT (listeners);
 	RK_TRACE (RBACKEND);
-	lockMutex ();
 
 	if ((orientation == Qt::Horizontal) && (role == Qt::DisplayRole)) {
 		if (section == MAIN_COL) return (i18n ("Command"));
@@ -428,97 +411,22 @@
 	if (!listeners) return;
 	RK_TRACE (RBACKEND);
 
-	if (RInterface::inRThread ()) {
-		MUTEX_UNLOCK;	// release the mutex in the R thread, as the main thread will need it.
-		emit (itemAboutToBeRemoved (parent));
-		MUTEX_LOCK;
-	} else {
-		relayItemAboutToBeRemoved (parent);
-	}
+	QModelIndex parent_index = indexFor (parent);
+	// items are always removed at the front
+	beginRemoveRows (parent_index, 0, 0);
 }
 
 void RCommandStackModel::popComplete () {
 	if (!listeners) return;
 	RK_TRACE (RBACKEND);
 
-	if (RInterface::inRThread ()) {
-		MUTEX_UNLOCK;	// release the mutex in the R thread, as the main thread will need it.
-		emit (itemRemoved ());
-		MUTEX_LOCK;
-	} else {
-		relayItemRemoved ();
-	}
+	endRemoveRows ();
 }
 
 void RCommandStackModel::aboutToAdd (RCommandBase* parent) {
 	if (!listeners) return;
 	RK_TRACE (RBACKEND);
 
-	if (RInterface::inRThread ()) {
-		MUTEX_UNLOCK;	// release the mutex in the R thread, as the main thread will need it.
-		emit (itemAboutToBeAdded (parent));
-		MUTEX_LOCK;
-	} else {
-		relayItemAboutToBeAdded (parent);
-	}
-}
-
-void RCommandStackModel::addComplete () {
-	if (!listeners) return;
-	RK_TRACE (RBACKEND);
-
-	if (RInterface::inRThread ()) {
-		MUTEX_UNLOCK;	// release the mutex in the R thread, as the main thread will need it.
-		emit (itemAdded ());
-		MUTEX_LOCK;
-	} else {
-		relayItemAdded ();
-	}
-}
-
-void RCommandStackModel::itemChange (RCommandBase* item) {
-	if (!listeners) return;
-	RK_TRACE (RBACKEND);
-
-	if (RInterface::inRThread ()) {
-		MUTEX_UNLOCK;	// release the mutex in the R thread, as the main thread will need it.
-		emit (itemChanged (item));
-		MUTEX_LOCK;
-	} else {
-		relayItemChanged (item);
-	}
-}
-
-void RCommandStackModel::lockMutex () const {
-	if (have_mutex_lock) return;
-	RK_TRACE (RBACKEND);
-
-	RK_ASSERT (!RInterface::inRThread ());
-
-	MUTEX_LOCK;
-// We're playing silly const games, here, as the reimplementations from QAbstractItemModel need to be const.
-// Well, we're not really changing anything, though, just keeping track of the mutex lock.
-	bool *cheat = const_cast<bool*> (&have_mutex_lock);
-	*cheat = true;
-
-	QTimer::singleShot (0, const_cast<RCommandStackModel*> (this), SLOT (unlockMutex()));
-}
-
-void RCommandStackModel::unlockMutex () {
-	if (!have_mutex_lock) return;
-	RK_TRACE (RBACKEND);
-
-	RK_ASSERT (!RInterface::inRThread ());
-
-	MUTEX_UNLOCK;
-	have_mutex_lock = false;
-}
-
-void RCommandStackModel::relayItemAboutToBeAdded (RCommandBase* parent) {
-	RK_TRACE (RBACKEND);
-
-	RK_ASSERT (!RInterface::inRThread ());
-
 	QModelIndex parent_index = indexFor (parent);
 	if ((!parent) || parent->commandPointer ()) {
 		beginInsertRows (parent_index, 0, 0);
@@ -529,37 +437,17 @@
 	}
 }
 
-void RCommandStackModel::relayItemAdded () {
+void RCommandStackModel::addComplete () {
+	if (!listeners) return;
 	RK_TRACE (RBACKEND);
 
-	RK_ASSERT (!RInterface::inRThread ());
-
 	endInsertRows ();
 }
 
-void RCommandStackModel::relayItemAboutToBeRemoved (RCommandBase* parent) {
+void RCommandStackModel::itemChange (RCommandBase* item) {
+	if (!listeners) return;
 	RK_TRACE (RBACKEND);
 
-	RK_ASSERT (!RInterface::inRThread ());
-
-	QModelIndex parent_index = indexFor (parent);
-	// items are always removed at the front
-	beginRemoveRows (parent_index, 0, 0);
-}
-
-void RCommandStackModel::relayItemRemoved () {
-	RK_TRACE (RBACKEND);
-
-	RK_ASSERT (!RInterface::inRThread ());
-
-	endRemoveRows ();
-}
-
-void RCommandStackModel::relayItemChanged (RCommandBase* item) {
-	RK_TRACE (RBACKEND);
-
-	RK_ASSERT (!RInterface::inRThread ());
-
 	QModelIndex item_index = indexFor (item);
 	emit (dataChanged (item_index, item_index));
 }

Modified: trunk/rkward/rkward/rbackend/rcommandstack.h
===================================================================
--- trunk/rkward/rkward/rbackend/rcommandstack.h	2010-11-19 12:42:13 UTC (rev 3196)
+++ trunk/rkward/rkward/rbackend/rcommandstack.h	2010-11-19 13:06:38 UTC (rev 3197)
@@ -2,7 +2,7 @@
                           rcommandstack  -  description
                              -------------------
     begin                : Mon Sep 6 2004
-    copyright            : (C) 2004, 2007 by Thomas Friedrichsmeier
+    copyright            : (C) 2004, 2007, 2010 by Thomas Friedrichsmeier
     email                : tfry at users.sourceforge.net
  ***************************************************************************/
 
@@ -123,38 +123,10 @@
 	/** call this, when you have made changes to an item, that should be reflected in RControlWindow
 	@param item The item that was changed */
 	void itemChange (RCommandBase* item);
-private slots:
-	/** compagnon to lockMutex () */
-	void unlockMutex ();
-	/** the purpose of these signals and slots is to make sure the aboutToPop(), popComplete(), aboutToAdd(), addComplete(), and itemChange() methods are *always* dealt with in the main (GUI) thread. */
-	void relayItemAboutToBeAdded (RCommandBase* parent);
-	/** @see relayItemAboutToBeAdded() */
-	void relayItemAdded ();
-	/** @see relayItemAboutToBeAdded() */
-	void relayItemAboutToBeRemoved (RCommandBase* parent);
-	/** @see relayItemAboutToBeAdded() */
-	void relayItemRemoved ();
-	/** @see relayItemAboutToBeAdded() */
-	void relayItemChanged (RCommandBase* item);
-signals:
-	/** @see relayItemAboutToBeAdded() */
-	void itemAboutToBeAdded (RCommandBase* parent);
-	/** @see relayItemAboutToBeAdded() */
-	void itemAdded ();
-	/** @see relayItemAboutToBeAdded() */
-	void itemAboutToBeRemoved (RCommandBase* parent);
-	/** @see relayItemAboutToBeAdded() */
-	void itemRemoved ();
-	/** @see relayItemAboutToBeAdded() */
-	void itemChanged (RCommandBase* item);
 private:
-	/** locks the mutex temporarily (until the event loop is next entered again), and only, if not already locked */
-	void lockMutex () const;
 	/** number of listeners. If there are no listeners, the model will do almost nothing at all */
 	int listeners;
 	static RCommandStackModel* static_model;
-	/** @see lockMutex() */
-	bool have_mutex_lock;
 
 	/** create a model index for the given item */
 	QModelIndex indexFor (RCommandBase *item);

Modified: trunk/rkward/rkward/rbackend/rdata.cpp
===================================================================
--- trunk/rkward/rkward/rbackend/rdata.cpp	2010-11-19 12:42:13 UTC (rev 3196)
+++ trunk/rkward/rkward/rbackend/rdata.cpp	2010-11-19 13:06:38 UTC (rev 3197)
@@ -2,7 +2,7 @@
                           rdata  -  description
                              -------------------
     begin                : Sun Oct 01 2006
-    copyright            : (C) 2006 by Thomas Friedrichsmeier
+    copyright            : (C) 2006, 2010 by Thomas Friedrichsmeier
     email                : tfry at users.sourceforge.net
  ***************************************************************************/
 
@@ -25,7 +25,6 @@
 	RK_TRACE (RBACKEND);
 	datatype = NoData;
 	data = 0;
-	length = 0; 
 }
 
 RData::~RData () {
@@ -34,94 +33,113 @@
 	discardData ();
 }
 
-double *RData::getRealVector () {
-	return (static_cast<double *> (data));
+RData::RealStorage &RData::getRealVector () const {
+	return (*static_cast<RealStorage *> (data));
 }
 
-int *RData::getIntVector () {
-	return (static_cast<int *> (data));
+RData::IntStorage &RData::getIntVector () const {
+	return (*static_cast<IntStorage *> (data));
 }
 
-QString *RData::getStringVector () {
-	return (static_cast<QString *> (data));
+RData::StringStorage &RData::getStringVector () const {
+	return (*static_cast<StringStorage *> (data));
 }
 
-RData **RData::getStructureVector () {
-	return (static_cast<RData **> (data));
+RData::RDataStorage &RData::getStructureVector () const {
+	return (*static_cast<RDataStorage *> (data));
 }
 
-void RData::detachData () {
-	data = 0;
-	length = 0;
-	datatype = NoData;
-}
-
 void RData::discardData () {
 	RK_TRACE (RBACKEND);
 
 	if (datatype == StructureVector) {
-		RData **sdata = getStructureVector ();
-		for (int i=length-1; i >= 0; --i) {
+		RDataStorage sdata = getStructureVector ();
+		for (int i=sdata.size ()-1; i >= 0; --i) {
 			delete (sdata[i]);
 		}
-		delete [] sdata;
+		delete (static_cast<RDataStorage *> (data));
 	} else if (datatype == IntVector) {
-		int *idata = getIntVector ();
-		delete [] idata;
+		delete (static_cast<IntStorage *> (data));
 	} else if (datatype == RealVector) {
-		double *rdata = getRealVector ();
-		delete [] rdata;
+		delete (static_cast<RealStorage *> (data));
 	} else if (datatype == StringVector) {
-		QString *stdata = getStringVector ();
-		delete [] stdata;
+		delete (static_cast<StringStorage *> (data));
 	} else {
 		RK_ASSERT (datatype == NoData);
 	}
 
-	detachData ();
+	data = 0;
+	datatype = RData::NoData;
 }
 
-void RData::setData (RData *from) {
-	data = from->data;
-	length = from->length;
-	datatype = from->datatype;
+unsigned int RData::getDataLength() const {
+	if (datatype == RealVector) return (getRealVector ().size ());
+	if (datatype == IntVector) return (getIntVector ().size ());
+	if (datatype == StringVector) return (getStringVector ().size ());
+	if (datatype == StructureVector) return (getStructureVector ().size ());
+	return 0;
+}
 
-	from->detachData ();
-	delete from;
+void RData::swallowData (RData &from) {
+	data = from.data;
+	datatype = from.datatype;
+
+	from.data = 0;
+	from.datatype = RData::NoData;
 }
 
+void RData::setData (const RDataStorage &from) {
+	data = new RDataStorage (from);
+	datatype = RData::StructureVector;
+}
+
+void RData::setData (const IntStorage &from) {
+	data = new IntStorage (from);
+	datatype = RData::IntVector;
+}
+
+void RData::setData (const RealStorage &from) {
+	data = new RealStorage (from);
+	datatype = RData::RealVector;
+}
+
+void RData::setData (const StringStorage &from) {
+	data = new StringStorage (from);
+	datatype = RData::StringVector;
+}
+
 void RData::printStructure (const QString &prefix) {
 	switch (datatype) {
 		case NoData:
-			qDebug ("%s: NoData, length %d", prefix.toLatin1().data(), length);
+			qDebug ("%s: NoData, length %d", prefix.toLatin1().data(), getDataLength ());
 			break;
 		case IntVector:
-			qDebug ("%s: IntVector, length %d", prefix.toLatin1().data(), length);
-			for (unsigned int i = 0; i < length; ++i) {
+			qDebug ("%s: IntVector, length %d", prefix.toLatin1().data(), getDataLength ());
+			for (unsigned int i = 0; i < getDataLength (); ++i) {
 				qDebug ("%s%d: %d", prefix.toLatin1().data(), i, getIntVector ()[i]);
 			}
 			break;
 		case RealVector:
-			qDebug ("%s: RealVector, length %d", prefix.toLatin1().data(), length);
-			for (unsigned int i = 0; i < length; ++i) {
+			qDebug ("%s: RealVector, length %d", prefix.toLatin1().data(), getDataLength ());
+			for (unsigned int i = 0; i < getDataLength (); ++i) {
 				qDebug ("%s%d: %f", prefix.toLatin1().data(), i, getRealVector ()[i]);
 			}
 			break;
 		case StringVector:
-			qDebug ("%s: StringVector, length %d", prefix.toLatin1().data(), length);
-			for (unsigned int i = 0; i < length; ++i) {
+			qDebug ("%s: StringVector, length %d", prefix.toLatin1().data(), getDataLength ());
+			for (unsigned int i = 0; i < getDataLength (); ++i) {
 				qDebug ("%s%d: %s", prefix.toLatin1().data(), i, getStringVector ()[i].toLatin1().data());
 			}
 			break;
 		case StructureVector:
-			qDebug ("%s: StructureVector, length %d", prefix.toLatin1().data(), length);
-			for (unsigned int i = 0; i < length; ++i) {
+			qDebug ("%s: StructureVector, length %d", prefix.toLatin1().data(), getDataLength ());
+			for (unsigned int i = 0; i < getDataLength (); ++i) {
 				QString sub_prefix = prefix + QString::number (i);
 				getStructureVector ()[i]->printStructure (sub_prefix);
 			}
 			break;
 		default:
-			qDebug ("%s: INVALID %d, length %d", prefix.toLatin1().data(), datatype, length);
+			qDebug ("%s: INVALID %d, length %d", prefix.toLatin1().data(), datatype, getDataLength ());
 	}
 	qDebug ("%s: END\n\n", prefix.toLatin1 ().data());
 }

Modified: trunk/rkward/rkward/rbackend/rdata.h
===================================================================
--- trunk/rkward/rkward/rbackend/rdata.h	2010-11-19 12:42:13 UTC (rev 3196)
+++ trunk/rkward/rkward/rbackend/rdata.h	2010-11-19 13:06:38 UTC (rev 3197)
@@ -2,7 +2,7 @@
                           rdata  -  description
                              -------------------
     begin                : Sun Oct 01 2006
-    copyright            : (C) 2006 by Thomas Friedrichsmeier
+    copyright            : (C) 2006, 2010 by Thomas Friedrichsmeier
     email                : tfry at users.sourceforge.net
  ***************************************************************************/
 
@@ -18,7 +18,9 @@
 #ifndef RDATA_H
 #define RDATA_H
 
-class QString;
+#include <QVector>
+#include <QStringList>
+
 /** Class to represent data (other than output/erros) passed from the R backend to the main thread. Data is usually a vector of type int, double or QString, but can also contain a hierarchy of RData*s. RCommand is a subclass of this */
 class RData {
 public:
@@ -32,32 +34,35 @@
 		NoData=4
 	};
 
+	typedef QVector<qint32> IntStorage;
+	typedef QVector<double> RealStorage;
+	typedef QVector<RData*> RDataStorage;
+	typedef QStringList StringStorage;
 /** returns the type of data contained */
-	RDataType getDataType () { return datatype; };
+	RDataType getDataType () const { return datatype; };
 /** returns the length (size) of the data array. @see RCommand::GetStringVector @see RCommand::GetRealVector @see RCommand::GetIntVector @see RCommand:GetStructure */
-	unsigned int getDataLength () { return length; };
-/** returns an array of double, if that is the type of data contained (else 0). The array is owned by the RCommand! @see RCommand::GetRealVector @see RData::detachData () @see RData::getDataLength () @see RData::getDataType () */
-	double *getRealVector ();
-/** returns an array of int, if that is the type of data contained (else 0). The array is owned by the RCommand! @see RCommand::GetIntVector @see RData::detachData () @see RData::getDataLength () @see RData::getDataType () */
-	int *getIntVector ();
-/** returns an array of QString, if that is the type of data contained (else 0). The array is owned by the RCommand! @see RCommand::GetStringVector @see RData::detachData () @see RData::getDataLength () @see RData::getDataType () */
-	QString *getStringVector ();
-/** returns an array of RData*, if that is the type of data contained (else 0). The array is owned by the RCommand! @see RCommand::GetStructureVector @see RData::detachData () @see RData::getDataLength () @see RData::getDataType () */
-	RData **getStructureVector ();
-/** The data contained in the RData structure is owned by RData, and will usually be deleted at the end of the lifetime of the RData object. If you want to keep the data, call detachData () to prevent this deletion. You will be responsible for deletion of the data yourself. */
-	void detachData ();
+	unsigned int getDataLength () const;
+/** returns an array of double, if that is the type of data contained (else 0). @see RCommand::GetRealVector @see RData::getDataLength () @see RData::getDataType () */
+	RealStorage &getRealVector () const;
+/** returns an array of int, if that is the type of data contained (else 0). @see RCommand::GetIntVector @see RData::getDataLength () @see RData::getDataType () */
+	IntStorage &getIntVector () const;
+/** returns an array of QString, if that is the type of data contained (else 0). @see RCommand::GetStringVector @see RData::getDataLength () @see RData::getDataType () */
+	StringStorage &getStringVector () const;
+/** returns an array of RData*, if that is the type of data contained (else 0). @see RCommand::GetStructureVector @see RData::getDataLength () @see RData::getDataType () */
+	RDataStorage &getStructureVector () const;
 	void discardData ();
 /** purely for debugging! */
 	void printStructure (const QString &prefix);
 
-/** public for technical reasons only. Do not use! Copy data from the given RData, and discard it */
-	void setData (RData *from);
-/** public for technical reasons only. Do not use! */
+	void setData (const RDataStorage &from);
+	void setData (const IntStorage &from);
+	void setData (const RealStorage &from);
+	void setData (const StringStorage &from);
+/** public for technical reasons only. Do not use! Move data from the given RData to this RData. The source RData is emptied! */
+	void swallowData (RData &from);
+private:
 	RDataType datatype;
-/** public for technical reasons only. Do not use! */
 	void *data;
-/** public for technical reasons only. Do not use! */
-	unsigned int length;
 };
 
 #endif

Deleted: trunk/rkward/rkward/rbackend/rembedinternal.cpp
===================================================================
--- trunk/rkward/rkward/rbackend/rembedinternal.cpp	2010-11-19 12:42:13 UTC (rev 3196)
+++ trunk/rkward/rkward/rbackend/rembedinternal.cpp	2010-11-19 13:06:38 UTC (rev 3197)
@@ -1,1194 +0,0 @@
-/***************************************************************************
-                          rembedinternal  -  description
-                             -------------------
-    begin                : Sun Jul 25 2004
-    copyright            : (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010 by Thomas Friedrichsmeier
-    email                : tfry at users.sourceforge.net
- ***************************************************************************/
-
-/***************************************************************************
- *                                                                         *
- *   This program 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.                                   *
- *                                                                         *
- ***************************************************************************/
-
-#include "rembedinternal.h"
-
-// static
-REmbedInternal *REmbedInternal::this_pointer = 0; 
-
-#include <qstring.h>
-#include <QStringList>
-#include <qtextcodec.h>
-#include <klocale.h>
-
-#include "../core/robject.h"
-#include "../debug.h"
-
-#include "rklocalesupport.h"
-#include "rkpthreadsupport.h"
-#include "rksignalsupport.h"
-#include "../misc/rkcommonfunctions.h"
-
-#include <stdlib.h>
-#include <string.h>
-#include <stdint.h>
-#ifdef Q_WS_WIN
-#	include <winsock.h>
-#	undef ERROR	// windows define clashes with R define
-#else
-#include <dlfcn.h>
-#include <sys/resource.h>
-#include <sys/types.h>
-#endif
-#include <math.h>
-
-#include <Rversion.h>
-
-#if (R_VERSION > R_Version(2, 6, 9))
-#define R_2_7
-#endif
-
-#ifndef R_2_7
-#error R version 2.7.0 or later is needed to compile this version of RKWard
-#endif
-
-#if (R_VERSION > R_Version(2, 8, 9))
-#define R_2_9
-#endif
-
-extern "C" {
-#define R_INTERFACE_PTRS 1
-
-// needed to detect CHARSXP encoding
-#define IS_UTF8(x) (Rf_getCharCE(x) == CE_UTF8)
-#define IS_LATIN1(x) (Rf_getCharCE(x) == CE_LATIN1)
-
-#ifdef Q_WS_WIN
-	// needed for R includes
-#	define Win32
-#endif
-
-#include <Rdefines.h>
-#include <R_ext/Rdynload.h>
-#include <R_ext/eventloop.h>
-#include <R_ext/Callbacks.h>
-#include <R.h>
-#include <Rinternals.h>
-#include <R_ext/Parse.h>
-#include <Rembedded.h>
-
-#ifdef Q_WS_WIN
-#	include <R_ext/RStartup.h>
-#	include <R_ext/Utils.h>
-
-	void RK_scheduleIntr () {
-		UserBreak = 1;
-	}
-
-	void RK_doIntr () {
-		RK_scheduleIntr ();
-		R_CheckUserInterrupt ();
-	}
-
-	structRstart RK_R_Params;
-#else
-#	define RK_doIntr Rf_onintr
-#	include <Rinterface.h>
-#endif
-
-// some functions we need that are not declared
-extern void Rf_PrintWarnings (void);
-extern int Rf_initialize_R(int ac, char **av);	// in embedded.h in R 2.9.0. TODO: check presence in R 2.7.0
-extern void setup_Rmainloop(void);	// in embedded.h in R 2.9.0. TODO: check presence in R 2.7.0
-#ifndef Q_WS_WIN
-extern uintptr_t R_CStackLimit;	// inRinterface.h in R 2.9.0. TODO: check presence in R 2.7.0
-extern uintptr_t R_CStackStart;	// inRinterface.h in R 2.9.0. TODO: check presence in R 2.7.0
-extern Rboolean R_Interactive;	// inRinterface.h in R 2.9.0. TODO: check presence in R 2.7.0
-#endif
-SEXP R_LastvalueSymbol;
-#include <R_ext/eventloop.h>
-}
-
-#include "../rkglobals.h"
-#include "rdata.h"
-
-// Needed for the REPL
-const char *current_buffer = 0;
-bool repldlldo1_wants_code = false;
-bool repldll_buffer_transfer_finished = false;
-int repldll_result = 0;		/* -2: error; -1: incomplete; 0: nothing, yet 1: ok 2: incomplete statement, while buffer not empty. Should not happen */
-bool repldll_last_parse_successful = false;
-
-
-SEXP RKWard_RData_Tag;
-QString *SEXPToStringList (SEXP from_exp, unsigned int *count);
-QString SEXPToString (SEXP from_exp);
-int *SEXPToIntArray (SEXP from_exp, unsigned int *count);
-int SEXPToInt (SEXP from_exp, int def_value = INT_MIN);
-SEXP parseCommand (const QString &command_qstring, REmbedInternal::RKWardRError *error);
-SEXP runCommandInternalBase (SEXP pr, REmbedInternal::RKWardRError *error);
-
-// ############## R Standard callback overrides BEGIN ####################
-void RSuicide (const char* message) {
-	RK_TRACE (RBACKEND);
-
-	RCallbackArgs args;
-	args.type = RCallbackArgs::RBackendExit;
-	args.params["message"] = QVariant (i18n ("The R engine has encountered a fatal error:\n%1").arg (message));
-	REmbedInternal::this_pointer->handleStandardCallback (&args);
-	REmbedInternal::this_pointer->shutdown (true);
-	Rf_error ("Backend dead");	// this jumps us out of the REPL.
-}
-
-int RReadConsole (const char* prompt, unsigned char* buf, int buflen, int hist) {
-	RK_TRACE (RBACKEND);
-
-	// handle requests for new code
-	if (repldlldo1_wants_code) {
-		//Rprintf ("wants code, buffsize: %d\n", buflen);
-		if (repldll_buffer_transfer_finished) {
-			return 0;
-		}
-
-		int pos = 0;		// fgets emulation
-		while (pos < (buflen-1)) {
-			buf[pos] = *current_buffer;
-			if (*current_buffer == '\0') {
-				repldll_buffer_transfer_finished = true;
-				break;
-			}
-			++current_buffer;
-			++pos;
-		}
-		if (repldll_buffer_transfer_finished) buf[pos] = '\n';
-		buf[++pos] = '\0';
-		//Rprintf ("buffer now: '%s'\n", buf);
-		return 1;
-	}
-
-	// here, we handle readline() calls and such, i.e. not the regular prompt for code
-	// browser() also takes us here.
-	RCallbackArgs args;
-	args.type = RCallbackArgs::RReadLine;
-	args.params["prompt"] = QVariant (prompt);
-	args.params["cancelled"] = QVariant (false);
-
-	REmbedInternal::this_pointer->handleStandardCallback (&args);
-// default implementation seems to return 1 on success, 0 on failure, contrary to some documentation. see unix/std-sys.c
-	if (args.params["cancelled"].toBool ()) {
-#warning TODO: this should be handled in rthread.cpp, instead
-		REmbedInternal::this_pointer->currentCommandWasCancelled ();
-		RK_doIntr();
-		return 0;	// we should not ever get here, but still...
-	}
-	if (buf) {
-		QByteArray localres = REmbedInternal::this_pointer->current_locale_codec->fromUnicode (args.params["result"].toString ());
-		// need to append a newline, here. TODO: theoretically, RReadConsole comes back for more, if \0 was encountered before \n.
-		qstrncpy ((char *) buf, localres.left (buflen - 2).append ('\n').data (), buflen);
-		return 1;
-	}
-	return 0;
-}
-
-#ifdef Q_WS_WIN
-int RReadConsoleWin (const char* prompt, char* buf, int buflen, int hist) {
-	return RReadConsole (prompt, (unsigned char*) buf, buflen, hist);
-}
-#endif
-
-void RWriteConsoleEx (const char *buf, int buflen, int type) {
-	RK_TRACE (RBACKEND);
-
-	REmbedInternal::this_pointer->handleOutput (REmbedInternal::this_pointer->current_locale_codec->toUnicode (buf, buflen), buflen, type == 0);
-}
-
-/** For R callbacks that we want to disable, entirely */
-void RDoNothing () {
-	RK_TRACE (RBACKEND);
-}
-
-void RCleanUp (SA_TYPE saveact, int status, int RunLast) {
-	RK_TRACE (RBACKEND);
-
-	if (saveact != SA_SUICIDE) {
-		RCallbackArgs args;
-		args.type = RCallbackArgs::RBackendExit;
-		args.params["message"] = QVariant (i18n ("The R engine has shut down with status: %1").arg (status));
-		REmbedInternal::this_pointer->handleStandardCallback (&args);
-
-		if(saveact == SA_DEFAULT) saveact = SA_SAVE;
-		if (saveact == SA_SAVE) {
-				if (RunLast) R_dot_Last ();
-				if (R_DirtyImage) R_SaveGlobalEnv ();
-		} else {
-				if (RunLast) R_dot_Last ();
-		}
-
-		REmbedInternal::this_pointer->shutdown (false);
-	} else {
-		REmbedInternal::this_pointer->shutdown (true);
-	}
-	Rf_error ("Backend dead");	// this jumps us out of the REPL.
-}
-
-void REmbedInternal::tryToDoEmergencySave () {
-	RK_TRACE (RBACKEND);
-
-	// we're probably in a signal handler, and the stack base has changed.
-	uintptr_t old_lim = R_CStackLimit;
-	R_CStackLimit = (uintptr_t)-1;
-	if (R_DirtyImage) R_SaveGlobalEnvToFile (RKCommonFunctions::getUseableRKWardSavefileName ("rkward_recover", ".RData").toLocal8Bit ());
-	R_CStackLimit = old_lim;
-}
-
-QStringList charPArrayToQStringList (const char** chars, int count) {
-	QStringList ret;
-	for (int i = 0; i < count; ++i) {
-		// do we need to do locale conversion, here?
-		ret.append (chars[i]);
-	}
-	return ret;
-}
-
-int RChooseFile (int isnew, char *buf, int len) {
-	RK_TRACE (RBACKEND);
-
-	RCallbackArgs args;
-	args.type = RCallbackArgs::RChooseFile;
-	args.params["new"] = QVariant ((bool) isnew);
-
-	REmbedInternal::this_pointer->handleStandardCallback (&args);
-
-	QByteArray localres = REmbedInternal::this_pointer->current_locale_codec->fromUnicode (args.params["result"].toString ());
-	qstrncpy ((char *) buf, localres.data (), len);
-
-// return length of filename (strlen (buf))
-	return (qMin (len - 1, localres.size ()));
-}
-
-/* There are about one million possible entry points to editing / showing files. We try to cover them all, using the
-following bunch of functions (REditFilesHelper() and doShowEditFiles() are helpers, only) */
-
-void REditFilesHelper (QStringList files, QStringList titles, QString wtitle, RCallbackArgs::RCallbackType edit, bool delete_files) {
-	RK_TRACE (RBACKEND);
-
-	RCallbackArgs args;
-	if (edit == RCallbackArgs::REditFiles) args.type = RCallbackArgs::REditFiles;
-	else {
-		RK_ASSERT (edit == RCallbackArgs::RShowFiles);
-		args.type = RCallbackArgs::RShowFiles;
-		args.params["delete"] = QVariant (delete_files);
-	}
-	// see ?file.show() for what appears to be the intended meaning of these first three parameters
-	// (which seem to be inconsistently named even in R itself...)
-	args.params["files"] = QVariant (files);
-	args.params["titles"] = QVariant (titles);
-	args.params["wtitle"] = QVariant (wtitle);
-
-	REmbedInternal::this_pointer->handleStandardCallback (&args);
-}
-
-int REditFiles (int nfile, const char **file, const char **title, const char *wtitle) {
-	RK_TRACE (RBACKEND);
-
-	REditFilesHelper (charPArrayToQStringList (file, nfile), charPArrayToQStringList (title, nfile), wtitle, RCallbackArgs::REditFiles, false);
-
-// default implementation seems to return 1 if nfile <= 0, else 1. No idea, what for. see unix/std-sys.c
-	return (nfile <= 0);
-}
-
-SEXP doShowEditFiles (SEXP files, SEXP titles, SEXP wtitle, SEXP del, RCallbackArgs::RCallbackType edit) {
-	RK_TRACE (RBACKEND);
-
-	// this function would be much shorter, if SEXPToStringList would simply return a QStringList...
-	unsigned int files_count, titles_count;
-	QString *file_strings = SEXPToStringList (files, &files_count);
-	QString *title_strings = SEXPToStringList (titles, &titles_count);
-	QString wtitle_string = SEXPToString (wtitle);
-	bool del_files = SEXPToInt (del, 0) != 0;
-
-	RK_ASSERT (files_count == titles_count);
-	RK_ASSERT (files_count >= 1);
-
-	files_count = titles_count = qMin (files_count, titles_count);
-
-	QStringList files_list;
-	QStringList titles_list;
-	for (unsigned int i = 0; i < files_count; ++i) {
-		files_list.append (file_strings[i]);
-		titles_list.append (title_strings[i]);
-	}
-
-	REditFilesHelper (files_list, titles_list, wtitle_string, edit, del_files);
-
-	delete [] file_strings;
-	delete [] title_strings;
-
-	return (R_NilValue);
-}
-
-SEXP doEditFiles (SEXP files, SEXP titles, SEXP wtitle) {
-	return (doShowEditFiles (files, titles, wtitle, R_NilValue, RCallbackArgs::REditFiles));
-}
-
-int REditFile (const char *buf) {
-	RK_TRACE (RBACKEND);
-
-	const char *editor = "none";
-	const char *title = "";
-
-// does not exist in standard R 2.1.0, so no idea what to return.
-	return REditFiles (1, const_cast<const char**> (&buf), &title, editor);
-}
-
-SEXP doShowFiles (SEXP files, SEXP titles, SEXP wtitle, SEXP delete_files) {
-	return (doShowEditFiles (files, titles, wtitle, delete_files, RCallbackArgs::RShowFiles));
-}
-
-int RShowFiles (int nfile, const char **file, const char **headers, const char *wtitle, Rboolean del, const char */* pager */) {
-	RK_TRACE (RBACKEND);
-
-	REditFilesHelper (charPArrayToQStringList (file, nfile), charPArrayToQStringList (headers, nfile), QString (wtitle), RCallbackArgs::RShowFiles, (bool) del);
-
-// default implementation seems to returns 1 on success, 0 on failure. see unix/std-sys.c
-	return 1;
-}
-
-/* FROM R_ext/RStartup.h: "Return value here is expected to be 1 for Yes, -1 for No and 0 for Cancel:
-   symbolic constants in graphapp.h" */
-int doDialogHelper (QString caption, QString message, QString button_yes, QString button_no, QString button_cancel, bool wait) {
-	RK_TRACE (RBACKEND);
-
-	RCallbackArgs args;
-	args.type = RCallbackArgs::RShowMessage;
-	args.params["caption"] = QVariant (caption);
-	args.params["message"] = QVariant (message);
-	args.params["button_yes"] = QVariant (button_yes);
-	args.params["button_no"] = QVariant (button_no);
-	args.params["button_cancel"] = QVariant (button_cancel);
-	if (wait) args.params["wait"] = "1";
-
-	REmbedInternal::this_pointer->handleStandardCallback (&args);
-
-	QString ret = args.params["result"].toString ();
-	if (ret == "yes") return 1;
-	if (ret == "no") return -1;
-	return 0;
-}
-
-SEXP doDialog (SEXP caption, SEXP message, SEXP button_yes, SEXP button_no, SEXP button_cancel, SEXP wait) {
-	RK_TRACE (RBACKEND);
-
-	int result = doDialogHelper (SEXPToString (caption), SEXPToString (message), SEXPToString (button_yes), SEXPToString (button_no), SEXPToString (button_cancel), SEXPToInt (wait));
-
-	SEXP ret = Rf_allocVector(INTSXP, 1);
-	INTEGER (ret)[0] = result;
-	return ret;
-}
-
-void RShowMessage (const char* message) {
-	RK_TRACE (RBACKEND);
-
-	doDialogHelper (i18n ("Message from the R backend"), message, "ok", QString (), QString (), true);
-}
-
-// TODO: currently used on windows, only!
-int RAskYesNoCancel (const char* message) {
-	RK_TRACE (RBACKEND);
-
-	return doDialogHelper (i18n ("Question from the R backend"), message, "yes", "no", "cancel", true);
-}
-
-void RBusy (int busy) {
-	RK_TRACE (RBACKEND);
-
-	// R_ReplDLLDo1 calls R_Busy (1) after reading in code (if needed), parsing it, and right before evaluating it.
-	if (busy) {
-		repldlldo1_wants_code = false;
-		repldll_last_parse_successful = true;
-	}
-}
-
-// ############## R Standard callback overrides END ####################
-
-char *REmbedInternal::na_char_internal = new char;
-
-REmbedInternal::REmbedInternal () {
-	RK_TRACE (RBACKEND);
-
-	current_locale_codec = QTextCodec::codecForLocale ();
-	r_running = false;
-}
-
-#ifdef Q_WS_WIN
-void REmbedInternal::setupCallbacks () {
-	RK_TRACE (RBACKEND);
-
-	R_setStartTime();
-	R_DefParams(&RK_R_Params);
-
-// IMPORTANT: see also the #ifndef QS_WS_WIN-portion!
-	RK_R_Params.rhome = get_R_HOME ();
-	RK_R_Params.home = getRUser ();
-	RK_R_Params.CharacterMode = LinkDLL;
-	RK_R_Params.ShowMessage = RShowMessage;
-	RK_R_Params.ReadConsole = RReadConsoleWin;
-	RK_R_Params.WriteConsoleEx = RWriteConsoleEx;
-	RK_R_Params.WriteConsole = 0;
-	RK_R_Params.CallBack = RDoNothing;
-	RK_R_Params.YesNoCancel = RAskYesNoCancel;
-	RK_R_Params.Busy = RBusy;
-
-	// TODO: callback mechanism(s) for ChosseFile, ShowFiles, EditFiles
-	// TODO: also for RSuicide / RCleanup? (Less important, obviously, since those should not be triggered, in normal operation).
-
-	RK_R_Params.R_Quiet = (Rboolean) 0;
-	RK_R_Params.R_Interactive = (Rboolean) 1;
-}
-
-void REmbedInternal::connectCallbacks () {
-	RK_TRACE (RBACKEND);
-	R_SetParams(&RK_R_Params);
-}
-#else
-void REmbedInternal::setupCallbacks () {
-	RK_TRACE (RBACKEND);
-}
-
-void REmbedInternal::connectCallbacks () {
-	RK_TRACE (RBACKEND);
-
-// IMPORTANT: see also the #ifdef QS_WS_WIN-portion!
-// 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;		// rarely used in R on unix
-	ptr_R_ReadConsole = RReadConsole;
-	ptr_R_WriteConsoleEx = RWriteConsoleEx;
-	ptr_R_WriteConsole = 0;
-	ptr_R_ResetConsole = RDoNothing;
-	ptr_R_FlushConsole = RDoNothing;
-	ptr_R_ClearerrConsole = RDoNothing;
-	ptr_R_Busy = RBusy;
-	ptr_R_CleanUp = RCleanUp;			// unfortunately, it seems, we can't safely cancel quitting anymore, here!
-	ptr_R_ShowFiles = RShowFiles;
-	ptr_R_ChooseFile = RChooseFile;
-// TODO: R devels disabled this for some reason. We set it anyway...
-	ptr_R_EditFile = REditFile;
-//	ptr_R_EditFiles = REditFiles;		// undefined reference
-
-// these two, we won't override
-//	ptr_R_loadhistory = ... 	// we keep our own history
-//	ptr_R_savehistory = ...	// we keep our own history
-}
-#endif
-
-REmbedInternal::~REmbedInternal () {
-	RK_TRACE (RBACKEND);
-}
-
-void REmbedInternal::shutdown (bool suicidal) {
-	RK_TRACE (RBACKEND);
-
-	if (!r_running) return;		// already shut down
-	r_running = false;
-
-	Rf_endEmbeddedR (suicidal);
-}
-
-#if 0
-static int timeout_counter = 0;
-#endif
-
-void processX11EventsWorker (void *) {
-// this basically copied from R's unix/sys-std.c (Rstd_ReadConsole)
-#ifndef Q_WS_WIN
-	for (;;) {
-		fd_set *what;
-		what = R_checkActivityEx(R_wait_usec > 0 ? R_wait_usec : 50, 1, RK_doIntr);
-		R_runHandlers(R_InputHandlers, what);
-		if (what == NULL) break;
-	}
-	/* This seems to be needed to make Rcmdr react to events. Has this always been the case? It was commented out for a long time, without anybody noticing. */
-	R_PolledEvents ();
-#else
-#warning TODO: correct?
-	R_ProcessEvents();
-#endif
-
-#if 0
-// TODO: The remainder of this function had been commented out since R 2.3.x and is not in Rstd_ReadConsole. Do we still need this?
-	/* I don't really understand what I'm doing here, but apparently this is necessary for Tcl-Tk windows to function properly. */
-	R_PolledEvents ();
-	
-/* Maybe we also need to also call R_timeout_handler once in a while? Obviously this is extremely crude code! 
-TODO: verify we really need this. */
-	if (++timeout_counter > 100) {
-//		extern void (* R_timeout_handler) ();	// already defined in Rinferface.h
-		if (R_timeout_handler) R_timeout_handler ();
-		timeout_counter = 0;
-	}
-#endif
-}
-
-void REmbedInternal::processX11Events () {
-	// do not trace
-	if (!this_pointer->r_running) return;
-
-// In case an error (or user interrupt) is caught inside processX11EventsWorker, we don't want to long-jump out.
-	R_ToplevelExec (processX11EventsWorker, 0);
-}
-
-/** converts SEXP to strings, and returns the first string (or QString(), if SEXP contains no strings) */
-QString SEXPToString (SEXP from_exp) {
-	RK_TRACE (RBACKEND);
-
-	QString ret;
-
-	unsigned int count;
-	QString *list = SEXPToStringList (from_exp, &count);
-
-	if (count >= 1) ret = list[0];
-	delete [] list;
-	return ret;
-}
-
-QString *SEXPToStringList (SEXP from_exp, unsigned int *count) {
-	RK_TRACE (RBACKEND);
-
-	// bad format? coerce the vector first
-	if (TYPEOF (from_exp) != STRSXP) {
-		SEXP strexp;
-		PROTECT (strexp = coerceVector (from_exp, STRSXP));
-		QString *list = SEXPToStringList (strexp, count);
-		UNPROTECT (1);
-		return list;
-	}
-
-	// format already good? Avoid coercion (and associated copying)
-	*count = length (from_exp);
-	QString *list = new QString[*count];
-	unsigned int i = 0;
-	for (; i < *count; ++i) {
-#ifdef R_2_9
-		SEXP dummy = STRING_ELT (from_exp, i);
-#else
-		SEXP dummy = VECTOR_ELT (from_exp, i);
-#endif
-
-		if (TYPEOF (dummy) != CHARSXP) {
-			list[i] = QString ("not defined");	// can this ever happen?
-		} else {
-			if (dummy == NA_STRING) {
-				list[i] = QString::null;
-			} else {
-				if (IS_UTF8 (dummy)) {
-					list[i] = QString::fromUtf8 ((char *) STRING_PTR (dummy));
-				} else if (IS_LATIN1 (dummy)) {
-					list[i] = QString::fromLatin1 ((char *) STRING_PTR (dummy));
-				} else {
-					list[i] = REmbedInternal::this_pointer->current_locale_codec->toUnicode ((char *) STRING_PTR (dummy));
-				}
-			}
-		}
-	}
-
-	return list;
-}
-
-int *SEXPToIntArray (SEXP from_exp, unsigned int *count) {
-	RK_TRACE (RBACKEND);
-
-	int *integers;
-
-	// bad format? coerce the vector first
-	if (TYPEOF (from_exp) != INTSXP) {
-		SEXP intexp;
-		PROTECT (intexp = coerceVector (from_exp, INTSXP));
-		integers = SEXPToIntArray (intexp, count);
-		UNPROTECT (1);
-		return integers;
-	}
-
-	// format already good? Avoid coercion (and associated copying)
-	*count = length (from_exp);
-	integers = new int[*count];
-	for (unsigned int i = 0; i < *count; ++i) {
-		integers[i] = INTEGER (from_exp)[i];
-		if (integers[i] == R_NaInt) integers[i] = INT_MIN;		// this has no effect for now, but if R ever chnages it's R_NaInt, then it will
-	}
-	return integers;
-}
-
-/** converts SEXP to integers, and returns the first int (def_value, if SEXP contains no ints) */
-int SEXPToInt (SEXP from_exp, int def_value) {
-	RK_TRACE (RBACKEND);
-
-	int ret = def_value;
-	unsigned int count;
-	int *integers = SEXPToIntArray (from_exp, &count);
-	if (count >= 1) ret = integers[0];
-	delete [] integers;
-
-	return ret;
-}
-
-double *SEXPToRealArray (SEXP from_exp, unsigned int *count) {
-	RK_TRACE (RBACKEND);
-
-	double *reals;
-
-	// bad format? coerce the vector first
-	if (TYPEOF (from_exp) != REALSXP) {
-		SEXP realexp;
-		PROTECT (realexp = coerceVector (from_exp, REALSXP));
-		reals = SEXPToRealArray (realexp, count);
-		UNPROTECT (1);
-		return reals;
-	}
-	
-	// format already good? Avoid coercion (and associated copying)
-	*count = length (from_exp);
-	reals = new double[*count];
-	for (unsigned int i = 0; i < *count; ++i) {
-		reals[i] = REAL (from_exp)[i];
-		if (R_IsNaN (reals[i]) || R_IsNA (reals[i]) ) reals[i] = RKGlobals::na_double;
-	}
-	return reals;
-}
-
-RData *SEXPToRData (SEXP from_exp) {
-	RK_TRACE (RBACKEND);
-
-	RData *data = new RData;
-
-	unsigned int count;
-	int type = TYPEOF (from_exp);
-	switch (type) {
-		case LGLSXP:
-		case INTSXP:
-			data->data = SEXPToIntArray (from_exp, &count);
-			data->datatype = RData::IntVector;
-			break;
-		case REALSXP:
-			data->data = SEXPToRealArray (from_exp, &count);
-			data->datatype = RData::RealVector;
-			break;
-		case VECSXP:
-			count = 0;
-			count = length (from_exp);
-			{
-				RData **structure_array = new RData*[count];
-				for (unsigned int i=0; i < count; ++i) {
-					SEXP subexp = VECTOR_ELT (from_exp, i);
-					//PROTECT (subexp);	// should already be protected as part of the parent from_exp
-					structure_array[i] = SEXPToRData (subexp);
-					//UNPROTECT (1);
-				}
-				data->data = structure_array;
-			}
-			data->datatype = RData::StructureVector;
-			break;
-/*		case NILSXP:
-			data->data = 0;
-			data->datatype = RData::NoData;
-			count = 0;
-			break; */
-		case EXTPTRSXP:
-			if (R_ExternalPtrTag (from_exp) == RKWard_RData_Tag) {		// our very own data
-				delete data;
-				data = (RData*) R_ExternalPtrAddr (from_exp);
-				R_ClearExternalPtr (from_exp);
-				count = data->length;
-				break;
-			}
-		case STRSXP:
-		default:
-			data->data = SEXPToStringList (from_exp, &count);
-			data->datatype = RData::StringVector;
-	}
-
-	data->length = count;
-
-	return data;
-}
-
-SEXP doError (SEXP call) {
-	RK_TRACE (RBACKEND);
-
-	unsigned int count;
-	QString *strings = SEXPToStringList (call, &count);
-	REmbedInternal::this_pointer->handleError (strings, count);
-	delete [] strings;
-	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) {
-	RK_TRACE (RBACKEND);
-
-	unsigned int count;
-	QString *strings = SEXPToStringList (call, &count);
-	QStringList list;
-	for (unsigned int i = 0; i < count; ++i) {
-		list.append (strings[i]);
-	}
-	REmbedInternal::this_pointer->handleSubstackCall (list);
-	delete [] strings;
-	return R_NilValue;
-}
-
-void R_CheckStackWrapper (void *) {
-	R_CheckStack ();
-}
-
-SEXP doUpdateLocale () {
-	RK_TRACE (RBACKEND);
-
-	RK_DO (qDebug ("Changing locale"), RBACKEND, DL_WARNING);
-	REmbedInternal::this_pointer->current_locale_codec = RKGetCurrentLocaleCodec ();
-	RK_DO (qDebug ("New locale codec is %s", REmbedInternal::this_pointer->current_locale_codec->name ().data ()), RBACKEND, DL_WARNING);
-
-	return R_NilValue;
-}
-
-// returns the MIME-name of the current locale encoding (from Qt)
-SEXP doLocaleName () {
-	RK_TRACE (RBACKEND);
-
-	RK_ASSERT (REmbedInternal::this_pointer->current_locale_codec);
-	SEXP res = allocVector(STRSXP, 1);
-	PROTECT (res);
-#ifdef R_2_9
-	SET_STRING_ELT (res, 0, mkChar (REmbedInternal::this_pointer->current_locale_codec->name ().data ()));
-#else
-	SET_VECTOR_ELT (res, 0, mkChar (REmbedInternal::this_pointer->current_locale_codec->name ().data ()));
-#endif
-	UNPROTECT (1);
-	return res;
-}
-
-#include "rkstructuregetter.cpp"
-
-SEXP doGetStructure (SEXP toplevel, SEXP name, SEXP envlevel, SEXP namespacename) {
-	RK_TRACE (RBACKEND);
-
-	RKStructureGetter getter (false);
-	RData *ret = getter.getStructure (toplevel, name, envlevel, namespacename);
-	return R_MakeExternalPtr (ret, RKWard_RData_Tag, R_NilValue);
-}
-
-SEXP doGetGlobalEnvStructure (SEXP name, SEXP envlevel, SEXP namespacename) {
-	RK_TRACE (RBACKEND);
-
-	return doGetStructure (findVar (Rf_install (CHAR (STRING_ELT (name, 0))), R_GlobalEnv), name, envlevel, namespacename);
-}
-
-/** copy a symbol without touching it (esp. not forcing any promises) */
-SEXP doCopyNoEval (SEXP name, SEXP fromenv, SEXP toenv) {
-	RK_TRACE (RBACKEND);
-
-	if(!isString (name) || length (name) != 1) error ("name is not a single string");
-	if(!isEnvironment (fromenv)) error ("fromenv is not an environment");
-	if(!isEnvironment (toenv)) error ("toenv is not an environment");
-	defineVar (Rf_install (CHAR (STRING_ELT (name, 0))), findVar (Rf_install (CHAR (STRING_ELT (name, 0))), fromenv), toenv);
-	return (R_NilValue);
-}
-
-bool REmbedInternal::startR (int argc, char** argv, bool stack_check) {
-	RK_TRACE (RBACKEND);
-
-	setupCallbacks ();
-
-	RKSignalSupport::saveDefaultSignalHandlers ();
-
-	r_running = true;
-	Rf_initialize_R (argc, argv);
-
-#ifndef Q_WS_WIN
-	// in R on windows the stack limits detection seems to work out of the box for threads
-	if (stack_check) {
-		char dummy;
-		size_t stacksize;
-		void *stackstart;
-		RKGetCurrentThreadStackLimits (&stacksize, &stackstart, &dummy);
-		R_CStackStart = (uintptr_t) stackstart;
-		R_CStackLimit = stacksize;
-	} else {
-		R_CStackStart = (uintptr_t) -1;
-		R_CStackLimit = (uintptr_t) -1;
-	}
-#endif
-
-#ifdef Q_WS_WIN
-	R_set_command_line_arguments(argc, argv);
-	FlushConsoleInputBuffer(GetStdHandle(STD_INPUT_HANDLE));
-#endif
-
-	setup_Rmainloop ();
-
-#ifndef Q_WS_WIN
-	// in R on windows the stack limits detection seems to work out of the box for threads
-	if (stack_check) {
-		// safety check: If we are beyond the stack boundaries already, we better disable stack checking
-		// this has to come *after* the first setup_Rmainloop ()!
-		Rboolean stack_ok = R_ToplevelExec (R_CheckStackWrapper, (void *) 0);
-		if (!stack_ok) {
-			RK_DO (qDebug ("R_CheckStack() failed during initialization. Will disable stack checking and try to re-initialize."), RBACKEND, DL_WARNING);
-			RK_DO (qDebug ("If this does not work, try the --disable-stack-check command line option, *and* submit a bug report."), RBACKEND, DL_WARNING);
-			R_CStackStart = (uintptr_t) -1;
-			R_CStackLimit = (uintptr_t) -1;
-			setup_Rmainloop ();
-		}
-	}
-#endif
-
-#ifndef Q_WS_WIN
-	// on windows, set in connectCallbacks() for technical reasons
-	R_Interactive = (Rboolean) TRUE;
-#endif
-
-	RKGlobals::na_double = NA_REAL;
-	R_ReplDLLinit ();
-
-	RKWard_RData_Tag = Rf_install ("RKWard_RData_Tag");
-	R_LastvalueSymbol = Rf_install (".Last.value");
-
-	RKSignalSupport::installSignalProxies ();
-
-// register our functions
-	R_CallMethodDef callMethods [] = {
-//		{ "rk.do.condition", (DL_FUNC) &doCondition, 1 },
-		{ "rk.do.error", (DL_FUNC) &doError, 1 },
-		{ "rk.do.command", (DL_FUNC) &doSubstackCall, 1 },
-		{ "rk.get.structure", (DL_FUNC) &doGetStructure, 4 },
-		{ "rk.get.structure.global", (DL_FUNC) &doGetGlobalEnvStructure, 3 },
-		{ "rk.copy.no.eval", (DL_FUNC) &doCopyNoEval, 3 },
-		{ "rk.edit.files", (DL_FUNC) &doEditFiles, 3 },
-		{ "rk.show.files", (DL_FUNC) &doShowFiles, 4 },
-		{ "rk.dialog", (DL_FUNC) &doDialog, 6 },
-		{ "rk.update.locale", (DL_FUNC) &doUpdateLocale, 0 },
-		{ "rk.locale.name", (DL_FUNC) &doLocaleName, 0 },
-		{ 0, 0, 0 }
-	};
-	R_registerRoutines (R_getEmbeddingDllInfo(), NULL, callMethods, NULL, NULL);
-
-	connectCallbacks();
-
-	// get info on R runtime version
-	REmbedInternal::RKWardRError error;
-	unsigned int count;
-	int *dummy = getCommandAsIntVector ("as.numeric (R.version$major) * 1000 + as.numeric (R.version$minor) * 10", &count, &error);
-	RK_ASSERT ((error == REmbedInternal::NoError) && (count == 1));
-	if (count) r_version = dummy[0];
-	else r_version = 0;
-	delete [] dummy;
-
-	return true;
-}
-
-SEXP parseCommand (const QString &command_qstring, REmbedInternal::RKWardRError *error) {
-	RK_TRACE (RBACKEND);
-
-	ParseStatus status = PARSE_NULL;
-	SEXP cv, pr;
-
-	QByteArray localc = REmbedInternal::this_pointer->current_locale_codec->fromUnicode (command_qstring);		// needed so the string below does not go out of scope
-	const char *command = localc.data ();
-
-	PROTECT(cv=allocVector(STRSXP, 1));
-#ifdef R_2_9
-	SET_STRING_ELT(cv, 0, mkChar(command));
-#else
-	SET_VECTOR_ELT(cv, 0, mkChar(command));
-#endif
-
-	// TODO: Maybe we can use R_ParseGeneral instead. Then we could find the exact character, where parsing fails. Nope: not exported API
-	pr=R_ParseVector(cv, -1, &status, R_NilValue);
-	UNPROTECT(1);
-
-	if ((!pr) || (TYPEOF (pr) == NILSXP)) {
-		// got a null SEXP. This means parse was *not* ok, even if R_ParseVector told us otherwise
-		if (status == PARSE_OK) {
-			status = PARSE_ERROR;
-			printf ("weird parse error\n");
-		}
-	}
-
-	if (status != PARSE_OK) {
-		if ((status == PARSE_INCOMPLETE) || (status == PARSE_EOF)) {
-			*error = REmbedInternal::Incomplete;
-		} else if (status == PARSE_ERROR) {
-			//extern SEXP parseError (SEXP call, int linenum);
-			//parseError (R_NilValue, 0);
-			*error = REmbedInternal::SyntaxError;
-		} else { // PARSE_NULL
-			*error = REmbedInternal::OtherError;
-		}
-		pr = R_NilValue;
-	}
-
-	return pr;
-}
-
-SEXP runCommandInternalBase (SEXP pr, REmbedInternal::RKWardRError *error) {
-	RK_TRACE (RBACKEND);
-
-	SEXP exp;
-	int r_error = 0;
-
-	PROTECT (pr);
-	exp=R_NilValue;
-
-	if (TYPEOF(pr)==EXPRSXP && LENGTH(pr)>0) {
-		int bi=0;
-		while (bi<LENGTH(pr)) {
-			SEXP pxp=VECTOR_ELT(pr, bi);
-			exp=R_tryEval(pxp, R_GlobalEnv, &r_error);
-			bi++;
-			if (r_error) {
-				break;
-			}
-		}
-	} else {
-		exp=R_tryEval(pr, R_GlobalEnv, &r_error);
-	}
-
-	if (r_error) {
-		*error = REmbedInternal::OtherError;
-	} else {
-		*error = REmbedInternal::NoError;
-	}
-
-	UNPROTECT(1); /* pr */
-
-	// for safety, let's protect exp for the two print calls below.
-	// TODO: this is not good. It causes an additional PROTECT and UPROTECT. Need to (re-)move printing
-	PROTECT (exp);
-	/* Do NOT ask me why, but the line below is needed for warnings to be printed, while otherwise they would not be shown.
-	Apparently we need to print at least something in order to achieve this. Whatever really happens in Rprintf () to have such an effect, I did not bother to find out. */
-	Rprintf ((char *) "");
-
-	Rf_PrintWarnings ();
-
-	UNPROTECT (1);		// exp; We unprotect this, as most of the time the caller is not really interested in the result
-	return exp;
-}
-
-#if 0
-// This is currently unused, but might come in handy, again.
-/* Basically a safe version of Rf_PrintValue, as yes, Rf_PrintValue may lead to an error and long_jump->crash!
-For example in help (function, htmlhelp=TRUE), when no HTML-help is installed!
-SEXP exp should be PROTECTed prior to calling this function.
-//TODO: I don't think it's meant to be this way. Maybe nag the R-devels about it one day. 
-//TODO: this is not entirely correct. See PrintValueEnv (), which is what Repl_Console uses (but is hidden)
-*/
-void tryPrintValue (SEXP exp, REmbedInternal::RKWardRError *error) {
-	RK_TRACE (RBACKEND);
-
-	int ierror = 0;
-	SEXP tryprint, e;
-
-// Basically, we call 'print (expression)' (but inside a tryEval)
-	tryprint = Rf_findFun (Rf_install ("print"),  R_GlobalEnv);
-	PROTECT (tryprint);
-	e = allocVector (LANGSXP, 2);
-	PROTECT (e);
-	SETCAR (e, tryprint);
-	SETCAR (CDR (e), exp);
-	R_tryEval (e, R_GlobalEnv, &ierror);
-	UNPROTECT (2);	/* e, tryprint */
-
-	if (ierror) {
-		*error = REmbedInternal::OtherError;
-	} else {
-		*error = REmbedInternal::NoError;
-	}
-}
-#endif
-
-void runUserCommandInternal (void *) {
-	RK_TRACE (RBACKEND);
-
-/* R_ReplDLLdo1 return codes:
--1: EOF
-1: normal prompt
-2: continuation prompt (parse incomplete) */
-	do {
-		//Rprintf ("iteration status: %d\n", repldll_result);
-		repldll_result = -2;
-		repldlldo1_wants_code = true;
-		repldll_last_parse_successful = false;
-	} while (((repldll_result = R_ReplDLLdo1 ()) == 2) && (!repldll_buffer_transfer_finished));	// keep iterating while the statement is incomplete, and we still have more in the buffer to transfer
-	//Rprintf ("iteration complete, status: %d\n", repldll_result);
-	PROTECT (R_LastvalueSymbol);		// why do we need this? No idea, but R_ToplevelExec tries to unprotect something
-	if (REmbedInternal::this_pointer->RRuntimeIsVersion (2, 11, 9)) {
-		PROTECT (R_LastvalueSymbol);		// ... and with R 2.12.0 it tries to unprotect two things
-	}
-}
-
-void REmbedInternal::runCommandInternal (const QString &command_qstring, RKWardRError *error, bool print_result) {
-	RK_TRACE (RBACKEND);
-
-	// Apparently the line below is no good idea after all. At least on Windows, this causes issues (crashes) with RGtk2, and several methods-using libraries
-	//connectCallbacks ();		// sorry, but we will not play nicely with additional frontends trying to override our callbacks. (Unless they start their own R event loop, then they should be fine)
-
-	*error = NoError;
-	if (!print_result) {
-		SEXP parsed = parseCommand (command_qstring, error);
-		if (*error == NoError) runCommandInternalBase (parsed, error);
-	} else {		// run a user command
-/* Using R_ReplDLLdo1 () is a pain, but it seems to be the only entry point for evaluating a command as if it had been entered on a plain R console (with auto-printing if not invisible, etc.). Esp. since R_Visible is no longer exported in R 2.5.0, as it seems as of today (2007-01-17).
-
-Problems to deal with:
-- R_ReplDLLdo1 () may do a jump on an error. Hence we need R_ToplevelExec (public sind R 2.4.0)
-	- this is why runUserCommandInternal needs to be a separate function
-- R_ReplDLLdo1 () expects to receive the code input via R_ReadConsole. The same R_ReadConsole that commands like readline () or browser () will use to get their input.
-	- hence we need some state variables to figure out, when a call to R_ReadConsole originates directly from R_ReplDLLdo1 (), or some R statement. R_Busy () is our friend, here.
-- R_ReplDLLdo1 () will only ever evaluate one statement, even if several statements have already been transfered to the buffer. In fact, it will even return once after each ';' or '\n', even if the statement is not complete, but more is already in the buffer
-	- Hence we need two loops around R_ReplDLLdo1 (): one to make sure it continues reading until a statement is actually complete, another to continue if there is a second (complete or incomplete) statement in the command
-	- Also, in case the command was too long to fit inside the buffer at once (repldll_buffer_transfer_finished)
-- Some more state variables are used for figuring out, which type of error occurred, if any, since we don't get any decent return value
-
-This is the logic spread out over the following section, runUserCommandInternal (), and RReadConsole (). 
-
-NOTE from Deepayan Sarkar: Another possible simplification (which may not be worth doing
-ultimately): you distinguish between two types of calls to
-R_ReadConsole based on R_busy calls, but you may be able to use the
-second 'hist' argument. I didn't look too carefully, but it seems like
-hist == 1 iff R wants a parse-able input.
-*/
-
-		R_ReplDLLinit ();		// resets the parse buffer (things might be left over from a previous incomplete parse)
-		bool prev_iteration_was_incomplete = false;
-
-		QByteArray localc = current_locale_codec->fromUnicode (command_qstring);		// needed so the string below does not go out of scope
-		current_buffer = localc.data ();
-
-		repldll_buffer_transfer_finished = false;
-		Rboolean ok = (Rboolean) 1;	// set to false, if there is a jump during the R_ToplevelExec (i.e.. some sort of error)
-
-		repldll_result = 0;
-		while ((ok != FALSE) && ((!repldll_buffer_transfer_finished) || (repldll_result != -1))) {
-			// we always need to iterate until the parse returned an EOF AND we have no more code in the buffer to supply.
-			// However, if this happens right after we last received an INCOMPLETE, this means the parse really was incomplete.
-			// Otherwise, there's simply nothing more to parse.
-			prev_iteration_was_incomplete = (repldll_result == 2);
-			ok = R_ToplevelExec (runUserCommandInternal, 0);
-		}
-		if (ok == FALSE) {
-			if (repldll_last_parse_successful) {
-				*error = REmbedInternal::OtherError;
-			} else {
-				*error = REmbedInternal::SyntaxError;
-			}
-		} else {
-			if (prev_iteration_was_incomplete) {
-				*error = REmbedInternal::Incomplete;
-			} else {
-				*error = REmbedInternal::NoError;
-			}
-		}
-		repldlldo1_wants_code = false;		// make sure we don't get confused in RReadConsole
-	}
-}
-
-QString *REmbedInternal::getCommandAsStringVector (const QString &command, uint *count, RKWardRError *error) {	
-	RK_TRACE (RBACKEND);
-
-	SEXP exp;
-	QString *list = 0;
-
-	*error = NoError;
-	SEXP parsed = parseCommand (command, error);
-	if (*error == NoError) PROTECT (exp = runCommandInternalBase (parsed, error));
-	
-	if (*error == NoError) {
-		list = SEXPToStringList (exp, count);
-	}
-	
-	UNPROTECT (1); // exp
-	
-	if (*error != NoError) {
-		*count = 0;
-		return 0;
-	}
-	return list;
-}
-
-double *REmbedInternal::getCommandAsRealVector (const QString &command, uint *count, RKWardRError *error) {
-	RK_TRACE (RBACKEND);
-
-	SEXP exp;
-	double *reals = 0;
-	
-	*error = NoError;
-	SEXP parsed = parseCommand (command, error);
-	if (*error == NoError) PROTECT (exp = runCommandInternalBase (parsed, error));
-	
-	if (*error == NoError) {
-		reals = SEXPToRealArray (exp, count);
-	}
-	
-	UNPROTECT (1); // exp
-	
-	if (*error != NoError) {
-		*count = 0;
-		return 0;
-	}
-	return reals;
-}
-
-int *REmbedInternal::getCommandAsIntVector (const QString &command, uint *count, RKWardRError *error) {
-	RK_TRACE (RBACKEND);
-
-	SEXP exp;
-	int *integers = 0;
-	
-	*error = NoError;
-	SEXP parsed = parseCommand (command, error);
-	if (*error == NoError) PROTECT (exp = runCommandInternalBase (parsed, error));
-	
-	if (*error == NoError) {
-		integers = SEXPToIntArray (exp, count);
-	}
-	
-	UNPROTECT (1); // exp
-	
-	if (*error != NoError) {
-		*count = 0;
-		return 0;
-	}
-	return integers;
-}
-
-RData *REmbedInternal::getCommandAsRData (const QString &command, RKWardRError *error) {
-	RK_TRACE (RBACKEND);
-
-	SEXP exp;
-	RData *data = 0;
-	
-	*error = NoError;
-	SEXP parsed = parseCommand (command, error);
-	if (*error == NoError) PROTECT (exp = runCommandInternalBase (parsed, error));
-	
-	if (*error == NoError) {
-		data = SEXPToRData (exp);
-	}
-	
-	UNPROTECT (1); // exp
-	
-	return data;
-}

Deleted: trunk/rkward/rkward/rbackend/rembedinternal.h
===================================================================
--- trunk/rkward/rkward/rbackend/rembedinternal.h	2010-11-19 12:42:13 UTC (rev 3196)
+++ trunk/rkward/rkward/rbackend/rembedinternal.h	2010-11-19 13:06:38 UTC (rev 3197)
@@ -1,182 +0,0 @@
-/***************************************************************************
-                          rembedinternal  -  description
-                             -------------------
-    begin                : Sun Jul 25 2004
-    copyright            : (C) 2004, 2005, 2006, 2007, 2009 by Thomas Friedrichsmeier
-    email                : tfry at users.sourceforge.net
- ***************************************************************************/
-
-/***************************************************************************
- *                                                                         *
- *   This program 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.                                   *
- *                                                                         *
- ***************************************************************************/
-
-#ifndef R_EMBED_H
-#define R_EMBED_H
-
-#include <stddef.h>
-
-#include <QMap>
-#include <QVariant>
-
-#ifdef Q_WS_WIN
-extern "C" {
-	void RK_scheduleIntr();
-}
-#endif
-
-/** This struct is used to pass the standard callbacks from R to the main thread (if needed; some are handled in the backend thread). Note that for the callbacks that need to be passed to the main
-thread, we can be quite wasteful both in terms of cycles and memory, since these are usually
-requests for user interaction. Hence we use a QVariantMap to accommodate all the different needed
-parameters, easily, and in a readable way. */
-struct RCallbackArgs {
-/** is main thread done with the callback, yet? Initialized to false inside the true handler: RThread::doStandardCallback () */
-	bool done;
-/** type of the callback */
-	enum RCallbackType {
-		RBackendExit,
-		RShowMessage,
-		RShowFiles,
-		RChooseFile,
-		REditFiles,
-		RReadLine
-       } type;
-/** All the parameters sent in either direction */
-	QVariantMap params;
-};
-
-class QStringList;
-class RData;
-class QTextCodec;
-/** This function converts a list of strings to a QStringList (locale aware), and returns the pointer. Needed to keep R and Qt includes separate. The strings can be deleted afterwards. Implementation is in rthread.cpp */
-QString *stringsToStringList (char **strings, int count);
-/** Function to delete an array of Qstring. Does delete [] strings, nothing more. But can not inline this in this class due to conflicting R and Qt includes. Implementation is in rthread.cpp */
-void deleteQStringArray (QString *strings);
-
- /** The main purpose of separating this class from RThread is that R- and Qt-includes don't go together well. Hence this class is Qt-agnostic while
-	RThread is essentially R-agnostic.
-	
-	@see RThread
-
-	*@author Thomas Friedrichsmeier
-*/
-class REmbedInternal {
-public: 
-/** constructor. You can't create an instance of this class due to pure virtual functions. Create an instance of RThread instead. */
-	REmbedInternal ();
-/** destructor */
-	virtual ~REmbedInternal ();
-
-/** set up R standard callbacks */
-	void setupCallbacks ();
-/** connect R standard callbacks */
-	void connectCallbacks ();
-
-/** Enum specifying types of errors that may occur while parsing/evaluating a command in R */
-	enum RKWardRError {
-		NoError=0,			/**< No error */
-		Incomplete=1,		/**< The command is incomplete. Command was syntactically ok up to given point, but incomplete. It may or may not be semantically correct. */
-		SyntaxError=2,		/**< Syntax error */
-		OtherError=3		/**< Other error, usually a semantic error, e.g. object not found */
-	};
-
-/** clean shutdown of R.
- at param suicidal if true, perform only the most basic shutdown operations */
-	void shutdown (bool suicidal);
-protected:
-/** low-level initialization of R
- at param argc Number of arguments as would be passed on the commandline to R
- at param argv Arguments as would be passed on the commandline to R
- at param stack_check C stack checking enabled */
-	bool startR (int argc, char **argv, bool stack_check);
-/** low-level running of a command.
- at param command command to be run
- at param error this will be set to a value in RKWardError depending on success/failure of the command
- at param print_result whether the R_Visible flag should be set. If true, R will behave mostly as if in a regular console session. Otherwise values
-will only be printed if called for expressedly with print ("...") or similar.
- at param suppress_incomplete make sure never to run an incomplete command */
-	void runCommandInternal (const QString &command, RKWardRError *error, bool print_result=false);
-/** basically a wrapper to runCommandInternal (). Tries to convert the result of the command to an array of char* after running the command. Since
-this will not ever be done for user commands, the R_Visible flag will never be set.
- at param command command to be run 
- at param count length of list returned
- at param error this will be set to a value in RKWardError depending on success/failure of the command
- at returns an array of QString or 0 on failure
- at see RCommand::GetStringVector */
-	QString *getCommandAsStringVector (const QString &command, unsigned int *count, RKWardRError *error);
-/** basically a wrapper to runCommandInternal (). Tries to convert the result of the command to an array of double after running the command. Since
-this will not ever be done for user commands, the R_Visible flag will never be set.
- at param command command to be run 
- at param count length of array returned
- at param error this will be set to a value in RKWardError depending on success/failure of the command
- at returns an array of double or 0 on failure
- at see RCommand::GetRealVector */
-	double *getCommandAsRealVector (const QString &command, unsigned int *count, RKWardRError *error);

@@ Diff output truncated at 100000 characters. @@

This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the rkward-tracker mailing list