summaryrefslogtreecommitdiffstats
path: root/old/interpreter/scriptpreprocessor.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'old/interpreter/scriptpreprocessor.cpp')
-rw-r--r--old/interpreter/scriptpreprocessor.cpp256
1 files changed, 256 insertions, 0 deletions
diff --git a/old/interpreter/scriptpreprocessor.cpp b/old/interpreter/scriptpreprocessor.cpp
new file mode 100644
index 0000000..42a413b
--- /dev/null
+++ b/old/interpreter/scriptpreprocessor.cpp
@@ -0,0 +1,256 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of QtUiTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "scriptpreprocessor.h"
+#include "qscriptsystemtest.h"
+
+#include <QScriptEngine>
+#include <QScriptValue>
+#include <QScriptValueIterator>
+#include <QByteArray>
+
+ScriptPreprocessor::ScriptPreprocessor()
+{
+ QScriptEngine engine;
+ QScriptSystemTest::loadInternalScript("config.js", &engine);
+
+ QScriptValue settings = engine.globalObject().property("preprocess");
+ if (!settings.isObject()) return;
+
+ /* The documentation for the following settings objects is in config.js */
+
+ {
+ QScriptValueIterator it(settings.property("functionAppends"));
+ while (it.hasNext()) {
+ it.next();
+ functionAppends[it.name()] = it.value().toString();
+ }
+ }
+}
+
+void ScriptPreprocessor::preprocess(QString &script)
+{
+ QString out;
+ out.reserve(script.size());
+
+ bool in_singleline_comment = false;
+ bool in_multiline_comment = false;
+ bool in_singlequote_literal = false;
+ bool in_doublequote_literal = false;
+
+ const char singlequote = '\'';
+ const char doublequote = '"';
+ const char brace_open = '(';
+ const char brace_close = ')';
+ const char curlybrace_open = '{';
+ const char curlybrace_close = '}';
+ const char newline = '\n';
+ const char cr = '\r';
+ const char backslash = '\\';
+ const char forwardslash = '/';
+ const char asterisk = '*';
+
+ QString identifier_chars = "_";
+ for (char c = '0'; c <= '9'; ++c) identifier_chars.append(c);
+ for (char c = 'a'; c <= 'z'; ++c) identifier_chars.append(c);
+ for (char c = 'A'; c <= 'Z'; ++c) identifier_chars.append(c);
+
+ int braces = 0;
+ int curlybraces = 0;
+
+ QString function_append;
+ int function_append_braces = 0;
+
+ for (int i = 0; i < script.count(); ++i) {
+ QChar c1 = script[i];//.toLatin1();
+ QChar c2 = script[i+1];//.toLatin1(); // OK; QByteArray is always null-terminated.
+
+ if (in_singleline_comment) {
+ if (newline == c1) {
+ in_singleline_comment = false;
+ out.append(c1);
+ continue;
+ }
+ out.append(c1);
+ continue;
+ }
+
+ if (in_multiline_comment) {
+ if (asterisk == c1 && forwardslash == c2) {
+ in_multiline_comment = false;
+ out.append(c1);
+ out.append(c2);
+ ++i;
+ continue;
+ }
+ out.append(c1);
+ continue;
+ }
+
+ if (in_singlequote_literal) {
+ if (backslash == c1) {
+ out.append(c1);
+ out.append(c2);
+ ++i;
+ continue;
+ }
+ if (singlequote == c1) {
+ in_singlequote_literal = false;
+ out.append(c1);
+ continue;
+ }
+ if (cr == c1 && newline == c2) {
+ out.append("\\n\'+\r\n\'");
+ ++i;
+ continue;
+ }
+ if (newline == c1) {
+ out.append("\\n\'+\n\'");
+ continue;
+ }
+ out.append(c1);
+ continue;
+ }
+
+ if (in_doublequote_literal) {
+ if (backslash == c1) {
+ out.append(c1);
+ out.append(c2);
+ ++i;
+ continue;
+ }
+ if (doublequote == c1) {
+ in_doublequote_literal = false;
+ out.append(c1);
+ continue;
+ }
+ if (cr == c1 && newline == c2) {
+ out.append("\\n\"+\r\n\"");
+ ++i;
+ continue;
+ }
+ if (newline == c1) {
+ out.append("\\n\"+\n\"");
+ continue;
+ }
+ out.append(c1);
+ continue;
+ }
+
+ switch(c1.toLatin1()) {
+
+ case singlequote:
+ in_singlequote_literal = true;
+ out.append(c1);
+ continue;
+
+ case doublequote:
+ in_doublequote_literal = true;
+ out.append(c1);
+ continue;
+
+ case forwardslash:
+ out.append(c1);
+ if (c2 == forwardslash) {
+ in_singleline_comment = true;
+ out.append(c2);
+ ++i;
+ }
+ if (c2 == asterisk) {
+ in_multiline_comment = true;
+ out.append(c2);
+ ++i;
+ }
+ continue;
+
+ case brace_open:
+ ++braces;
+ out.append(c1);
+ continue;
+
+ case brace_close:
+ --braces;
+ out.append(c1);
+ if (!function_append.isEmpty() && function_append_braces == braces) {
+ out.append(function_append);
+ function_append = QString();
+ }
+ continue;
+
+ case curlybrace_open:
+ ++curlybraces;
+ out.append(c1);
+ continue;
+
+ case curlybrace_close:
+ --curlybraces;
+ out.append(c1);
+ continue;
+
+ default:
+ // Look ahead to next non-identifier character
+ int tok_len;
+ for (tok_len = 0; i + tok_len < script.count() && identifier_chars.contains(script[i+tok_len]); ++tok_len) {}
+ if (tok_len < 2) {
+ out.append(c1);
+ continue;
+ }
+ QString tok = script.mid(i, tok_len);
+
+ // Apply preprocessing rules
+
+ // 1. Function appends - text placed immediately after the closing
+ // bracket of a function invocation.
+ if (functionAppends.contains(tok)) {
+ function_append = functionAppends[tok];
+ function_append_braces = braces;
+ }
+
+ out.append(tok);
+ i += tok_len - 1;
+ continue;
+ }
+ }
+
+ out.squeeze();
+
+ script = out;
+}