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

tfry at users.sf.net tfry at users.sf.net
Mon Nov 3 13:18:34 UTC 2014


Revision: 4983
          http://sourceforge.net/p/rkward/code/4983
Author:   tfry
Date:     2014-11-03 13:18:31 +0000 (Mon, 03 Nov 2014)
Log Message:
-----------
- Move i18n-code back to common.js. It's much easier to read, there, and probably we will use slightly different semantics in rkcomponentscript.js
- Enhance quote() and noquote() function to support several levels of quote protection.
- Cache compilation of common.js (Qt >= 4.7)

Modified Paths:
--------------
    trunk/rkward/rkward/plugins/testing/test1.xml
    trunk/rkward/rkward/scriptbackends/common.js
    trunk/rkward/rkward/scriptbackends/qtscriptbackend.cpp
    trunk/rkward/rkward/scriptbackends/qtscriptbackend.h
    trunk/rkward/rkward/scriptbackends/qtscripti18n.cpp

Modified: trunk/rkward/rkward/plugins/testing/test1.xml
===================================================================
--- trunk/rkward/rkward/plugins/testing/test1.xml	2014-11-01 16:35:21 UTC (rev 4982)
+++ trunk/rkward/rkward/plugins/testing/test1.xml	2014-11-03 13:18:31 UTC (rev 4983)
@@ -7,7 +7,7 @@
 		<script><![CDATA[
 			call_num = 0;
  			last_command_id = -1;
-			gui.setValue ("text.text", "Select a dependent variable!");
+			gui.setValue ("text.text", i18n ("Select a dependent variable!"));
 
 			/*f = Kross.module('forms');
 			label = f.createWidget(scripty, 'QLabel', 'Label', {});

Modified: trunk/rkward/rkward/scriptbackends/common.js
===================================================================
--- trunk/rkward/rkward/scriptbackends/common.js	2014-11-01 16:35:21 UTC (rev 4982)
+++ trunk/rkward/rkward/scriptbackends/common.js	2014-11-03 13:18:31 UTC (rev 4983)
@@ -18,16 +18,73 @@
 }
 
 noquote = function (text) {
+	if (text.noquote) {
+		text.noquote++;
+		return (text);
+	}
 	var ret = new String (text);
 	ret.noquote = 1;
 	return (ret);
 }
 
 quote = function (text) {
-	if (text.noquote) return text;
+	if (text.noquote) {
+		text.noquote--;
+		return (text);
+	}
 	return ("\"" + text.replace (/\"/g, "\\\"") + "\"");
 }
 
+i18n = function (msgid) {
+	var ret = _i18n.i18n (msgid);
+	for (int i = 1; i < arguments.length; i++) {
+		ret = ret.replace(new RegExp("%" + i, 'g'), arguments[i]);
+	}
+	if (msgid.noquote) {
+		ret.noquote = msgid.noquote;
+		return (ret);
+	}
+	// quote the translated string, as it will most likely be passed to R as a string literal.
+	// at the same time, protect it against additional quoting (esp. when used in makeHeaderCode ())
+	return (noquote (quote (ret)));
+}
+
+i18nc = function (msgctxt, msgid) {
+	var ret = _i18n.i18nc (msgctxt, msgid);
+	for (int i = 2; i < arguments.length; i++) {
+		ret = ret.replace(new RegExp("%" + (i - 1), 'g'), arguments[i]);
+	}
+	if (msgid.noquote) {
+		ret.noquote = msgid.noquote;
+		return (ret);
+	}
+	return (noquote (quote (ret)));
+}
+
+i18np = function (msgid, msgid_plural, n) {
+	var ret = _i18n.i18np (msgid, msgid_plural, n);
+	for (int i = 3; i < arguments.length; i++) {
+		ret = ret.replace(new RegExp("%" + (i - 1), 'g'), arguments[i]);	// start replacing at %2. %1 already handled.
+	}
+	if (msgid.noquote) {
+		ret.noquote = msgid.noquote;
+		return (ret);
+	}
+	return (noquote (quote (ret)));
+}
+
+i18ncp = function (msgctxt, msgid, msgid_plural, n) {
+	var ret = _i18n.i18ncp (msgctxt, msgid, msgid_plural, n);
+	for (int i = 4; i < arguments.length; i++) {
+		ret = ret.replace(new RegExp("%" + (i - 2), 'g'), arguments[i]);
+	}
+	if (msgid.noquote) {
+		ret.noquote = msgid.noquote;
+		return (ret);
+	}
+	return (noquote (quote (ret)));
+}
+
 makeHeaderCode = function (title, parameters) {
 	echo ("rk.header(" + quote (title));
 	if (parameters.length) {

Modified: trunk/rkward/rkward/scriptbackends/qtscriptbackend.cpp
===================================================================
--- trunk/rkward/rkward/scriptbackends/qtscriptbackend.cpp	2014-11-01 16:35:21 UTC (rev 4982)
+++ trunk/rkward/rkward/scriptbackends/qtscriptbackend.cpp	2014-11-03 13:18:31 UTC (rev 4983)
@@ -143,9 +143,11 @@
 
 #include <kurl.h>
 
-QtScriptBackendThread::QtScriptBackendThread (const QString &commonfile, const QString &scriptfile, QtScriptBackend *parent, const RKMessageCatalog *catalog) : QThread (parent) {
+QtScriptBackendThread::QtScriptBackendThread (const QString &commonfile, const QString &scriptfile, QtScriptBackend *parent, const RKMessageCatalog *catalog) : QThread (parent), engine (0) {
 	RK_TRACE (PHP);
 
+	// you'd think the engine already was in this thread, but no, it is not. You'd also think, this was fixable by setting "this" as the engine's parent, instead of 0, but no, somehow not.
+	engine.moveToThread (this);
 	_commonfile = commonfile;
 	_scriptfile = scriptfile;
 	killed = false;
@@ -251,8 +253,8 @@
 		_filename = script_path.toLocalFile ();
 	}
 
-        QFile file (_filename);
-        if (!file.open (QIODevice::ReadOnly | QIODevice::Text)) {
+		QFile file (_filename);
+		if (!file.open (QIODevice::ReadOnly | QIODevice::Text)) {
 		emit (error (i18n ("The file \"%1\" (needed by \"%2\") could not be found. Please check your installation.", _filename, _scriptfile)));
 		return false;
 	}
@@ -274,7 +276,18 @@
 	RKMessageCatalogObject::addI18nToScriptEngine (&engine, catalog);
 	if (scriptError ()) return;
 
+#ifdef USE_Q_SCRIPT_PROGRAM
+	if (!RKPrecompiledQtScripts::loadCommonScript (&engine, _commonfile)) {
+		if (!engine.hasUncaughtException ()) {
+			emit error (i18n ("Could not open common script file \"%1\"", _commonfile));
+		} else {
+			scriptError ();
+		}
+		return;
+	}
+#else
 	if (!includeFile (_commonfile)) return;
+#endif
 	if (!includeFile (_scriptfile)) return;
 
 	emit (commandDone ("startup complete"));
@@ -308,4 +321,34 @@
 	}
 }
 
+#ifdef USE_Q_SCRIPT_PROGRAM
+namespace RKPrecompiledQtScripts {
+	QMap<QString, QScriptProgram> compiled_includes;
+	QMutex compiled_includes_mutex;
+
+	bool loadCommonScript (QScriptEngine* engine, QString scriptfile) {
+		RK_TRACE (PHP);
+
+		QMutexLocker ml (&compiled_includes_mutex);
+		if (!compiled_includes.contains (scriptfile)) {
+			RK_DEBUG (PHP, DL_DEBUG, "Compiling common script file %s", qPrintable (scriptfile));
+			QFile file (scriptfile);
+			if (!file.open (QIODevice::ReadOnly | QIODevice::Text)) {
+				return false;
+			}
+			compiled_includes.insert (scriptfile, QScriptProgram (file.readAll (), scriptfile));
+			file.close ();
+		} else {
+			RK_DEBUG (PHP, DL_DEBUG, "Script file %s is already compiled", qPrintable (scriptfile));
+		}
+		engine->evaluate (compiled_includes[scriptfile]);
+		if (engine->hasUncaughtException ()) {
+			compiled_includes.remove (scriptfile);
+			return false;
+		}
+		return true;
+	}
+}
+#endif
+
 #include "qtscriptbackend.moc"

Modified: trunk/rkward/rkward/scriptbackends/qtscriptbackend.h
===================================================================
--- trunk/rkward/rkward/scriptbackends/qtscriptbackend.h	2014-11-01 16:35:21 UTC (rev 4982)
+++ trunk/rkward/rkward/scriptbackends/qtscriptbackend.h	2014-11-03 13:18:31 UTC (rev 4983)
@@ -2,7 +2,7 @@
                           qtscriptbackend  -  description
                              -------------------
     begin                : Mon Sep 28 2009
-    copyright            : (C) 2009, 2012 by Thomas Friedrichsmeier
+    copyright            : (C) 2009, 2012, 2014 by Thomas Friedrichsmeier
     email                : tfry at users.sourceforge.net
  ***************************************************************************/
 
@@ -104,4 +104,12 @@
 	bool sleeping;
 };
 
+#if QT_VERSION >= 0x040700
+#	define USE_Q_SCRIPT_PROGRAM
+#	include <QScriptProgram>
+namespace RKPrecompiledQtScripts {
+	bool loadCommonScript (QScriptEngine *engine, QString scriptfile);
+};
 #endif
+
+#endif

Modified: trunk/rkward/rkward/scriptbackends/qtscripti18n.cpp
===================================================================
--- trunk/rkward/rkward/scriptbackends/qtscripti18n.cpp	2014-11-01 16:35:21 UTC (rev 4982)
+++ trunk/rkward/rkward/scriptbackends/qtscripti18n.cpp	2014-11-03 13:18:31 UTC (rev 4983)
@@ -24,25 +24,6 @@
 void RKMessageCatalogObject::addI18nToScriptEngine (QScriptEngine* engine, const RKMessageCatalog* catalog) {
 	QScriptValue handle = engine->newQObject (new RKMessageCatalogObject (catalog, engine));
 	engine->globalObject ().setProperty ("_i18n", handle);
-
-	const int n_funs = 4;
-	// NOTE that we exploit the fact that these are ordered by number of arguments from 1 to 4, below.
-	QLatin1String funs [n_funs] = { 
-		QLatin1String ("i18n(msgid)"), 
-		QLatin1String ("i18nc(msgctxt, msgid)"), 
-		QLatin1String ("i18np(msgid, msgid_plural, count)"), 
-		QLatin1String ("i18ncp(msgctxt, msgid, msgid_plural, count)")
-	};
-	QString eval;
-	for (int i = 0; i < n_funs; ++i) {
-		eval += QLatin1String ("function ") + funs[i] + QLatin1String ("{ ret = _i18n.") + funs[i] + ";\n"
-		      + QLatin1String ("argn=") + ((i < 2) ? QLatin1String ("1") : QLatin1String ("2")) + ";\n"
-		      + QLatin1String ("for (i=") + QString::number (i+1) + QLatin1String ("; i<arguments.length; i++) ")
-			  + QLatin1String ("ret = ret.replace(new RegExp(\"%\"+argn++, 'g'), arguments[i]);\n")
-			  + QLatin1String ("return(ret); }\n");
-	}
-	RK_DEBUG (PHP, DL_DEBUG, "Evaluating i18n glue code:\n%s", qPrintable (eval));
-	engine->evaluate (eval);
 }
 
 #include "qtscripti18n.moc"





More information about the rkward-tracker mailing list