summaryrefslogtreecommitdiffstats
path: root/tools/qsexec/src/main.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tools/qsexec/src/main.cpp')
-rw-r--r--tools/qsexec/src/main.cpp240
1 files changed, 240 insertions, 0 deletions
diff --git a/tools/qsexec/src/main.cpp b/tools/qsexec/src/main.cpp
new file mode 100644
index 0000000..912a531
--- /dev/null
+++ b/tools/qsexec/src/main.cpp
@@ -0,0 +1,240 @@
+/****************************************************************************
+**
+** Copyright (C) 2007-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the QtScript project on Trolltech Labs.
+**
+** This file may be used under the terms of the GNU General Public
+** License version 2.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of
+** this file. Please review the following information to ensure GNU
+** General Public Licensing requirements will be met:
+** http://www.trolltech.com/products/qt/opensource.html
+**
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://www.trolltech.com/products/qt/licensing.html or contact the
+** sales department at sales@trolltech.com.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+****************************************************************************/
+
+#include <QtScript>
+
+#include <QtCore/QFile>
+#include <QtCore/QTextStream>
+#include <QtCore/QStringList>
+#include <QtCore/QCoreApplication>
+#include <QtCore/QSet>
+#include <QtDebug>
+
+namespace {
+
+void printUsage()
+{
+ QFile info(QCoreApplication::applicationDirPath()+"/README.TXT");
+ if (!info.exists() || !info.open(QFile::ReadOnly)) {
+ qDebug() << "Can't read README.TXT";
+ } else {
+ QTextStream stream(&info);
+ qDebug() << stream.readAll();
+ info.close();
+ }
+}
+
+bool loadFile(QString fileName, QScriptEngine *engine)
+{
+ // avoid loading files more than once
+ static QSet<QString> loadedFiles;
+ QFileInfo fileInfo(fileName);
+ QString absoluteFileName = fileInfo.absoluteFilePath();
+ QString absolutePath = fileInfo.absolutePath();
+ QString canonicalFileName = fileInfo.canonicalFilePath();
+ if (loadedFiles.contains(canonicalFileName)) {
+ return true;
+ }
+ loadedFiles.insert(canonicalFileName);
+ QString path = fileInfo.path();
+
+ // load the file
+ QFile file(fileName);
+ if (file.open(QFile::ReadOnly)) {
+ QTextStream stream(&file);
+ QString contents = stream.readAll();
+ file.close();
+
+ int endlineIndex = contents.indexOf('\n');
+ QString line = contents.left(endlineIndex);
+ int lineNumber = 1;
+
+ // strip off #!/usr/bin/env qscript line
+ if (line.startsWith("#!")) {
+ contents.remove(0, endlineIndex+1);
+ ++lineNumber;
+ }
+
+ // set qt.script.absoluteFilePath
+ QScriptValue script = engine->globalObject().property("qs").property("script");
+ QScriptValue oldFilePathValue = script.property("absoluteFilePath");
+ QScriptValue oldPathValue = script.property("absolutePath");
+ script.setProperty("absoluteFilePath", engine->toScriptValue(absoluteFileName));
+ script.setProperty("absolutePath", engine->toScriptValue(absolutePath));
+
+ QScriptValue r = engine->evaluate(contents, fileName, lineNumber);
+ if (engine->hasUncaughtException()) {
+ QStringList backtrace = engine->uncaughtExceptionBacktrace();
+ qDebug() << QString(" %1\n%2\n\n").arg(r.toString()).arg(backtrace.join("\n"));
+ return true;
+ }
+ script.setProperty("absoluteFilePath", oldFilePathValue); // if we come from includeScript(), or whereever
+ script.setProperty("absolutePath", oldPathValue); // if we come from includeScript(), or whereever
+ } else {
+ return false;
+ }
+ return true;
+}
+
+QScriptValue includeScript(QScriptContext *context, QScriptEngine *engine)
+{
+ QString currentFileName = engine->globalObject().property("qs").property("script").property("absoluteFilePath").toString();
+ QFileInfo currentFileInfo(currentFileName);
+ QString path = currentFileInfo.path();
+ QString importFile = context->argument(0).toString();
+ QFileInfo importInfo(importFile);
+ if (importInfo.isRelative()) {
+ importFile = path + "/" + importInfo.filePath();
+ }
+ if (!loadFile(importFile, engine)) {
+ return context->throwError(QString("Failed to resolve include: %1").arg(importFile));
+ }
+ return engine->toScriptValue(true);
+}
+
+QScriptValue importExtension(QScriptContext *context, QScriptEngine *engine)
+{
+ return engine->importExtension(context->argument(0).toString());
+}
+
+bool stopInteractiveMode;
+
+QScriptValue exitInteractiveMode(QScriptContext *context, QScriptEngine *engine)
+{
+ Q_UNUSED(context);
+ stopInteractiveMode = true;
+ return engine->undefinedValue();
+}
+void interactiveMode(QScriptEngine *engine)
+{
+ engine->globalObject().setProperty("quit", engine->newFunction(exitInteractiveMode));
+ qDebug() << "Running in interactive mode. Press Ctrl+C or call quit() to stop.";
+
+ QTextStream input(stdin, QFile::ReadOnly);
+ const char *qtScriptPrompt = "qs> ";
+ const char *dotPrompt = ".... ";
+ const char *prompt = qtScriptPrompt;
+ QString code;
+ stopInteractiveMode = false;
+ while (!stopInteractiveMode) {
+ QString line;
+ printf("%s", prompt);
+ fflush(stdout);
+ line = input.readLine();
+ if (line.isNull())
+ break;
+ code += line;
+ code += QLatin1Char('\n');
+ if (line.trimmed().isEmpty()) {
+ continue;
+ } else if (!engine->canEvaluate(code)) {
+ prompt = dotPrompt;
+ } else {
+ QScriptValue result = engine->evaluate(code, QLatin1String("stdin"));
+ code.clear();
+ prompt = qtScriptPrompt;
+ if (!result.isUndefined())
+ fprintf(stderr, "%s\n", qPrintable(result.toString()));
+ }
+ }
+}
+
+} // namespace
+
+int main(int argc, char *argv[])
+{
+ QCoreApplication app(argc, argv);
+ QStringList paths = QStringList() << QCoreApplication::applicationDirPath() + "/../../plugins";
+ app.setLibraryPaths(paths);
+
+ QScriptEngine *engine = new QScriptEngine();
+
+ QScriptValue global = engine->globalObject();
+ // add the qt object
+ global.setProperty("qs", engine->newObject());
+ // add a 'script' object
+ QScriptValue script = engine->newObject();
+ global.property("qs").setProperty("script", script);
+ // add a 'system' object
+ QScriptValue system = engine->newObject();
+ global.property("qs").setProperty("system", system);
+
+ // add os information to qt.system.os
+#ifdef Q_OS_WIN32
+ QScriptValue osName = engine->toScriptValue(QString("windows"));
+#elif defined(Q_OS_LINUX)
+ QScriptValue osName = engine->toScriptValue(QString("linux"));
+#elif defined(Q_OS_MAC)
+ QScriptValue osName = engine->toScriptValue(QString("mac"));
+#elif defined(Q_OS_UNIX)
+ QScriptValue osName = engine->toScriptValue(QString("unix"));
+#endif
+ system.setProperty("os", osName);
+
+ // add environment variables to qt.system.env
+ QMap<QString,QVariant> envMap;
+ QStringList envList = QProcess::systemEnvironment();
+ foreach (const QString &entry, envList) {
+ QStringList keyVal = entry.split('=');
+ if (keyVal.size() == 1)
+ envMap.insert(keyVal.at(0), QString());
+ else
+ envMap.insert(keyVal.at(0), keyVal.at(1));
+ }
+ system.setProperty("env", engine->toScriptValue(envMap));
+
+ // add the include functionality to qt.script.include
+ script.setProperty("include", engine->newFunction(includeScript));
+ // add the importExtension functionality to qt.script.importExtension
+ script.setProperty("importExtension", engine->newFunction(importExtension));
+
+ QStringList args = QCoreApplication::arguments();
+ args.takeFirst();
+ if (args.isEmpty()) {
+ interactiveMode(engine);
+ } else if (args.size() == 1 &&
+ (args.at(0) == "-help" || args.at(0) == "--help" || args.at(0) == "-h" || args.at(0) == "/h")) {
+ printUsage();
+ } else { // read script file and execute
+
+ QStringList files;
+ bool singlefile = (args.at(0) != "-f");
+ if (singlefile) {
+ files << args.takeFirst();
+ // add arguments to qt.script.arguments
+ script.setProperty("args", engine->toScriptValue(args));
+ } else {
+ args.takeFirst();
+ files += args;
+ }
+
+ foreach (const QString &fileName, files) {
+ if (!loadFile(fileName, engine)) {
+ qDebug() << "Failed:" << fileName;
+ return EXIT_FAILURE;
+ }
+ }
+ }
+ delete engine;
+ return EXIT_SUCCESS;
+}