int main(int argc, char **argv) { QCoreApplication app(argc, argv); if ( argc < 3 ) { qDebug("not enough arguments"); return 1; } QFile f(argv[1]); if ( !f.open(QFile::ReadOnly | QFile::Text) ) { qDebug("Unable to open assembler script file."); return 1; } QScriptEngine engine; QScriptValue v = engine.evaluate(QString::fromLocal8Bit(f.readAll()), f.fileName(), 1); if ( engine.hasUncaughtException() ) { qDebug("Uncaught exception while loading assembler script at line %i: %s", engine.uncaughtExceptionLineNumber(), qPrintable(engine.uncaughtException().toString()) ); return 2; } f.close(); f.setFileName(argv[2]); if ( !f.open(QFile::ReadOnly | QFile::Text) ) { qDebug("Unable to open source file."); return 1; } engine.globalObject().setProperty("source", engine.newVariant(QString::fromLocal8Bit(f.readAll()))); engine.globalObject().setProperty("reloc", engine.newVariant(argc > 3 ? QString::fromLocal8Bit(argv[3]) : "0x0000")); QScriptValue r = engine.evaluate("assemble(source, reloc)"); if ( engine.hasUncaughtException() ) { qDebug("Uncaught exception while assembling file at line %i: %s", engine.uncaughtExceptionLineNumber(), qPrintable(engine.uncaughtException().toString()) ); return 3; } qDebug("%s", qPrintable(r.toString())); return 0; }
int main(int argc, char *argv[]) { QApplication app(argc, argv); QScriptEngine engine; QFile scriptFile(":/object.js"); scriptFile.open(QFile::ReadOnly); engine.evaluate(scriptFile.readAll()); scriptFile.close(); QTextEdit editor; QTimer timer; QScriptValue constructor = engine.evaluate("Object"); QScriptValueList arguments; arguments << engine.newQObject(&timer); arguments << engine.newQObject(&editor); QScriptValue object = constructor.construct(arguments); if (engine.hasUncaughtException()) { qDebug() << engine.uncaughtException().toString(); } editor.show(); timer.start(1000); return app.exec(); }
int main(int argc, char **argv) { Q_INIT_RESOURCE(rtfedit); QApplication app(argc, argv); QTextCodec::setCodecForTr(QTextCodec::codecForLocale()); QScriptEngine engine; QFile scriptFile(":/rtfedit.js"); scriptFile.open(QIODevice::ReadOnly); engine.evaluate(QObject::tr(scriptFile.readAll())); scriptFile.close(); RTFUiLoader loader; QFile uiFile(":/rtfedit.ui"); uiFile.open(QIODevice::ReadOnly); QWidget *ui = loader.load(&uiFile); uiFile.close(); QScriptValue func = engine.evaluate("RTF"); QScriptValue scriptUi = engine.newQObject(ui); QScriptValue table = func.construct(QScriptValueList() << scriptUi); if(engine.hasUncaughtException()) { QScriptValue value = engine.uncaughtException(); QString lineNumber = QString("\nLine Number:%1\n").arg(engine.uncaughtExceptionLineNumber()); QStringList btList = engine.uncaughtExceptionBacktrace(); QString trace; for(short i=0; i<btList.size(); ++i) trace += btList.at(i); QMessageBox::information(NULL, QObject::tr("Exception"), value.toString() + lineNumber + trace ); } ui->show(); return app.exec(); }
QVariant JsonTranslationService::parseJson(const QByteArray &json) { #if QT_VERSION < QT_VERSION_CHECK(5,0,0) QString js; js.reserve(json.size() + 2); js.append("(").append(QString::fromUtf8(json)).append(")"); static QScriptEngine engine; if (!engine.canEvaluate(js)) { m_error = tr("Couldn't parse response from the server because of an error: \"%1\"") .arg(tr("Can't evaluate JSON data")); return QVariant(); } QScriptValue data = engine.evaluate(js); if (engine.hasUncaughtException()) { m_error = tr("Couldn't parse response from the server because of an error: \"%1\"") .arg(engine.uncaughtException().toString()); return QVariant(); } return data.toVariant(); #else QJsonParseError err; QJsonDocument doc = QJsonDocument::fromJson(json, &err); if (err.error != QJsonParseError::NoError) { m_error = tr("Couldn't parse response from the server because of an error: \"%1\"") .arg(err.errorString()); return QVariant(); } return doc.toVariant(); #endif }
World *ScriptEvaluator::evaluate(const QString &script) { QScriptEngine engine; World* world = new World(); QScriptValue worldValue = engine.newQObject(world); engine.globalObject().setProperty("world", worldValue); QScriptValue directionalLightClass = engine.scriptValueFromQMetaObject<DirectionalLight>(); engine.globalObject().setProperty("DirectionalLight", directionalLightClass); engine.evaluate(script); if (engine.hasUncaughtException()) { QMessageBox messageBox; messageBox.setIcon(QMessageBox::Warning); messageBox.setWindowTitle("Script error"); messageBox.setText("An error occurred while executing the script."); messageBox.setInformativeText(engine.uncaughtException().toString()); messageBox.setDetailedText(engine.uncaughtExceptionBacktrace().join("\n")); messageBox.exec(); return 0; } return world; }
int tst_Suite::qt_metacall(QMetaObject::Call _c, int _id, void **_a) { _id = QObject::qt_metacall(_c, _id, _a); if (_id < 0) return _id; if (_c == QMetaObject::InvokeMetaMethod) { QString name = testNames.at(_id); QString path = testsDir.absoluteFilePath(name + ".js"); QString excludeMessage; if (isExcludedTest(name, &excludeMessage)) { QTest::qSkip(excludeMessage.toLatin1(), QTest::SkipAll, path.toLatin1(), -1); } else { QScriptEngine engine; engine.evaluate(mjsunitContents).toString(); if (engine.hasUncaughtException()) { QStringList bt = engine.uncaughtExceptionBacktrace(); QString err = engine.uncaughtException().toString(); qWarning("%s\n%s", qPrintable(err), qPrintable(bt.join("\n"))); } else { QScriptValue fakeFail = engine.newFunction(qscript_fail); fakeFail.setData(engine.globalObject().property("fail")); engine.globalObject().setProperty("fail", fakeFail); QString contents = readFile(path); QScriptValue ret = engine.evaluate(contents); if (engine.hasUncaughtException()) { if (!ret.isError()) { Q_ASSERT(ret.instanceOf(engine.globalObject().property("MjsUnitAssertionError"))); QString actual = ret.property("actual").toString(); QString expected = ret.property("expected").toString(); int lineNumber = ret.property("lineNumber").toInt32(); QString failMessage; if (isExpectedFailure(name, actual, expected, &failMessage)) { QTest::qExpectFail("", failMessage.toLatin1(), QTest::Continue, path.toLatin1(), lineNumber); } #ifdef GENERATE_ADDEXPECTEDFAILURE_CODE else { generatedAddExpectedFailureCode.append( " addExpectedFailure(\"" + name + "\", \"" + actual + "\", \"" + expected + "\", willFixInNextReleaseMessage);\n"); } #endif QTest::qCompare(actual, expected, "actual", "expect", path.toLatin1(), lineNumber); } else { int lineNumber = ret.property("lineNumber").toInt32(); QTest::qExpectFail("", ret.toString().toLatin1(), QTest::Continue, path.toLatin1(), lineNumber); QTest::qVerify(false, ret.toString().toLatin1(), "", path.toLatin1(), lineNumber); } } } } _id -= testNames.size(); } return _id; }
void tst_QScriptV8TestSuite::runTestFunction(int testIndex) { QString name = testNames.at(testIndex); QString path = testsDir.absoluteFilePath(name + ".js"); QString excludeMessage; if (isExcludedTest(name, &excludeMessage)) { QTest::qSkip(excludeMessage.toLatin1(), path.toLatin1(), -1); return; } QScriptEngine engine; engine.evaluate(mjsunitContents); if (engine.hasUncaughtException()) { QStringList bt = engine.uncaughtExceptionBacktrace(); QString err = engine.uncaughtException().toString(); qWarning("%s\n%s", qPrintable(err), qPrintable(bt.join("\n"))); } else { // Prepare to intercept calls to mjsunit's fail() function. QScriptValue fakeFail = engine.newFunction(qscript_fail); fakeFail.setData(engine.globalObject().property("fail")); engine.globalObject().setProperty("fail", fakeFail); QString contents = readFile(path); QScriptValue ret = engine.evaluate(contents); if (engine.hasUncaughtException()) { if (!ret.isError()) { int lineNumber = ret.property("lineNumber").toInt32(); QTest::qVerify(ret.instanceOf(engine.globalObject().property("MjsUnitAssertionError")), ret.toString().toLatin1(), "", path.toLatin1(), lineNumber); QString actual = ret.property("actual").toString(); QString expected = ret.property("expected").toString(); QString failMessage; if (shouldGenerateExpectedFailures) { if (ret.property("message").isString()) failMessage = ret.property("message").toString(); addExpectedFailure(name, actual, expected, failMessage); } else if (isExpectedFailure(name, actual, expected, &failMessage)) { QTest::qExpectFail("", failMessage.toLatin1(), QTest::Continue, path.toLatin1(), lineNumber); } QTest::qCompare(actual, expected, "actual", "expect", path.toLatin1(), lineNumber); } else { int lineNumber = ret.property("lineNumber").toInt32(); QTest::qExpectFail("", ret.toString().toLatin1(), QTest::Continue, path.toLatin1(), lineNumber); QTest::qVerify(false, ret.toString().toLatin1(), "", path.toLatin1(), lineNumber); } } } }
void handleException() { Q_ASSERT( m_engine ); Q_ASSERT( m_engine->hasUncaughtException() ); const QString err = m_engine->uncaughtException().toString(); const int linenr = m_engine->uncaughtExceptionLineNumber(); const QString trace = m_engine->uncaughtExceptionBacktrace().join("\n"); qrossdebug( QString("%1, line:%2, backtrace:\n%3").arg(err).arg(linenr).arg(trace) ); m_script->action()->setError(err, trace, linenr); m_engine->clearExceptions(); }
void FormulaDialog::accept() { QScriptEngine eng; QString exp = ui->formula->text(); exp.replace("%1", "%%1"); exp.replace("%n", "%1"); eng.evaluate(exp.arg(10)); if(eng.hasUncaughtException()) { Utils::showErrorBox(tr("There is an error in the formula, following exception was thrown:\n\n%1") .arg(eng.uncaughtException().toString())); return; } QDialog::accept(); }
static bool hadUncaughtExceptions(QScriptEngine& engine, const QString& fileName) { if (engine.hasUncaughtException()) { const auto backtrace = engine.uncaughtExceptionBacktrace(); const auto exception = engine.uncaughtException().toString(); const auto line = QString::number(engine.uncaughtExceptionLineNumber()); engine.clearExceptions(); auto message = QString("[UncaughtException] %1 in %2:%3").arg(exception, fileName, line); if (!backtrace.empty()) { static const auto lineSeparator = "\n "; message += QString("\n[Backtrace]%1%2").arg(lineSeparator, backtrace.join(lineSeparator)); } qWarning() << qPrintable(message); return true; } return false; }
int main(int argc, char **argv) { QCoreApplication app(argc, argv); QScriptEngine engine; QFile f(app.applicationDirPath() + "/calculator.js"); f.open(QFile::ReadOnly); QString theProgram = QTextStream(&f).readAll(); theProgram += "calculate('1/0');"; qDebug() << engine.evaluate(theProgram, "calculator.js").toNumber(); qDebug() << "Error?" << engine.hasUncaughtException(); qDebug() << engine.uncaughtException().property("message").toString(); qDebug() << "On line number" << engine.uncaughtExceptionLineNumber(); qDebug() << "Backtrace: " << engine.uncaughtExceptionBacktrace(); }
bool JSScript::execute(TWScriptAPI *tw) const { QFile scriptFile(m_Filename); if (!scriptFile.open(QIODevice::ReadOnly)) { // handle error return false; } QTextStream stream(&scriptFile); stream.setCodec(m_Codec); QString contents = stream.readAll(); scriptFile.close(); QScriptEngine engine; QScriptValue twObject = engine.newQObject(tw); engine.globalObject().setProperty("TW", twObject); QScriptValue val; #if QT_VERSION >= 0x040500 QSETTINGS_OBJECT(settings); if (settings.value("scriptDebugger", false).toBool()) { QScriptEngineDebugger debugger; debugger.attachTo(&engine); val = engine.evaluate(contents, m_Filename); } else { val = engine.evaluate(contents, m_Filename); } #else val = engine.evaluate(contents, m_Filename); #endif if (engine.hasUncaughtException()) { tw->SetResult(engine.uncaughtException().toString()); return false; } else { if (!val.isUndefined()) { tw->SetResult(convertValue(val)); } return true; } }
void ScriptForm::accept() { m_script = textEdit->toPlainText(); QScriptEngine javaScriptParser; int errorLineNumber = 0; QString errorMessage; #if QT_VERSION >= 0x040500 QScriptSyntaxCheckResult syntaxResult = javaScriptParser.checkSyntax(m_script); if (syntaxResult.state() != QScriptSyntaxCheckResult::Valid) { errorLineNumber = syntaxResult.errorLineNumber(); errorMessage = syntaxResult.errorMessage(); if (errorMessage.isEmpty()) errorMessage = tr("Syntax Error"); } #else QScriptValue value(&javaScriptParser, 0); javaScriptParser.globalObject().setProperty("cellRow", value); javaScriptParser.globalObject().setProperty("cellColumn", value); javaScriptParser.globalObject().setProperty("cellValue", value); QScriptValue result = javaScriptParser.evaluate(m_script); if (javaScriptParser.hasUncaughtException()) { errorLineNumber = javaScriptParser .uncaughtExceptionLineNumber(); errorMessage = javaScriptParser.uncaughtException() .toString(); } #endif if (!errorMessage.isEmpty()) { AQP::warning(this, tr("Error"), tr("Invalid script on line %1:\n%2") .arg(errorLineNumber).arg(errorMessage)); QTextCursor cursor = textEdit->textCursor(); cursor.clearSelection(); cursor.movePosition(QTextCursor::Start); cursor.movePosition(QTextCursor::Down, QTextCursor::MoveAnchor, errorLineNumber - 1); cursor.select(QTextCursor::LineUnderCursor); textEdit->setTextCursor(cursor); } else QDialog::accept(); }
int main(int argc, char **argv) { QCoreApplication app(argc, argv); QTextStream err(stderr); QStringList arguments = app.arguments(); if( arguments.length() < 2 ) { err << QString("USAGE: %1 <script>\n").arg(arguments[0]); return 1; } QScriptEngine engine; engine.globalObject().setProperty("createServer", engine.newFunction(createServer)); QFile file(arguments[1]); if( !file.open(QFile::ReadOnly) ) { err << QString("Error opening %1: %2\n").arg(arguments[1]).arg(file.errorString()); return 2; } QTextStream reader(&file); engine.evaluate(reader.readAll(), arguments[1]); if( engine.hasUncaughtException() ) { err << "Exception\n"; err << engine.uncaughtException().property("message").toString() << "\n"; err << "On line number " << engine.uncaughtExceptionLineNumber() << "\n"; err << "Backtrace:\n"; foreach(QString s, engine.uncaughtExceptionBacktrace()) err << " " << s << "\n"; return 3; } app.exec(); }
void ScriptJob::run() { m_mutex->lock(); if ( !loadScript(&m_data.program) ) { kDebug() << "Script could not be loaded correctly"; m_mutex->unlock(); return; } QScriptEngine *engine = m_engine; ScriptObjects objects = m_objects; m_mutex->unlock(); // Store start time of the script QElapsedTimer timer; timer.start(); // Add call to the appropriate function QString functionName; QScriptValueList arguments = QScriptValueList() << request()->toScriptValue( engine ); switch ( request()->parseMode() ) { case ParseForDepartures: case ParseForArrivals: functionName = ServiceProviderScript::SCRIPT_FUNCTION_GETTIMETABLE; break; case ParseForJourneysByDepartureTime: case ParseForJourneysByArrivalTime: functionName = ServiceProviderScript::SCRIPT_FUNCTION_GETJOURNEYS; break; case ParseForStopSuggestions: functionName = ServiceProviderScript::SCRIPT_FUNCTION_GETSTOPSUGGESTIONS; break; case ParseForAdditionalData: functionName = ServiceProviderScript::SCRIPT_FUNCTION_GETADDITIONALDATA; break; default: kDebug() << "Parse mode unsupported:" << request()->parseMode(); break; } if ( functionName.isEmpty() ) { // This should never happen, therefore no i18n handleError( "Unknown parse mode" ); return; } // Check if the script function is implemented QScriptValue function = engine->globalObject().property( functionName ); if ( !function.isFunction() ) { handleError( i18nc("@info/plain", "Function <icode>%1</icode> not implemented by " "the script", functionName) ); return; } // Call script function QScriptValue result = function.call( QScriptValue(), arguments ); if ( engine->hasUncaughtException() ) { // TODO Get filename where the exception occured, maybe use ScriptAgent for that handleError( i18nc("@info/plain", "Error in script function <icode>%1</icode>, " "line %2: <message>%3</message>.", functionName, engine->uncaughtExceptionLineNumber(), engine->uncaughtException().toString()) ); return; } GlobalTimetableInfo globalInfo; globalInfo.requestDate = QDate::currentDate(); globalInfo.delayInfoAvailable = !objects.result->isHintGiven( ResultObject::NoDelaysForStop ); // The called function returned, but asynchronous network requests may have been started. // Wait for all network requests to finish, because slots in the script may get called if ( !waitFor(objects.network.data(), SIGNAL(allRequestsFinished()), WaitForNetwork) ) { return; } // Wait for script execution to finish ScriptAgent agent( engine ); if ( !waitFor(&agent, SIGNAL(scriptFinished()), WaitForScriptFinish) ) { return; } // Update last download URL QMutexLocker locker( m_mutex ); m_lastUrl = objects.network->lastUrl(); // TODO Store all URLs m_lastUserUrl = objects.network->lastUserUrl(); // Inform about script run time DEBUG_ENGINE_JOBS( "Script finished in" << (timer.elapsed() / 1000.0) << "seconds: " << m_data.provider.scriptFileName() << request()->parseMode() ); // If data for the current job has already been published, do not emit // xxxReady() with an empty resultset if ( m_published == 0 || m_objects.result->count() > m_published ) { const bool couldNeedForcedUpdate = m_published > 0; const MoreItemsRequest *moreItemsRequest = dynamic_cast< const MoreItemsRequest* >( request() ); const AbstractRequest *_request = moreItemsRequest ? moreItemsRequest->request().data() : request(); switch ( _request->parseMode() ) { case ParseForDepartures: emit departuresReady( m_objects.result->data().mid(m_published), m_objects.result->features(), m_objects.result->hints(), m_objects.network->lastUserUrl(), globalInfo, *dynamic_cast<const DepartureRequest*>(_request), couldNeedForcedUpdate ); break; case ParseForArrivals: { emit arrivalsReady( m_objects.result->data().mid(m_published), m_objects.result->features(), m_objects.result->hints(), m_objects.network->lastUserUrl(), globalInfo, *dynamic_cast< const ArrivalRequest* >(_request), couldNeedForcedUpdate ); break; } case ParseForJourneysByDepartureTime: case ParseForJourneysByArrivalTime: emit journeysReady( m_objects.result->data().mid(m_published), m_objects.result->features(), m_objects.result->hints(), m_objects.network->lastUserUrl(), globalInfo, *dynamic_cast<const JourneyRequest*>(_request), couldNeedForcedUpdate ); break; case ParseForStopSuggestions: emit stopSuggestionsReady( m_objects.result->data().mid(m_published), m_objects.result->features(), m_objects.result->hints(), m_objects.network->lastUserUrl(), globalInfo, *dynamic_cast<const StopSuggestionRequest*>(_request), couldNeedForcedUpdate ); break; case ParseForAdditionalData: { const QList< TimetableData > data = m_objects.result->data(); if ( data.isEmpty() ) { handleError( i18nc("@info/plain", "Did not find any additional data.") ); return; } else if ( data.count() > 1 ) { kWarning() << "The script added more than one result set, only the first gets used"; } emit additionalDataReady( data.first(), m_objects.result->features(), m_objects.result->hints(), m_objects.network->lastUserUrl(), globalInfo, *dynamic_cast<const AdditionalDataRequest*>(_request), couldNeedForcedUpdate ); break; } default: kDebug() << "Parse mode unsupported:" << _request->parseMode(); break; } } // Check for exceptions if ( m_engine->hasUncaughtException() ) { // TODO Get filename where the exception occured, maybe use ScriptAgent for that handleError( i18nc("@info/plain", "Error in script function <icode>%1</icode>, " "line %2: <message>%3</message>.", functionName, m_engine->uncaughtExceptionLineNumber(), m_engine->uncaughtException().toString()) ); return; } // Cleanup m_engine->deleteLater(); m_engine = 0; m_objects.storage->checkLifetime(); m_objects.clear(); }
void ScriptableWorker::run() { MONITOR_LOG("starting"); QScriptEngine engine; ScriptableProxy proxy(m_wnd); Scriptable scriptable(&proxy); scriptable.initEngine( &engine, QString::fromUtf8(m_args.at(Arguments::CurrentPath)), m_args.at(Arguments::ActionId) ); if (m_socket) { QObject::connect( &scriptable, SIGNAL(sendMessage(QByteArray,int)), m_socket, SLOT(sendMessage(QByteArray,int)) ); QObject::connect( m_socket, SIGNAL(messageReceived(QByteArray,int)), &scriptable, SLOT(setInput(QByteArray)) ); QObject::connect( m_socket, SIGNAL(disconnected()), &scriptable, SLOT(abort()) ); QObject::connect( &scriptable, SIGNAL(destroyed()), m_socket, SLOT(deleteAfterDisconnected()) ); if ( m_socket->isClosed() ) { MONITOR_LOG("terminated"); return; } m_socket->start(); } QObject::connect( &scriptable, SIGNAL(requestApplicationQuit()), qApp, SLOT(quit()) ); QByteArray response; int exitCode; if ( m_args.length() <= Arguments::Rest ) { MONITOR_LOG("Error: bad command syntax"); exitCode = CommandBadSyntax; } else { const QString cmd = QString::fromUtf8( m_args.at(Arguments::Rest) ); if ( hasLogLevel(LogDebug) ) { MONITOR_LOG("Client arguments:"); for (int i = Arguments::Rest; i < m_args.length(); ++i) MONITOR_LOG( " " + QString::fromUtf8(m_args.at(i)) ); } #ifdef HAS_TESTS if ( cmd == "flush" && m_args.length() == Arguments::Rest + 2 ) { MONITOR_LOG( "flush ID: " + QString::fromUtf8(m_args.at(Arguments::Rest + 1)) ); scriptable.sendMessageToClient(QByteArray(), CommandFinished); return; } #endif QScriptValue fn = engine.globalObject().property(cmd); if ( !fn.isFunction() ) { MONITOR_LOG("Error: unknown command"); response = createLogMessage("CopyQ client", Scriptable::tr("Name \"%1\" doesn't refer to a function.") .arg(cmd), LogError).toUtf8(); exitCode = CommandError; } else { QScriptValueList fnArgs; for ( int i = Arguments::Rest + 1; i < m_args.length(); ++i ) fnArgs.append( scriptable.newByteArray(m_args.at(i)) ); QScriptValue result = fn.call(QScriptValue(), fnArgs); if ( engine.hasUncaughtException() ) { const QString exceptionText = engine.uncaughtException().toString(); MONITOR_LOG( QString("Error: exception in command \"%1\": %2") .arg(cmd).arg(exceptionText) ); response = createLogMessage("CopyQ client", exceptionText, LogError).toUtf8(); exitCode = CommandError; } else { response = serializeScriptValue(result); exitCode = CommandFinished; } } } scriptable.sendMessageToClient(response, exitCode); MONITOR_LOG("finished"); }
void tst_QScriptJSTestSuite::runTestFunction(int testIndex) { if (!(testIndex & 1)) { // data QTest::addColumn<TestRecord>("record"); bool hasData = false; QString testsShellPath = testsDir.absoluteFilePath("shell.js"); QString testsShellContents = readFile(testsShellPath); QDir subSuiteDir(subSuitePaths.at(testIndex / 2)); QString subSuiteShellPath = subSuiteDir.absoluteFilePath("shell.js"); QString subSuiteShellContents = readFile(subSuiteShellPath); QDir testSuiteDir(subSuiteDir); testSuiteDir.cdUp(); QString suiteJsrefPath = testSuiteDir.absoluteFilePath("jsref.js"); QString suiteJsrefContents = readFile(suiteJsrefPath); QString suiteShellPath = testSuiteDir.absoluteFilePath("shell.js"); QString suiteShellContents = readFile(suiteShellPath); QFileInfoList testFileInfos = subSuiteDir.entryInfoList(QStringList() << "*.js", QDir::Files); foreach (QFileInfo tfi, testFileInfos) { if ((tfi.fileName() == "shell.js") || (tfi.fileName() == "browser.js")) continue; QString abspath = tfi.absoluteFilePath(); QString relpath = testsDir.relativeFilePath(abspath); QString excludeMessage; if (isExcludedFile(relpath, &excludeMessage)) { QTest::newRow(relpath.toLatin1()) << TestRecord(excludeMessage, relpath); continue; } QScriptEngine eng; QScriptValue global = eng.globalObject(); global.setProperty("print", eng.newFunction(qscript_void)); global.setProperty("quit", eng.newFunction(qscript_quit)); global.setProperty("options", eng.newFunction(qscript_options)); eng.evaluate(testsShellContents, testsShellPath); if (eng.hasUncaughtException()) { QStringList bt = eng.uncaughtExceptionBacktrace(); QString err = eng.uncaughtException().toString(); qWarning("%s\n%s", qPrintable(err), qPrintable(bt.join("\n"))); break; } eng.evaluate(suiteJsrefContents, suiteJsrefPath); if (eng.hasUncaughtException()) { QStringList bt = eng.uncaughtExceptionBacktrace(); QString err = eng.uncaughtException().toString(); qWarning("%s\n%s", qPrintable(err), qPrintable(bt.join("\n"))); break; } eng.evaluate(suiteShellContents, suiteShellPath); if (eng.hasUncaughtException()) { QStringList bt = eng.uncaughtExceptionBacktrace(); QString err = eng.uncaughtException().toString(); qWarning("%s\n%s", qPrintable(err), qPrintable(bt.join("\n"))); break; } eng.evaluate(subSuiteShellContents, subSuiteShellPath); if (eng.hasUncaughtException()) { QStringList bt = eng.uncaughtExceptionBacktrace(); QString err = eng.uncaughtException().toString(); qWarning("%s\n%s", qPrintable(err), qPrintable(bt.join("\n"))); break; } QScriptValue origTestCaseCtor = global.property("TestCase"); QScriptValue myTestCaseCtor = eng.newFunction(qscript_TestCase); myTestCaseCtor.setData(origTestCaseCtor); global.setProperty("TestCase", myTestCaseCtor); global.setProperty("gTestfile", tfi.fileName()); global.setProperty("gTestsuite", testSuiteDir.dirName()); global.setProperty("gTestsubsuite", subSuiteDir.dirName()); QString testFileContents = readFile(abspath); // qDebug() << relpath; eng.evaluate(testFileContents, abspath); if (eng.hasUncaughtException() && !relpath.endsWith("-n.js")) { QStringList bt = eng.uncaughtExceptionBacktrace(); QString err = eng.uncaughtException().toString(); qWarning("%s\n%s\n", qPrintable(err), qPrintable(bt.join("\n"))); continue; } QScriptValue testcases = global.property("testcases"); if (!testcases.isArray()) testcases = global.property("gTestcases"); int count = testcases.property("length").toInt32(); if (count == 0) continue; hasData = true; QString title = global.property("TITLE").toString(); for (int i = 0; i < count; ++i) { QScriptValue kase = testcases.property(i); QString description = kase.property("description").toString(); QScriptValue expect = kase.property("expect"); QScriptValue actual = kase.property("actual"); bool passed = kase.property("passed").toBoolean(); int lineNumber = kase.property("__lineNumber__").toInt32(); TestRecord rec(description, passed, actual.toString(), expect.toString(), relpath, lineNumber); QTest::newRow(description.toLatin1()) << rec; } } if (!hasData) QTest::newRow("") << TestRecord(); // dummy } else {
void ScriptableWorker::run() { if ( hasLogLevel(LogDebug) ) { bool isEval = m_args.length() == Arguments::Rest + 2 && m_args.at(Arguments::Rest) == "eval"; for (int i = Arguments::Rest + (isEval ? 1 : 0); i < m_args.length(); ++i) { QString indent = isEval ? QString("EVAL:") : (QString::number(i - Arguments::Rest + 1) + " "); foreach (const QByteArray &line, m_args.at(i).split('\n')) { SCRIPT_LOG( indent + getTextData(line) ); indent = " "; } } } bool hasData; const quintptr id = m_args.at(Arguments::ActionId).toULongLong(&hasData); QVariantMap data; if (hasData) data = Action::data(id); const QString currentPath = getTextData(m_args.at(Arguments::CurrentPath)); QScriptEngine engine; ScriptableProxy proxy(m_wnd, data); Scriptable scriptable(&proxy); scriptable.initEngine(&engine, currentPath, data); if (m_socket) { QObject::connect( proxy.signaler(), SIGNAL(sendMessage(QByteArray,int)), m_socket, SLOT(sendMessage(QByteArray,int)) ); QObject::connect( &scriptable, SIGNAL(sendMessage(QByteArray,int)), m_socket, SLOT(sendMessage(QByteArray,int)) ); QObject::connect( m_socket, SIGNAL(messageReceived(QByteArray,int)), &scriptable, SLOT(setInput(QByteArray)) ); QObject::connect( m_socket, SIGNAL(disconnected()), &scriptable, SLOT(abort()) ); QObject::connect( &scriptable, SIGNAL(destroyed()), m_socket, SLOT(deleteAfterDisconnected()) ); if ( m_socket->isClosed() ) { SCRIPT_LOG("TERMINATED"); return; } m_socket->start(); } QObject::connect( &scriptable, SIGNAL(requestApplicationQuit()), qApp, SLOT(quit()) ); QByteArray response; int exitCode; if ( m_args.length() <= Arguments::Rest ) { SCRIPT_LOG("Error: bad command syntax"); exitCode = CommandBadSyntax; } else { const QString cmd = getTextData( m_args.at(Arguments::Rest) ); #ifdef HAS_TESTS if ( cmd == "flush" && m_args.length() == Arguments::Rest + 2 ) { log( "flush ID: " + getTextData(m_args.at(Arguments::Rest + 1)), LogAlways ); scriptable.sendMessageToClient(QByteArray(), CommandFinished); return; } #endif QScriptValue fn = engine.globalObject().property(cmd); if ( !fn.isFunction() ) { SCRIPT_LOG("Error: unknown command"); const QString msg = Scriptable::tr("Name \"%1\" doesn't refer to a function.").arg(cmd); response = createLogMessage(msg, LogError).toUtf8(); exitCode = CommandError; } else { /* Special arguments: * "-" read this argument from stdin * "--" read all following arguments without control sequences */ QScriptValueList fnArgs; bool readRaw = false; for ( int i = Arguments::Rest + 1; i < m_args.length(); ++i ) { const QByteArray &arg = m_args.at(i); if (!readRaw && arg == "--") { readRaw = true; } else { const QScriptValue value = readRaw || arg != "-" ? scriptable.newByteArray(arg) : scriptable.input(); fnArgs.append(value); } } engine.evaluate(m_pluginScript); QScriptValue result = fn.call(QScriptValue(), fnArgs); if ( engine.hasUncaughtException() ) { const QString exceptionText = QString("%1\n--- backtrace ---\n%2\n--- end backtrace ---") .arg( engine.uncaughtException().toString(), engine.uncaughtExceptionBacktrace().join("\n") ); SCRIPT_LOG( QString("Error: Exception in command \"%1\": %2") .arg(cmd, exceptionText) ); response = createLogMessage(exceptionText, LogError).toUtf8(); exitCode = CommandError; } else { response = serializeScriptValue(result); exitCode = CommandFinished; } } } if (exitCode == CommandFinished && hasData) Action::setData(id, scriptable.data()); scriptable.sendMessageToClient(response, exitCode); SCRIPT_LOG("DONE"); }
void Agent::run() { NodeList* nodeList = NodeList::getInstance(); nodeList->setOwnerType(NODE_TYPE_AGENT); const char AGENT_NODE_TYPES_OF_INTEREST[2] = { NODE_TYPE_VOXEL_SERVER, NODE_TYPE_AUDIO_MIXER }; nodeList->setNodeTypesOfInterest(AGENT_NODE_TYPES_OF_INTEREST, sizeof(AGENT_NODE_TYPES_OF_INTEREST)); nodeList->getNodeSocket()->setBlocking(false); // figure out the URL for the script for this agent assignment QString scriptURLString("http://%1:8080/assignment/%2"); scriptURLString = scriptURLString.arg(NodeList::getInstance()->getDomainIP().toString(), uuidStringWithoutCurlyBraces(_uuid)); // setup curl for script download CURLcode curlResult; CURL* curlHandle = curl_easy_init(); // tell curl which file to grab curl_easy_setopt(curlHandle, CURLOPT_URL, scriptURLString.toStdString().c_str()); // send the data to the WriteMemoryCallback function curl_easy_setopt(curlHandle, CURLOPT_WRITEFUNCTION, writeScriptDataToString); QString scriptContents; // pass the scriptContents QString to append data to curl_easy_setopt(curlHandle, CURLOPT_WRITEDATA, (void *)&scriptContents); // send a user agent since some servers will require it curl_easy_setopt(curlHandle, CURLOPT_USERAGENT, "libcurl-agent/1.0"); // make sure CURL fails on a 400 code curl_easy_setopt(curlHandle, CURLOPT_FAILONERROR, true); qDebug() << "Downloading script at" << scriptURLString << "\n"; // blocking get for JS file curlResult = curl_easy_perform(curlHandle); if (curlResult == CURLE_OK) { // cleanup curl curl_easy_cleanup(curlHandle); curl_global_cleanup(); QScriptEngine engine; // register meta-type for glm::vec3 conversions qScriptRegisterMetaType(&engine, vec3toScriptValue, vec3FromScriptValue); QScriptValue agentValue = engine.newQObject(this); engine.globalObject().setProperty("Agent", agentValue); VoxelScriptingInterface voxelScripter; QScriptValue voxelScripterValue = engine.newQObject(&voxelScripter); engine.globalObject().setProperty("Voxels", voxelScripterValue); QScriptValue treeScaleValue = engine.newVariant(QVariant(TREE_SCALE)); engine.globalObject().setProperty("TREE_SCALE", treeScaleValue); // let the VoxelPacketSender know how frequently we plan to call it voxelScripter.getVoxelPacketSender()->setProcessCallIntervalHint(INJECT_INTERVAL_USECS); // hook in a constructor for audio injectorss AudioInjector scriptedAudioInjector(BUFFER_LENGTH_SAMPLES_PER_CHANNEL); QScriptValue audioInjectorValue = engine.newQObject(&scriptedAudioInjector); engine.globalObject().setProperty("AudioInjector", audioInjectorValue); qDebug() << "Downloaded script:" << scriptContents << "\n"; QScriptValue result = engine.evaluate(scriptContents); qDebug() << "Evaluated script.\n"; if (engine.hasUncaughtException()) { int line = engine.uncaughtExceptionLineNumber(); qDebug() << "Uncaught exception at line" << line << ":" << result.toString() << "\n"; } timeval startTime; gettimeofday(&startTime, NULL); timeval lastDomainServerCheckIn = {}; sockaddr_in senderAddress; unsigned char receivedData[MAX_PACKET_SIZE]; ssize_t receivedBytes; int thisFrame = 0; NodeList::getInstance()->startSilentNodeRemovalThread(); while (!_shouldStop) { // if we're not hearing from the domain-server we should stop running if (NodeList::getInstance()->getNumNoReplyDomainCheckIns() == MAX_SILENT_DOMAIN_SERVER_CHECK_INS) { break; } // send a check in packet to the domain server if DOMAIN_SERVER_CHECK_IN_USECS has elapsed if (usecTimestampNow() - usecTimestamp(&lastDomainServerCheckIn) >= DOMAIN_SERVER_CHECK_IN_USECS) { gettimeofday(&lastDomainServerCheckIn, NULL); NodeList::getInstance()->sendDomainServerCheckIn(); } // find the audio-mixer in the NodeList so we can inject audio at it Node* audioMixer = NodeList::getInstance()->soloNodeOfType(NODE_TYPE_AUDIO_MIXER); if (audioMixer && audioMixer->getActiveSocket()) { emit willSendAudioDataCallback(); } int usecToSleep = usecTimestamp(&startTime) + (thisFrame++ * INJECT_INTERVAL_USECS) - usecTimestampNow(); if (usecToSleep > 0) { usleep(usecToSleep); } if (audioMixer && audioMixer->getActiveSocket() && scriptedAudioInjector.hasSamplesToInject()) { // we have an audio mixer and samples to inject, send those off scriptedAudioInjector.injectAudio(NodeList::getInstance()->getNodeSocket(), audioMixer->getActiveSocket()); // clear out the audio injector so that it doesn't re-send what we just sent scriptedAudioInjector.clear(); } if (audioMixer && !audioMixer->getActiveSocket()) { // don't have an active socket for the audio-mixer, ping it now NodeList::getInstance()->pingPublicAndLocalSocketsForInactiveNode(audioMixer); } if (voxelScripter.getVoxelPacketSender()->voxelServersExist()) { // allow the scripter's call back to setup visual data emit willSendVisualDataCallback(); // release the queue of edit voxel messages. voxelScripter.getVoxelPacketSender()->releaseQueuedMessages(); // since we're in non-threaded mode, call process so that the packets are sent voxelScripter.getVoxelPacketSender()->process(); } if (engine.hasUncaughtException()) { int line = engine.uncaughtExceptionLineNumber(); qDebug() << "Uncaught exception at line" << line << ":" << engine.uncaughtException().toString() << "\n"; } while (NodeList::getInstance()->getNodeSocket()->receive((sockaddr*) &senderAddress, receivedData, &receivedBytes) && packetVersionMatch(receivedData)) { if (receivedData[0] == PACKET_TYPE_VOXEL_JURISDICTION) { voxelScripter.getJurisdictionListener()->queueReceivedPacket((sockaddr&) senderAddress, receivedData, receivedBytes); } else { NodeList::getInstance()->processNodeData((sockaddr*) &senderAddress, receivedData, receivedBytes); } } } NodeList::getInstance()->stopSilentNodeRemovalThread(); } else { // error in curl_easy_perform qDebug() << "curl_easy_perform for JS failed:" << curl_easy_strerror(curlResult) << "\n"; // cleanup curl curl_easy_cleanup(curlHandle); curl_global_cleanup(); } }