Example #1
0
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;
}
Example #2
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();
}
Example #3
0
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();
}
Example #4
0
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
}
Example #5
0
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;
}
Example #6
0
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);
            }
        }
    }
}
Example #8
0
 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();
 }
Example #9
0
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();
}
Example #10
0
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;
}
Example #11
0
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();
}
Example #12
0
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;
	}
}
Example #13
0
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();
}
Example #14
0
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();
}
Example #16
0
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 {
Example #18
0
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");
}
Example #19
0
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();
    }
}