<commit_before>#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <Engine/MainWindow.hpp>
#include "Editor.hpp"
#include "Util/EditorSettings.hpp"
#include <Engine/Util/Input.hpp>
#include <Engine/Util/FileSystem.hpp>
#include <Utility/Log.hpp>
#include <Engine/Input/Input.hpp>
#include <Engine/Manager/Managers.hpp>
#include <Engine/Manager/ScriptManager.hpp>
#include <Engine/Manager/ProfilingManager.hpp>
#include <Engine/Manager/ParticleManager.hpp>
#include <Engine/Manager/DebugDrawingManager.hpp>
#include <Engine/Util/Profiling.hpp>
#include <Engine/Util/GPUProfiling.hpp>
#include <Engine/Hymn.hpp>
#include <thread>
#include "ImGui/OpenGLImplementation.hpp"
#include <imgui.h>
#include "GUI/ProfilingWindow.hpp"
#include <iostream>

#ifdef USINGMEMTRACK
#include <MemTrackInclude.hpp>
#endif

int main() {
    Log().SetupStreams(&std::cout, &std::cout, &std::cout, &std::cerr);

    // Enable logging if requested.
    if (EditorSettings::GetInstance().GetBool("Logging")){
        FILE* file = freopen(FileSystem::DataPath("Hymn to Beauty", "log.txt").c_str(), "a", stderr);
        if (file == nullptr)
            Log() << "Could not open logging file!\n";
    }

    Log() << "Editor started - " << time(nullptr) << "\n";

    if (!glfwInit())
        return 1;

    MainWindow* window = new MainWindow(EditorSettings::GetInstance().GetLong("Width"), EditorSettings::GetInstance().GetLong("Height"), false, false, "Hymn to Beauty", EditorSettings::GetInstance().GetBool("Debug Context"));

    glewInit();
    window->Init(false);

    Input::GetInstance().SetWindow(window->GetGLFWWindow());

    Managers().StartUp();

    Editor* editor = new Editor();
    // Setup imgui implementation.
    ImGuiImplementation::Init(window->GetGLFWWindow());

    bool profiling = false;
    GUI::ProfilingWindow profilingWindow;

    // Main loop.
    double targetFPS = 60.0;
    double lastTime = glfwGetTime();
    double lastTimeRender = glfwGetTime();
    while (!window->ShouldClose() || !editor->ReadyToClose()) {
        float deltaTime = static_cast<float>(glfwGetTime() - lastTime);
        lastTime = glfwGetTime();

        Managers().profilingManager->SetActive(profiling);

        // Begin new profiling frame.
        if (Managers().profilingManager->Active())
            Managers().profilingManager->BeginFrame();

        { PROFILE("Frame");
        { GPUPROFILE("Frame", Video::Query::Type::TIME_ELAPSED);

            glfwPollEvents();

            if (Input()->Triggered(InputHandler::WINDOWMODE)) {
                bool fullscreen, borderless;
                window->GetWindowMode(fullscreen, borderless);
                window->SetWindowMode(!fullscreen, borderless);
            }

            if (Input()->Triggered(InputHandler::PROFILE))
                profiling = !profiling;

            // Start new frame.
            ImGuiImplementation::NewFrame();

            window->Update();

            if (editor->IsVisible()) {
                Hymn().world.ClearKilled();
                Managers().particleManager->Update(Hymn().world, deltaTime, true);

                Managers().debugDrawingManager->Update(deltaTime);
                Hymn().Render(editor->GetCamera(),
                              EditorSettings::GetInstance().GetBool("Sound Source Icons"),
                              EditorSettings::GetInstance().GetBool("Particle Emitter Icons"),
                              EditorSettings::GetInstance().GetBool("Light Source Icons"),
                              EditorSettings::GetInstance().GetBool("Camera Icons"),
                              EditorSettings::GetInstance().GetBool("Physics Volumes"),
                              EditorSettings::GetInstance().GetBool("Lighting"));

                if (window->ShouldClose())
                    editor->Close();

                editor->Show(deltaTime);

                if (window->ShouldClose() && !editor->isClosing())
                    window->CancelClose();

            } else {
                { PROFILE("Update");
                { GPUPROFILE("Update", Video::Query::Type::TIME_ELAPSED);
                    Hymn().Update(deltaTime);
                }
                }

                { PROFILE("Render");
                { GPUPROFILE("Render", Video::Query::Type::TIME_ELAPSED);
                    Hymn().Render();
                }
                }

                if (Input()->Triggered(InputHandler::PLAYTEST)) {
                    // Rollback to the editor state.
                    editor->LoadSceneState();

                    // Turn editor back on.
                    editor->SetVisible(true);
                }
            }
        }
        }

        if (Managers().profilingManager->Active()) {
            Managers().profilingManager->EndFrame();
            profilingWindow.Show();
        }

        ImGui::Render();

        // Swap buffers and wait until next frame.
        window->SwapBuffers();

        long wait = static_cast<long>((1.0 / targetFPS + lastTimeRender - glfwGetTime()) * 1000000.0);
        if (wait > 0)
            std::this_thread::sleep_for(std::chrono::microseconds(wait));
        lastTimeRender = glfwGetTime();
    }
#ifdef USINGMEMTRACK
    MemTrack::TrackListMemoryUsage();
#endif
    // Save editor settings.
    EditorSettings::GetInstance().Save();

    // Shut down and cleanup.
    ImGuiImplementation::Shutdown();
    delete editor;
    Hymn().world.Clear();

    Managers().ShutDown();

    delete window;
    glfwTerminate();

    Log() << "Editor ended - " << time(nullptr) << "\n";

    return 0;
}
<commit_msg>Clear world after managers has destroyed so that managers can clean up dependencies on other components properly.<commit_after>#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <Engine/MainWindow.hpp>
#include "Editor.hpp"
#include "Util/EditorSettings.hpp"
#include <Engine/Util/Input.hpp>
#include <Engine/Util/FileSystem.hpp>
#include <Utility/Log.hpp>
#include <Engine/Input/Input.hpp>
#include <Engine/Manager/Managers.hpp>
#include <Engine/Manager/ScriptManager.hpp>
#include <Engine/Manager/ProfilingManager.hpp>
#include <Engine/Manager/ParticleManager.hpp>
#include <Engine/Manager/DebugDrawingManager.hpp>
#include <Engine/Util/Profiling.hpp>
#include <Engine/Util/GPUProfiling.hpp>
#include <Engine/Hymn.hpp>
#include <thread>
#include "ImGui/OpenGLImplementation.hpp"
#include <imgui.h>
#include "GUI/ProfilingWindow.hpp"
#include <iostream>

#ifdef USINGMEMTRACK
#include <MemTrackInclude.hpp>
#endif

int main() {
    Log().SetupStreams(&std::cout, &std::cout, &std::cout, &std::cerr);

    // Enable logging if requested.
    if (EditorSettings::GetInstance().GetBool("Logging")){
        FILE* file = freopen(FileSystem::DataPath("Hymn to Beauty", "log.txt").c_str(), "a", stderr);
        if (file == nullptr)
            Log() << "Could not open logging file!\n";
    }

    Log() << "Editor started - " << time(nullptr) << "\n";

    if (!glfwInit())
        return 1;

    MainWindow* window = new MainWindow(EditorSettings::GetInstance().GetLong("Width"), EditorSettings::GetInstance().GetLong("Height"), false, false, "Hymn to Beauty", EditorSettings::GetInstance().GetBool("Debug Context"));

    glewInit();
    window->Init(false);

    Input::GetInstance().SetWindow(window->GetGLFWWindow());

    Managers().StartUp();

    Editor* editor = new Editor();
    // Setup imgui implementation.
    ImGuiImplementation::Init(window->GetGLFWWindow());

    bool profiling = false;
    GUI::ProfilingWindow profilingWindow;

    // Main loop.
    double targetFPS = 60.0;
    double lastTime = glfwGetTime();
    double lastTimeRender = glfwGetTime();
    while (!window->ShouldClose() || !editor->ReadyToClose()) {
        float deltaTime = static_cast<float>(glfwGetTime() - lastTime);
        lastTime = glfwGetTime();

        Managers().profilingManager->SetActive(profiling);

        // Begin new profiling frame.
        if (Managers().profilingManager->Active())
            Managers().profilingManager->BeginFrame();

        { PROFILE("Frame");
        { GPUPROFILE("Frame", Video::Query::Type::TIME_ELAPSED);

            glfwPollEvents();

            if (Input()->Triggered(InputHandler::WINDOWMODE)) {
                bool fullscreen, borderless;
                window->GetWindowMode(fullscreen, borderless);
                window->SetWindowMode(!fullscreen, borderless);
            }

            if (Input()->Triggered(InputHandler::PROFILE))
                profiling = !profiling;

            // Start new frame.
            ImGuiImplementation::NewFrame();

            window->Update();

            if (editor->IsVisible()) {
                Hymn().world.ClearKilled();
                Managers().particleManager->Update(Hymn().world, deltaTime, true);

                Managers().debugDrawingManager->Update(deltaTime);
                Hymn().Render(editor->GetCamera(),
                              EditorSettings::GetInstance().GetBool("Sound Source Icons"),
                              EditorSettings::GetInstance().GetBool("Particle Emitter Icons"),
                              EditorSettings::GetInstance().GetBool("Light Source Icons"),
                              EditorSettings::GetInstance().GetBool("Camera Icons"),
                              EditorSettings::GetInstance().GetBool("Physics Volumes"),
                              EditorSettings::GetInstance().GetBool("Lighting"));

                if (window->ShouldClose())
                    editor->Close();

                editor->Show(deltaTime);

                if (window->ShouldClose() && !editor->isClosing())
                    window->CancelClose();

            } else {
                { PROFILE("Update");
                { GPUPROFILE("Update", Video::Query::Type::TIME_ELAPSED);
                    Hymn().Update(deltaTime);
                }
                }

                { PROFILE("Render");
                { GPUPROFILE("Render", Video::Query::Type::TIME_ELAPSED);
                    Hymn().Render();
                }
                }

                if (Input()->Triggered(InputHandler::PLAYTEST)) {
                    // Rollback to the editor state.
                    editor->LoadSceneState();

                    // Turn editor back on.
                    editor->SetVisible(true);
                }
            }
        }
        }

        if (Managers().profilingManager->Active()) {
            Managers().profilingManager->EndFrame();
            profilingWindow.Show();
        }

        ImGui::Render();

        // Swap buffers and wait until next frame.
        window->SwapBuffers();

        long wait = static_cast<long>((1.0 / targetFPS + lastTimeRender - glfwGetTime()) * 1000000.0);
        if (wait > 0)
            std::this_thread::sleep_for(std::chrono::microseconds(wait));
        lastTimeRender = glfwGetTime();
    }
#ifdef USINGMEMTRACK
    MemTrack::TrackListMemoryUsage();
#endif
    // Save editor settings.
    EditorSettings::GetInstance().Save();

    // Shut down and cleanup.
    ImGuiImplementation::Shutdown();
    delete editor;

    Managers().ShutDown();
    Hymn().world.Clear();

    delete window;
    glfwTerminate();

    Log() << "Editor ended - " << time(nullptr) << "\n";

    return 0;
}
<|endoftext|>


<commit_before>/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qbs.
**
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "tst_blackboxbase.h"

#include "../shared.h"

#include <tools/fileinfo.h>
#include <tools/hostosinfo.h>
#include <tools/installoptions.h>
#include <tools/profile.h>

#include <QtCore/qdiriterator.h>
#include <QtCore/qjsondocument.h>
#include <QtCore/qtemporarydir.h>

using qbs::Internal::HostOsInfo;
using qbs::Internal::removeDirectoryWithContents;
using qbs::InstallOptions;
using qbs::Profile;

static QString initQbsExecutableFilePath()
{
    const QString qbsInstallDir = QString::fromLocal8Bit(qgetenv("QBS_INSTALL_DIR"));
    return HostOsInfo::appendExecutableSuffix(QDir::cleanPath(!qbsInstallDir.isEmpty()
        ? qbsInstallDir + QLatin1String("/bin/qbs")
        : QCoreApplication::applicationDirPath() + QLatin1String("/qbs")));
}

static bool supportsBuildDirectoryOption(const QString &command) {
    return !(QStringList() << "help" << "config" << "config-ui"
             << "setup-android" << "setup-qt" << "setup-toolchains" << "create-project")
            .contains(command);
}

static bool supportsSettingsDirOption(const QString &command) {
    return !(QStringList() << "help" << "create-project").contains(command);
}

TestBlackboxBase::TestBlackboxBase(const QString &testDataSrcDir, const QString &testName)
    : testDataDir(testWorkDir(testName)),
      testSourceDir(testDataSourceDir(testDataSrcDir)),
      qbsExecutableFilePath(initQbsExecutableFilePath()),
      defaultInstallRoot(relativeBuildDir() + QLatin1Char('/') + InstallOptions::defaultInstallRoot())
{
    QLocale::setDefault(QLocale::c());
}

int TestBlackboxBase::runQbs(const QbsRunParameters &params)
{
    QStringList args;
    if (!params.command.isEmpty())
        args << params.command;
    if (!params.settingsDir.isEmpty() && supportsSettingsDirOption(params.command))
        args << "--settings-dir" << params.settingsDir;
    if (supportsBuildDirectoryOption(params.command)) {
        args.push_back(QStringLiteral("-d"));
        args.push_back(params.buildDirectory.isEmpty()
                       ? QStringLiteral(".")
                       : params.buildDirectory);
    }
    args << params.arguments;
    const bool commandImpliesResolve = params.command.isEmpty() || params.command == "resolve"
            || params.command == "build" || params.command == "install" || params.command == "run"
            || params.command == "generate";
    if (!params.profile.isEmpty() && commandImpliesResolve) {
        args.push_back(QLatin1String("profile:") + params.profile);
    }
    QProcess process;
    if (!params.workingDir.isEmpty())
        process.setWorkingDirectory(params.workingDir);
    process.setProcessEnvironment(params.environment);
    process.start(qbsExecutableFilePath, args);
    if (!process.waitForStarted() || !process.waitForFinished(testTimeoutInMsecs())
            || process.exitStatus() != QProcess::NormalExit) {
        m_qbsStderr = process.readAllStandardError();
        if (!params.expectCrash) {
            QTest::qFail("qbs did not run correctly", __FILE__, __LINE__);
            qDebug("%s", qPrintable(process.errorString()));
        }
        return -1;
    }

    m_qbsStderr = process.readAllStandardError();
    m_qbsStdout = process.readAllStandardOutput();
    sanitizeOutput(&m_qbsStderr);
    sanitizeOutput(&m_qbsStdout);
    const bool shouldLog = (process.exitStatus() != QProcess::NormalExit
            || process.exitCode() != 0) && !params.expectFailure;
    if (!m_qbsStderr.isEmpty()
            && (shouldLog || qEnvironmentVariableIsSet("QBS_AUTOTEST_ALWAYS_LOG_STDERR")))
        qDebug("%s", m_qbsStderr.constData());
    if (!m_qbsStdout.isEmpty()
            && (shouldLog || qEnvironmentVariableIsSet("QBS_AUTOTEST_ALWAYS_LOG_STDOUT")))
        qDebug("%s", m_qbsStdout.constData());
    return process.exitCode();
}

/*!
  Recursive copy from directory to another.
  Note that this updates the file stamps on Linux but not on Windows.
  */
void TestBlackboxBase::ccp(const QString &sourceDirPath, const QString &targetDirPath)
{
    QDir currentDir;
    QDirIterator dit(sourceDirPath, QDir::Dirs | QDir::NoDotAndDotDot | QDir::Hidden);
    while (dit.hasNext()) {
        dit.next();
        const QString targetPath = targetDirPath + QLatin1Char('/') + dit.fileName();
        currentDir.mkpath(targetPath);
        ccp(dit.filePath(), targetPath);
    }

    QDirIterator fit(sourceDirPath, QDir::Files | QDir::Hidden);
    while (fit.hasNext()) {
        fit.next();
        const QString targetPath = targetDirPath + QLatin1Char('/') + fit.fileName();
        QFile::remove(targetPath);  // allowed to fail
        QFile src(fit.filePath());
        QVERIFY2(src.copy(targetPath), qPrintable(src.errorString()));
    }
}

void TestBlackboxBase::rmDirR(const QString &dir)
{
    QString errorMessage;
    removeDirectoryWithContents(dir, &errorMessage);
}

QByteArray TestBlackboxBase::unifiedLineEndings(const QByteArray &ba)
{
    if (HostOsInfo::isWindowsHost()) {
        QByteArray result;
        result.reserve(ba.size());
        for (const char &c : ba) {
            if (c != '\r')
                result.append(c);
        }
        return result;
    } else {
        return ba;
    }
}

void TestBlackboxBase::sanitizeOutput(QByteArray *ba)
{
    if (HostOsInfo::isWindowsHost())
        ba->replace('\r', "");
}

void TestBlackboxBase::initTestCase()
{
    QVERIFY(regularFileExists(qbsExecutableFilePath));

    const SettingsPtr s = settings();
    if (profileName() != "none" && !s->profiles().contains(profileName()))
        QFAIL(QByteArray("The build profile '" + profileName().toLocal8Bit() +
                         "' could not be found. Please set it up on your machine."));

    validateTestProfile();

    // Initialize the test data directory.
    QVERIFY(testDataDir != testSourceDir);
    rmDirR(testDataDir);
    QDir().mkpath(testDataDir);
    ccp(testSourceDir, testDataDir);
    QDir().mkpath(testDataDir + "/find");
    ccp(testSourceDir + "/../find", testDataDir + "/find");
    QVERIFY(copyDllExportHeader(testSourceDir, testDataDir));
}

void TestBlackboxBase::validateTestProfile()
{
    const SettingsPtr s = settings();
    if (profileName() != "none" && !s->profiles().contains(profileName()))
        QFAIL(QByteArray("The build profile '" + profileName().toLocal8Bit() +
                         "' could not be found. Please set it up on your machine."));
    if (!m_needsQt)
        return;
    const QStringList qmakeFilePaths = Profile(profileName(), s.get())
            .value("moduleProviders.Qt.qmakeFilePaths").toStringList();
    if (!qmakeFilePaths.empty())
        return;
    if (!findExecutable(QStringList{"qmake"}).isEmpty())
        return;
    QSKIP(QByteArray("The build profile '" + profileName().toLocal8Bit() +
                     "' is not a valid Qt profile and Qt was not found "
                     "in the global search paths."));

}

QString TestBlackboxBase::findExecutable(const QStringList &fileNames)
{
    const QStringList path = QString::fromLocal8Bit(qgetenv("PATH"))
            .split(HostOsInfo::pathListSeparator(), QBS_SKIP_EMPTY_PARTS);

    for (const QString &fileName : fileNames) {
        QFileInfo fi(fileName);
        if (fi.isAbsolute())
            return fi.exists() ? fileName : QString();
        for (const QString &ppath : path) {
            const QString fullPath
                    = HostOsInfo::appendExecutableSuffix(ppath + QLatin1Char('/') + fileName);
            if (QFileInfo(fullPath).exists())
                return QDir::cleanPath(fullPath);
        }
    }
    return {};
}

QMap<QString, QString> TestBlackboxBase::findJdkTools(int *status)
{
    QTemporaryDir temp;
    QDir::setCurrent(testDataDir + "/find");
    QbsRunParameters params = QStringList() << "-f" << "find-jdk.qbs";
    params.buildDirectory = temp.path();
    const int res = runQbs(params);
    if (status)
        *status = res;
    QFile file(temp.path() + "/" + relativeProductBuildDir("find-jdk") + "/jdk.json");
    if (!file.open(QIODevice::ReadOnly))
        return {};
    const auto tools = QJsonDocument::fromJson(file.readAll()).toVariant().toMap();
    return {
        {"java", QDir::fromNativeSeparators(tools["java"].toString())},
        {"javac", QDir::fromNativeSeparators(tools["javac"].toString())},
        {"jar", QDir::fromNativeSeparators(tools["jar"].toString())}
    };
}

qbs::Version TestBlackboxBase::qmakeVersion(const QString &qmakeFilePath)
{
    QStringList arguments;
    arguments << "-query" << "QT_VERSION";
    QProcess qmakeProcess;
    qmakeProcess.start(qmakeFilePath, arguments);
    if (!qmakeProcess.waitForStarted() || !qmakeProcess.waitForFinished()
        || qmakeProcess.exitStatus() != QProcess::NormalExit) {
        qDebug() << "qmake '" << qmakeFilePath << "' could not be run.";
        return qbs::Version();
    }
    QByteArray result = qmakeProcess.readAll().simplified();
    qbs::Version version = qbs::Version::fromString(result);
    if (!version.isValid())
        qDebug() << "qmake '" << qmakeFilePath << "' version is not valid.";
    return version;
}
<commit_msg>Print stderr and stdout in case of error<commit_after>/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qbs.
**
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "tst_blackboxbase.h"

#include "../shared.h"

#include <tools/fileinfo.h>
#include <tools/hostosinfo.h>
#include <tools/installoptions.h>
#include <tools/profile.h>

#include <QtCore/qdiriterator.h>
#include <QtCore/qjsondocument.h>
#include <QtCore/qtemporarydir.h>

using qbs::Internal::HostOsInfo;
using qbs::Internal::removeDirectoryWithContents;
using qbs::InstallOptions;
using qbs::Profile;

static QString initQbsExecutableFilePath()
{
    const QString qbsInstallDir = QString::fromLocal8Bit(qgetenv("QBS_INSTALL_DIR"));
    return HostOsInfo::appendExecutableSuffix(QDir::cleanPath(!qbsInstallDir.isEmpty()
        ? qbsInstallDir + QLatin1String("/bin/qbs")
        : QCoreApplication::applicationDirPath() + QLatin1String("/qbs")));
}

static bool supportsBuildDirectoryOption(const QString &command) {
    return !(QStringList() << "help" << "config" << "config-ui"
             << "setup-android" << "setup-qt" << "setup-toolchains" << "create-project")
            .contains(command);
}

static bool supportsSettingsDirOption(const QString &command) {
    return !(QStringList() << "help" << "create-project").contains(command);
}

TestBlackboxBase::TestBlackboxBase(const QString &testDataSrcDir, const QString &testName)
    : testDataDir(testWorkDir(testName)),
      testSourceDir(testDataSourceDir(testDataSrcDir)),
      qbsExecutableFilePath(initQbsExecutableFilePath()),
      defaultInstallRoot(relativeBuildDir() + QLatin1Char('/') + InstallOptions::defaultInstallRoot())
{
    QLocale::setDefault(QLocale::c());
}

int TestBlackboxBase::runQbs(const QbsRunParameters &params)
{
    QStringList args;
    if (!params.command.isEmpty())
        args << params.command;
    if (!params.settingsDir.isEmpty() && supportsSettingsDirOption(params.command))
        args << "--settings-dir" << params.settingsDir;
    if (supportsBuildDirectoryOption(params.command)) {
        args.push_back(QStringLiteral("-d"));
        args.push_back(params.buildDirectory.isEmpty()
                       ? QStringLiteral(".")
                       : params.buildDirectory);
    }
    args << params.arguments;
    const bool commandImpliesResolve = params.command.isEmpty() || params.command == "resolve"
            || params.command == "build" || params.command == "install" || params.command == "run"
            || params.command == "generate";
    if (!params.profile.isEmpty() && commandImpliesResolve) {
        args.push_back(QLatin1String("profile:") + params.profile);
    }
    QProcess process;
    if (!params.workingDir.isEmpty())
        process.setWorkingDirectory(params.workingDir);
    process.setProcessEnvironment(params.environment);
    process.start(qbsExecutableFilePath, args);
    if (!process.waitForStarted() || !process.waitForFinished(testTimeoutInMsecs())
            || process.exitStatus() != QProcess::NormalExit) {
        m_qbsStderr = process.readAllStandardError();
        m_qbsStdout = process.readAllStandardOutput();
        if (!params.expectCrash) {
            QTest::qFail("qbs did not run correctly", __FILE__, __LINE__);
            qDebug("%s", qPrintable(process.errorString()));
            qDebug("%s", m_qbsStderr.constData());
            qDebug("%s", m_qbsStdout.constData());
        }
        return -1;
    }

    m_qbsStderr = process.readAllStandardError();
    m_qbsStdout = process.readAllStandardOutput();
    sanitizeOutput(&m_qbsStderr);
    sanitizeOutput(&m_qbsStdout);
    const bool shouldLog = (process.exitStatus() != QProcess::NormalExit
            || process.exitCode() != 0) && !params.expectFailure;
    if (!m_qbsStderr.isEmpty()
            && (shouldLog || qEnvironmentVariableIsSet("QBS_AUTOTEST_ALWAYS_LOG_STDERR")))
        qDebug("%s", m_qbsStderr.constData());
    if (!m_qbsStdout.isEmpty()
            && (shouldLog || qEnvironmentVariableIsSet("QBS_AUTOTEST_ALWAYS_LOG_STDOUT")))
        qDebug("%s", m_qbsStdout.constData());
    return process.exitCode();
}

/*!
  Recursive copy from directory to another.
  Note that this updates the file stamps on Linux but not on Windows.
  */
void TestBlackboxBase::ccp(const QString &sourceDirPath, const QString &targetDirPath)
{
    QDir currentDir;
    QDirIterator dit(sourceDirPath, QDir::Dirs | QDir::NoDotAndDotDot | QDir::Hidden);
    while (dit.hasNext()) {
        dit.next();
        const QString targetPath = targetDirPath + QLatin1Char('/') + dit.fileName();
        currentDir.mkpath(targetPath);
        ccp(dit.filePath(), targetPath);
    }

    QDirIterator fit(sourceDirPath, QDir::Files | QDir::Hidden);
    while (fit.hasNext()) {
        fit.next();
        const QString targetPath = targetDirPath + QLatin1Char('/') + fit.fileName();
        QFile::remove(targetPath);  // allowed to fail
        QFile src(fit.filePath());
        QVERIFY2(src.copy(targetPath), qPrintable(src.errorString()));
    }
}

void TestBlackboxBase::rmDirR(const QString &dir)
{
    QString errorMessage;
    removeDirectoryWithContents(dir, &errorMessage);
}

QByteArray TestBlackboxBase::unifiedLineEndings(const QByteArray &ba)
{
    if (HostOsInfo::isWindowsHost()) {
        QByteArray result;
        result.reserve(ba.size());
        for (const char &c : ba) {
            if (c != '\r')
                result.append(c);
        }
        return result;
    } else {
        return ba;
    }
}

void TestBlackboxBase::sanitizeOutput(QByteArray *ba)
{
    if (HostOsInfo::isWindowsHost())
        ba->replace('\r', "");
}

void TestBlackboxBase::initTestCase()
{
    QVERIFY(regularFileExists(qbsExecutableFilePath));

    const SettingsPtr s = settings();
    if (profileName() != "none" && !s->profiles().contains(profileName()))
        QFAIL(QByteArray("The build profile '" + profileName().toLocal8Bit() +
                         "' could not be found. Please set it up on your machine."));

    validateTestProfile();

    // Initialize the test data directory.
    QVERIFY(testDataDir != testSourceDir);
    rmDirR(testDataDir);
    QDir().mkpath(testDataDir);
    ccp(testSourceDir, testDataDir);
    QDir().mkpath(testDataDir + "/find");
    ccp(testSourceDir + "/../find", testDataDir + "/find");
    QVERIFY(copyDllExportHeader(testSourceDir, testDataDir));
}

void TestBlackboxBase::validateTestProfile()
{
    const SettingsPtr s = settings();
    if (profileName() != "none" && !s->profiles().contains(profileName()))
        QFAIL(QByteArray("The build profile '" + profileName().toLocal8Bit() +
                         "' could not be found. Please set it up on your machine."));
    if (!m_needsQt)
        return;
    const QStringList qmakeFilePaths = Profile(profileName(), s.get())
            .value("moduleProviders.Qt.qmakeFilePaths").toStringList();
    if (!qmakeFilePaths.empty())
        return;
    if (!findExecutable(QStringList{"qmake"}).isEmpty())
        return;
    QSKIP(QByteArray("The build profile '" + profileName().toLocal8Bit() +
                     "' is not a valid Qt profile and Qt was not found "
                     "in the global search paths."));

}

QString TestBlackboxBase::findExecutable(const QStringList &fileNames)
{
    const QStringList path = QString::fromLocal8Bit(qgetenv("PATH"))
            .split(HostOsInfo::pathListSeparator(), QBS_SKIP_EMPTY_PARTS);

    for (const QString &fileName : fileNames) {
        QFileInfo fi(fileName);
        if (fi.isAbsolute())
            return fi.exists() ? fileName : QString();
        for (const QString &ppath : path) {
            const QString fullPath
                    = HostOsInfo::appendExecutableSuffix(ppath + QLatin1Char('/') + fileName);
            if (QFileInfo(fullPath).exists())
                return QDir::cleanPath(fullPath);
        }
    }
    return {};
}

QMap<QString, QString> TestBlackboxBase::findJdkTools(int *status)
{
    QTemporaryDir temp;
    QDir::setCurrent(testDataDir + "/find");
    QbsRunParameters params = QStringList() << "-f" << "find-jdk.qbs";
    params.buildDirectory = temp.path();
    const int res = runQbs(params);
    if (status)
        *status = res;
    QFile file(temp.path() + "/" + relativeProductBuildDir("find-jdk") + "/jdk.json");
    if (!file.open(QIODevice::ReadOnly))
        return {};
    const auto tools = QJsonDocument::fromJson(file.readAll()).toVariant().toMap();
    return {
        {"java", QDir::fromNativeSeparators(tools["java"].toString())},
        {"javac", QDir::fromNativeSeparators(tools["javac"].toString())},
        {"jar", QDir::fromNativeSeparators(tools["jar"].toString())}
    };
}

qbs::Version TestBlackboxBase::qmakeVersion(const QString &qmakeFilePath)
{
    QStringList arguments;
    arguments << "-query" << "QT_VERSION";
    QProcess qmakeProcess;
    qmakeProcess.start(qmakeFilePath, arguments);
    if (!qmakeProcess.waitForStarted() || !qmakeProcess.waitForFinished()
        || qmakeProcess.exitStatus() != QProcess::NormalExit) {
        qDebug() << "qmake '" << qmakeFilePath << "' could not be run.";
        return qbs::Version();
    }
    QByteArray result = qmakeProcess.readAll().simplified();
    qbs::Version version = qbs::Version::fromString(result);
    if (!version.isValid())
        qDebug() << "qmake '" << qmakeFilePath << "' version is not valid.";
    return version;
}
<|endoftext|>


<commit_before>/*
 * fbautostart.cpp
 *
 * This file is part of the Fluxbox Autostart ( fbautostart )
 * Utility.
 *
 * Copyright(c) 2010 Paul Tagliamonte <paultag@ubuntu.com>
 *
 * This file may be licensed under the terms of of the
 * GNU General Public License Version 3 (the ``GPL'').
 *
 * Software distributed under the License is distributed
 * on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
 * express or implied. See the GPL for the specific language
 * governing rights and limitations.
 *
 * You should have received a copy of the GPL along with this
 * program. If not, go to http://www.gnu.org/licenses/gpl.html
 * or write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 *
 */

#include <iostream>
#include <vector>
#include <string>

#include "fbautostart.h"
#include "dot_desktop.cpp"

#define _APPNAME_ "fbautostart"
#define _VERSION_ "2.71828"

using namespace std;

bool noexec = false;

void version() {
	std::cout << "" << _APPNAME_ << " " << _VERSION_ << std::endl;
}

void lecture() {
	version();
	std::cout << "Copyright (C) 2010 Paul Tagliamonte" << std::endl;
	std::cout << "License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>" << std::endl;
	std::cout << "This is free software: you are free to change and redistribute it." << std::endl;
	std::cout << "There is NO WARRANTY, to the extent permitted by law." << std::endl;
}

void help() {
	std::cout << "Usage: fbautostart [OPTION] ... " << std::endl;
	std::cout << "Startup all applications according to the" << std::endl;
	std::cout << "XDG Spec. Right now, I'm hardcoded to think that" << std::endl;
	std::cout << "I am doing this on behalf of '" << _ON_BEHALF_OF << "'" << std::endl;

	std::cout << std::endl;

	std::cout << "--license             Print out license information" << std::endl;
	std::cout << "--help                Print out this message" << std::endl;
	std::cout << "--noexec              Don't exec, just do a dry run" << std::endl;
	std::cout << "--window-manager ID   Override hardcoded value ( " << _ON_BEHALF_OF <<  " )" << std::endl;

	std::cout << "" << std::endl;

	std::cout << "Copyleft (c) Paul Tagliamonte, 2010, GNU GPLv3+" << std::endl;

	std::cout << "" << std::endl;
}

int runCommand( std::string appl ) {
	/*
	 * The following is almost directly ripped off from
	 * Fluxbox's implementation. ( at ak|ra's behest )
	 */

	pid_t pid = fork();
	if (pid)
		return pid;

	// get shell path from the environment
	//
	// this process exits immediately, so we don't have to
	//  worry about memleaks
	std::string shell = getenv("SHELL");

	if ( shell != "" )
		shell = "/bin/sh";

	if ( ! noexec ) { // we'll do it live
		execl( shell.c_str(), shell.c_str(), "-c", appl.c_str(), static_cast<void*>(NULL) );
		exit ( EXIT_SUCCESS );
		return pid; // compiler happy -> we are happy ;)
	} else { // dummy mode ( test )
		std::cout << "Would have run: " << appl << std::endl;
		exit(0);
		return 0;
	}
}

void processArgs( int argc, char ** args ) {
	for ( int i = 1; i < argc; ++i ) {
		if ( strcmp(args[i], "--license") == 0 ) {
			lecture();
			exit(0);
		} else if ( strcmp(args[i], "--version") == 0 ) {
			version();
			exit(0);
		} else if ( strcmp(args[i], "--help") == 0 ) {
			help();
			exit(0);
		} else if ( strcmp(args[i], "--noexec") == 0 ) {
			noexec = true;
		} else if ( strcmp(args[i], "--window-manager") == 0 ) {
			_ON_BEHALF_OF = args[i+1];
			i = i+1;
		} else {
			std::cout << "Holy god. I have no idea what:" << std::endl;
			std::cout << "  " << args[i] << std::endl;
			std::cout << "means. Try again :/" << std::endl;
			std::cout << std::endl;

			help();
			exit(1);
		}
	}
}

int main ( int argc, char ** argv ) {
	processArgs( argc, argv );

	if ( noexec ) {
		std::cout << "Warning: In noexec mode." << std::endl;
	}

	std::cout << "Launching on behalf of " << _ON_BEHALF_OF << std::endl;

	std::vector<dot_desktop>   files;
	std::vector<std::string>   dirs;

	if ( getConfDirs( dirs ) ) { // if no directories barf in our face
		if ( getDesktopFiles( dirs, files ) ) { // and we load everything with glee
			for ( unsigned int i = 0; i < files.size(); ++i ) { // run through all the files
				dot_desktop d = files.at(i);
				bool happy = true;
				std::string only = d.getAttr("OnlyShowIn"); // Only one per file ( per xdg )
				std::string noti = d.getAttr("NotShowIn");  // We'll ignore that until we care
				                                             // XXX: This is most likely a bug.
				if ( only != "" ) { // even if an attr does not exist
				                    // the object will return it as "".
					int index = -1;
					index = only.find(_ON_BEHALF_OF); // if we have our WM in the OnlyLaunch
					if ( index < 0 ) { // we're disabled ( not found )
						happy = false;
						debug("");
						debug("Not running the following app ( Excluded by a OnlyShowIn )");
						debug(d.getAttr("Name"));
					}
				}
				if ( noti != "" ) { // NAUGHTY NAUGHTY
					int index = -1;
					index = noti.find(_ON_BEHALF_OF); // if we have found our WM
					if ( index >= 0 ) { // We're in Launch, stop from launching it.
						happy = false;
						debug("");
						debug("Forced into not running the following app ( Included by not being in NotShowIn )");
						debug(d.getAttr("Name"));
					}
				}
				if ( d.getAttr("Hidden") == "" && happy ) { // If we sould exec
					std::string appl = d.getAttr("Exec"); // get the line to run
					if ( appl != "" ) { // if it's defined and ready to go
						debug( "Processing File: ");
						debug(d.getFile());
						runCommand( appl ); // kickoff
					}
				} // otherwise, we're out of here.
			}
			return 0;
		}
		return 0xDEADBEEF;
	}
	return 0xCAFEBABE;
}

<commit_msg>just breaking up the line a bit<commit_after>/*
 * fbautostart.cpp
 *
 * This file is part of the Fluxbox Autostart ( fbautostart )
 * Utility.
 *
 * Copyright(c) 2010 Paul Tagliamonte <paultag@ubuntu.com>
 *
 * This file may be licensed under the terms of of the
 * GNU General Public License Version 3 (the ``GPL'').
 *
 * Software distributed under the License is distributed
 * on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
 * express or implied. See the GPL for the specific language
 * governing rights and limitations.
 *
 * You should have received a copy of the GPL along with this
 * program. If not, go to http://www.gnu.org/licenses/gpl.html
 * or write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 *
 */

#include <iostream>
#include <vector>
#include <string>

#include "fbautostart.h"
#include "dot_desktop.cpp"

#define _APPNAME_ "fbautostart"
#define _VERSION_ "2.71828"

using namespace std;

bool noexec = false;

void version() {
	std::cout << "" << _APPNAME_ << " " << _VERSION_ << std::endl;
}

void lecture() {
	version();
	std::cout << "Copyright (C) 2010 Paul Tagliamonte" << std::endl;
	std::cout << "License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>" << std::endl;
	std::cout << "This is free software: you are free to change and redistribute it." << std::endl;
	std::cout << "There is NO WARRANTY, to the extent permitted by law." << std::endl;
}

void help() {
	std::cout << "Usage: fbautostart [OPTION] ... " << std::endl;
	std::cout << "Startup all applications according to the" << std::endl;
	std::cout << "XDG Spec. Right now, I'm hardcoded to think that" << std::endl;
	std::cout << "I am doing this on behalf of '" << _ON_BEHALF_OF << "'" << std::endl;

	std::cout << std::endl;

	std::cout << "--license             Print out license information" << std::endl;
	std::cout << "--help                Print out this message" << std::endl;
	std::cout << "--noexec              Don't exec, just do a dry run" << std::endl;
	std::cout << "--window-manager ID   Override hardcoded value ( " << _ON_BEHALF_OF <<  " )" << std::endl;

	std::cout << "" << std::endl;

	std::cout << "Copyleft (c) Paul Tagliamonte, 2010, GNU GPLv3+" << std::endl;

	std::cout << "" << std::endl;
}

int runCommand( std::string appl ) {
	/*
	 * The following is almost directly ripped off from
	 * Fluxbox's implementation. ( at ak|ra's behest )
	 */

	pid_t pid = fork();
	if (pid)
		return pid;

	// get shell path from the environment
	//
	// this process exits immediately, so we don't have to
	//  worry about memleaks
	std::string shell = getenv("SHELL");

	if ( shell != "" )
		shell = "/bin/sh";

	if ( ! noexec ) { // we'll do it live
		execl(
			shell.c_str(),
			shell.c_str(),
			"-c",
			appl.c_str(),
			static_cast<void*>(NULL)
		);
		exit ( EXIT_SUCCESS );
		return pid; // compiler happy -> we are happy ;)
	} else { // dummy mode ( test )
		std::cout << "Would have run: " << appl << std::endl;
		exit(0);
		return 0;
	}
}

void processArgs( int argc, char ** args ) {
	for ( int i = 1; i < argc; ++i ) {
		if ( strcmp(args[i], "--license") == 0 ) {
			lecture();
			exit(0);
		} else if ( strcmp(args[i], "--version") == 0 ) {
			version();
			exit(0);
		} else if ( strcmp(args[i], "--help") == 0 ) {
			help();
			exit(0);
		} else if ( strcmp(args[i], "--noexec") == 0 ) {
			noexec = true;
		} else if ( strcmp(args[i], "--window-manager") == 0 ) {
			_ON_BEHALF_OF = args[i+1];
			i = i+1;
		} else {
			std::cout << "Holy god. I have no idea what:" << std::endl;
			std::cout << "  " << args[i] << std::endl;
			std::cout << "means. Try again :/" << std::endl;
			std::cout << std::endl;

			help();
			exit(1);
		}
	}
}

int main ( int argc, char ** argv ) {
	processArgs( argc, argv );

	if ( noexec ) {
		std::cout << "Warning: In noexec mode." << std::endl;
	}

	std::cout << "Launching on behalf of " << _ON_BEHALF_OF << std::endl;

	std::vector<dot_desktop>   files;
	std::vector<std::string>   dirs;

	if ( getConfDirs( dirs ) ) { // if no directories barf in our face
		if ( getDesktopFiles( dirs, files ) ) { // and we load everything with glee
			for ( unsigned int i = 0; i < files.size(); ++i ) { // run through all the files
				dot_desktop d = files.at(i);
				bool happy = true;
				std::string only = d.getAttr("OnlyShowIn"); // Only one per file ( per xdg )
				std::string noti = d.getAttr("NotShowIn");  // We'll ignore that until we care
				                                             // XXX: This is most likely a bug.
				if ( only != "" ) { // even if an attr does not exist
				                    // the object will return it as "".
					int index = -1;
					index = only.find(_ON_BEHALF_OF); // if we have our WM in the OnlyLaunch
					if ( index < 0 ) { // we're disabled ( not found )
						happy = false;
						debug("");
						debug("Not running the following app ( Excluded by a OnlyShowIn )");
						debug(d.getAttr("Name"));
					}
				}
				if ( noti != "" ) { // NAUGHTY NAUGHTY
					int index = -1;
					index = noti.find(_ON_BEHALF_OF); // if we have found our WM
					if ( index >= 0 ) { // We're in Launch, stop from launching it.
						happy = false;
						debug("");
						debug("Forced into not running the following app ( Included by not being in NotShowIn )");
						debug(d.getAttr("Name"));
					}
				}
				if ( d.getAttr("Hidden") == "" && happy ) { // If we sould exec
					std::string appl = d.getAttr("Exec"); // get the line to run
					if ( appl != "" ) { // if it's defined and ready to go
						debug( "Processing File: ");
						debug(d.getFile());
						runCommand( appl ); // kickoff
					}
				} // otherwise, we're out of here.
			}
			return 0;
		}
		return 0xDEADBEEF;
	}
	return 0xCAFEBABE;
}

<|endoftext|>


<commit_before>
// Select one of the scenarios below
#define SCENARIO 3

#if SCENARIO == 1
// this is the "no harm done" version. Only operator% is active,
// with NO_CAST * defined
#define P %
#undef QT_USE_FAST_OPERATOR_PLUS
#undef QT_USE_FAST_CONCATENATION
#define QT_NO_CAST_FROM_ASCII
#define QT_NO_CAST_TO_ASCII
#endif

#if SCENARIO == 2
// this is the "full" version. Operator+ is replaced by a QStringBuilder
// based version
// with NO_CAST * defined
#define P %
#define QT_USE_FAST_OPERATOR_PLUS
#define QT_USE_FAST_CONCATENATION
#define QT_NO_CAST_FROM_ASCII
#define QT_NO_CAST_TO_ASCII
#endif

#if SCENARIO == 3
// this is the "no harm done" version. Only operator% is active,
// with NO_CAST * _not_ defined
#define P %
#undef QT_USE_FAST_OPERATOR_PLUS
#undef QT_USE_FAST_CONCATENATION
#undef QT_NO_CAST_FROM_ASCII
#undef QT_NO_CAST_TO_ASCII
#endif

#if SCENARIO == 4
// this is the "full" version. Operator+ is replaced by a QStringBuilder
// based version
// with NO_CAST * _not_ defined
#define P %
#define QT_USE_FAST_OPERATOR_PLUS
#define QT_USE_FAST_CONCATENATION
#undef QT_NO_CAST_FROM_ASCII
#undef QT_NO_CAST_TO_ASCII
#endif

#include <qbytearray.h>
#include <qdebug.h>
#include <qstring.h>
#include <qstringbuilder.h>

#include <qtest.h>

#define COMPARE(a, b) QCOMPARE(a, b)
//#define COMPARE(a, b)

#define SEP(s) qDebug() << "\n\n-------- " s "  ---------";

#define LITERAL "some string literal"

class tst_qstringbuilder : public QObject
{
    Q_OBJECT

public:
    tst_qstringbuilder()
      : l1literal(LITERAL),
        l1string(LITERAL),
        ba(LITERAL),
        string(l1string),
        stringref(&string, 2, 10),
        achar('c'),
        r2(QLatin1String(LITERAL LITERAL)),
        r3(QLatin1String(LITERAL LITERAL LITERAL)),
        r4(QLatin1String(LITERAL LITERAL LITERAL LITERAL)),
        r5(QLatin1String(LITERAL LITERAL LITERAL LITERAL LITERAL))
    {}

public:
    enum { N = 10000 };

    int run_traditional()
    {
        int s = 0;
        for (int i = 0; i < N; ++i) {
#if 0
            s += QString(l1string + l1string).size();
            s += QString(l1string + l1string + l1string).size();
            s += QString(l1string + l1string + l1string + l1string).size();
            s += QString(l1string + l1string + l1string + l1string + l1string).size();
#endif
            s += QString(achar + l1string + achar).size();
        }
        return s;
    }

    int run_builder()
    {
        int s = 0;
        for (int i = 0; i < N; ++i) {
#if 0
            s += QString(l1literal P l1literal).size();
            s += QString(l1literal P l1literal P l1literal).size();
            s += QString(l1literal P l1literal P l1literal P l1literal).size();
            s += QString(l1literal P l1literal P l1literal P l1literal P l1literal).size();
#endif
            s += QString(achar % l1literal % achar).size();
        }
        return s;
    }

private slots:

    void separator_0() {
        qDebug() << "\nIn each block the QStringBuilder based result appear first, "
            "QStringBased second.\n";
    }

    void separator_1() { SEP("literal + literal  (builder first)"); }

    void b_2_l1literal() {
        QBENCHMARK { r = l1literal P l1literal; }
        COMPARE(r, r2);
    }
    #ifndef QT_NO_CAST_FROM_ASCII
    void b_l1literal_LITERAL() {
        QBENCHMARK { r = l1literal P LITERAL; }
        COMPARE(r, r2);
    }
    #endif
    void s_2_l1string() {
        QBENCHMARK { r = l1string + l1string; }
        COMPARE(r, r2);
    }

    void separator_2() { SEP("2 strings"); }

    void b_2_string() {
        QBENCHMARK { r = string P string; }
        COMPARE(r, r2);
    }
    void s_2_string() {
        QBENCHMARK { r = string + string; }
        COMPARE(r, r2);
    }

    void separator_2c() { SEP("2 string refs"); }

    void b_2_stringref() {
        QBENCHMARK { r = stringref % stringref; }
        COMPARE(r, QString(stringref.toString() + stringref.toString()));
    }
    void s_2_stringref() {
        QBENCHMARK { r = stringref.toString() + stringref.toString(); }
        COMPARE(r, QString(stringref % stringref));
    }

    void separator_2b() { SEP("3 strings"); }

    void b_3_string() {
        QBENCHMARK { r = string P string P string; }
        COMPARE(r, r3);
    }
    void s_3_string() {
        QBENCHMARK { r = string + string + string; }
        COMPARE(r, r3);
    }

    void separator_2a() { SEP("string + literal  (builder first)"); }

    void b_string_l1literal() {
        QBENCHMARK { r = string % l1literal; }
        COMPARE(r, r2);
    }
    #ifndef QT_NO_CAST_FROM_ASCII
    void b_string_LITERAL() {
        QBENCHMARK { r = string P LITERAL; }
        COMPARE(r, r2);
    }
    void b_LITERAL_string() {
        QBENCHMARK { r = LITERAL P string; }
        COMPARE(r, r2);
    }
    #endif
    void b_string_l1string() {
        QBENCHMARK { r = string P l1string; }
        COMPARE(r, r2);
    }
    void s_string_l1literal() {
        QBENCHMARK { r = string + l1string; }
        COMPARE(r, r2);
    }
    void s_string_l1string() {
        QBENCHMARK { r = string + l1string; }
        COMPARE(r, r2);
    }

    void separator_3() { SEP("3 literals"); }

    void b_3_l1literal() {
        QBENCHMARK { r = l1literal P l1literal P l1literal; }
        COMPARE(r, r3);
    }
    void s_3_l1string() {
        QBENCHMARK { r = l1string + l1string + l1string; }
        COMPARE(r, r3);
    }

    void separator_4() { SEP("4 literals"); }

    void b_4_l1literal() {
        QBENCHMARK { r = l1literal P l1literal P l1literal P l1literal; }
        COMPARE(r, r4);
    }
    void s_4_l1string() {
        QBENCHMARK { r = l1string + l1string + l1string + l1string; }
        COMPARE(r, r4);
    }

    void separator_5() { SEP("5 literals"); }

    void b_5_l1literal() {
        QBENCHMARK { r = l1literal P l1literal P l1literal P l1literal P l1literal; }
        COMPARE(r, r5);
    }

    void s_5_l1string() {
        QBENCHMARK { r = l1string + l1string + l1string + l1string + l1string; }
        COMPARE(r, r5);
    }

    void separator_6() { SEP("4 chars"); }

    void b_string_4_char() {
        QBENCHMARK { r = string + achar + achar + achar + achar; }
        COMPARE(r, QString(string P achar P achar P achar P achar));
    }

    void s_string_4_char() {
        QBENCHMARK { r = string + achar + achar + achar + achar; }
        COMPARE(r, QString(string P achar P achar P achar P achar));
    }

    void separator_7() { SEP("char + string + char"); }

    void b_char_string_char() {
        QBENCHMARK { r = achar + string + achar; }
        COMPARE(r, QString(achar P string P achar));
    }

    void s_char_string_char() {
        QBENCHMARK { r = achar + string + achar; }
        COMPARE(r, QString(achar P string P achar));
    }

    void separator_8() { SEP("string.arg"); }

    void b_string_arg() {
        const QString pattern = l1string + QString::fromLatin1("%1") + l1string;
        QBENCHMARK { r = l1literal P string P l1literal; }
        COMPARE(r, r3);
    }

    void s_string_arg() {
        const QString pattern = l1string + QLatin1String("%1") + l1string;
        QBENCHMARK { r = pattern.arg(string); }
        COMPARE(r, r3);
    }

    void s_bytearray_arg() {
        QByteArray result;
        QBENCHMARK { result = ba + ba + ba; }
    }

    void separator_9() { SEP("QString::reserve()"); }

    void b_reserve() {
        QBENCHMARK {
            r.clear();
            r = string P string P string P string;
        }
        COMPARE(r, r4);
    }
    void b_reserve_lit() {
        QBENCHMARK {
            r.clear();
            r = string P l1literal P string P string;
        }
        COMPARE(r, r4);
    }
    void s_reserve() {
        QBENCHMARK {
            r.clear();
            r.reserve(string.size() + string.size() + string.size() + string.size());
            r += string;
            r += string;
            r += string;
            r += string;
        }
        COMPARE(r, r4);
    }
    void s_reserve_lit() {
        QBENCHMARK {
            r.clear();
            //r.reserve(string.size() + qstrlen(l1string.latin1())
            //    + string.size() + string.size());
            r.reserve(1024);
            r += string;
            r += l1string;
            r += string;
            r += string;
        }
        COMPARE(r, r4);
    }

private:
    const QLatin1Literal l1literal;
    const QLatin1String l1string;
    const QByteArray ba;
    const QString string;
    const QStringRef stringref;
    const QLatin1Char achar;
    const QString r2, r3, r4, r5;

    QString r;
};

//void operator%(QString, int) {}

int main(int argc, char *argv[])
{
    //qDebug() << (QString("xx") * QLatin1String("y")).toString();
    //42 % 3; // Sanity test, should always work.
    //QString("x") % 2; // Sanity test, should only compile when the
    // operator%(QString, int) is visible.

    if (argc == 2 && (QLatin1String(argv[1]) == QLatin1String("--run-builder")
                   || QLatin1String(argv[1]) == QLatin1String("-b"))) {
        tst_qstringbuilder test;
        return test.run_builder();
    }

    if (argc == 2 && (QLatin1String(argv[1]) == QLatin1String("--run-traditional")
                   || QLatin1String(argv[1]) == QLatin1String("-t"))) {
        tst_qstringbuilder test;
        return test.run_traditional();
    }

    if (argc == 1) {
        QCoreApplication app(argc, argv);
        QStringList args = app.arguments();
        tst_qstringbuilder test;
        return QTest::qExec(&test, argc, argv);
    }

    qDebug() << "Usage: " << argv[0] << " [--run-builder|-r|--run-traditional|-t]";
}

#include "main.moc"
<commit_msg>Add some comparisons with std::string to the QStringBuilder benchmarks.<commit_after>
// Select one of the scenarios below
#define SCENARIO 1

#if SCENARIO == 1
// this is the "no harm done" version. Only operator% is active,
// with NO_CAST * defined
#define P %
#undef QT_USE_FAST_OPERATOR_PLUS
#undef QT_USE_FAST_CONCATENATION
#define QT_NO_CAST_FROM_ASCII
#define QT_NO_CAST_TO_ASCII
#endif

#if SCENARIO == 2
// this is the "full" version. Operator+ is replaced by a QStringBuilder
// based version
// with NO_CAST * defined
#define P +
#define QT_USE_FAST_OPERATOR_PLUS
#define QT_USE_FAST_CONCATENATION
#define QT_NO_CAST_FROM_ASCII
#define QT_NO_CAST_TO_ASCII
#endif

#if SCENARIO == 3
// this is the "no harm done" version. Only operator% is active,
// with NO_CAST * _not_ defined
#define P %
#undef QT_USE_FAST_OPERATOR_PLUS
#undef QT_USE_FAST_CONCATENATION
#undef QT_NO_CAST_FROM_ASCII
#undef QT_NO_CAST_TO_ASCII
#endif

#if SCENARIO == 4
// this is the "full" version. Operator+ is replaced by a QStringBuilder
// based version
// with NO_CAST * _not_ defined
#define P +
#define QT_USE_FAST_OPERATOR_PLUS
#define QT_USE_FAST_CONCATENATION
#undef QT_NO_CAST_FROM_ASCII
#undef QT_NO_CAST_TO_ASCII
#endif

#include <qbytearray.h>
#include <qdebug.h>
#include <qstring.h>
#include <qstringbuilder.h>

#include <qtest.h>

#include <string>

#define COMPARE(a, b) QCOMPARE(a, b)
//#define COMPARE(a, b)

#define SEP(s) qDebug() << "\n\n-------- " s "  ---------";

#define LITERAL "some string literal"

class tst_qstringbuilder : public QObject
{
    Q_OBJECT

public:
    tst_qstringbuilder()
      : l1literal(LITERAL),
        l1string(LITERAL),
        ba(LITERAL),
        string(l1string),
        stdstring(LITERAL),
        stringref(&string, 2, 10),
        achar('c'),
        r2(QLatin1String(LITERAL LITERAL)),
        r3(QLatin1String(LITERAL LITERAL LITERAL)),
        r4(QLatin1String(LITERAL LITERAL LITERAL LITERAL)),
        r5(QLatin1String(LITERAL LITERAL LITERAL LITERAL LITERAL))
    {}

public:
    enum { N = 10000 };

    int run_traditional()
    {
        int s = 0;
        for (int i = 0; i < N; ++i) {
#if 0
            s += QString(l1string + l1string).size();
            s += QString(l1string + l1string + l1string).size();
            s += QString(l1string + l1string + l1string + l1string).size();
            s += QString(l1string + l1string + l1string + l1string + l1string).size();
#endif
            s += QString(achar + l1string + achar).size();
        }
        return s;
    }

    int run_builder()
    {
        int s = 0;
        for (int i = 0; i < N; ++i) {
#if 0
            s += QString(l1literal P l1literal).size();
            s += QString(l1literal P l1literal P l1literal).size();
            s += QString(l1literal P l1literal P l1literal P l1literal).size();
            s += QString(l1literal P l1literal P l1literal P l1literal P l1literal).size();
#endif
            s += QString(achar % l1literal % achar).size();
        }
        return s;
    }

private slots:

    void separator_0() {
        qDebug() << "\nIn each block the QStringBuilder based result appear first "
            "(with a 'b_' prefix), QStringBased second ('q_' prefix), std::string "
            "last ('s_' prefix)\n";
    }

    void separator_1() { SEP("literal + literal  (builder first)"); }

    void b_2_l1literal() {
        QBENCHMARK { r = l1literal P l1literal; }
        COMPARE(r, r2);
    }
    #ifndef QT_NO_CAST_FROM_ASCII
    void b_l1literal_LITERAL() {
        QBENCHMARK { r = l1literal P LITERAL; }
        COMPARE(r, r2);
    }
    #endif
    void q_2_l1string() {
        QBENCHMARK { r = l1string + l1string; }
        COMPARE(r, r2);
    }

    void separator_2() { SEP("2 strings"); }

    void b_2_string() {
        QBENCHMARK { r = string P string; }
        COMPARE(r, r2);
    }
    void q_2_string() {
        QBENCHMARK { r = string + string; }
        COMPARE(r, r2);
    }
    void s_2_string() {
        QBENCHMARK { stdr = stdstring + stdstring; }
        COMPARE(stdr, stdstring + stdstring);
    }

    void separator_2c() { SEP("2 string refs"); }

    void b_2_stringref() {
        QBENCHMARK { r = stringref % stringref; }
        COMPARE(r, QString(stringref.toString() + stringref.toString()));
    }
    void q_2_stringref() {
        QBENCHMARK { r = stringref.toString() + stringref.toString(); }
        COMPARE(r, QString(stringref % stringref));
    }

    void separator_2b() { SEP("3 strings"); }

    void b_3_string() {
        QBENCHMARK { r = string P string P string; }
        COMPARE(r, r3);
    }
    void q_3_string() {
        QBENCHMARK { r = string + string + string; }
        COMPARE(r, r3);
    }
    void s_3_string() {
        QBENCHMARK { stdr = stdstring + stdstring + stdstring; }
        COMPARE(stdr, stdstring + stdstring + stdstring);
    }

    void separator_2e() { SEP("4 strings"); }

    void b_4_string() {
        QBENCHMARK { r = string P string P string P string; }
        COMPARE(r, r4);
    }
    void q_4_string() {
        QBENCHMARK { r = string + string + string + string; }
        COMPARE(r, r4);
    }
    void s_4_string() {
        QBENCHMARK { stdr = stdstring + stdstring + stdstring + stdstring; }
        COMPARE(stdr, stdstring + stdstring + stdstring + stdstring);
    }

    void separator_2a() { SEP("string + literal  (builder first)"); }

    void b_string_l1literal() {
        QBENCHMARK { r = string % l1literal; }
        COMPARE(r, r2);
    }
    #ifndef QT_NO_CAST_FROM_ASCII
    void b_string_LITERAL() {
        QBENCHMARK { r = string P LITERAL; }
        COMPARE(r, r2);
    }
    void b_LITERAL_string() {
        QBENCHMARK { r = LITERAL P string; }
        COMPARE(r, r2);
    }
    #endif
    void b_string_l1string() {
        QBENCHMARK { r = string P l1string; }
        COMPARE(r, r2);
    }
    void q_string_l1literal() {
        QBENCHMARK { r = string + l1string; }
        COMPARE(r, r2);
    }
    void q_string_l1string() {
        QBENCHMARK { r = string + l1string; }
        COMPARE(r, r2);
    }
    void s_LITERAL_string() {
        QBENCHMARK { stdr = LITERAL + stdstring; }
        COMPARE(stdr, stdstring + stdstring);
    }

    void separator_3() { SEP("3 literals"); }

    void b_3_l1literal() {
        QBENCHMARK { r = l1literal P l1literal P l1literal; }
        COMPARE(r, r3);
    }
    void q_3_l1string() {
        QBENCHMARK { r = l1string + l1string + l1string; }
        COMPARE(r, r3);
    }
    void s_3_l1string() {
        QBENCHMARK { stdr = stdstring + LITERAL + LITERAL; }
        COMPARE(stdr, stdstring + stdstring + stdstring);
    }

    void separator_4() { SEP("4 literals"); }

    void b_4_l1literal() {
        QBENCHMARK { r = l1literal P l1literal P l1literal P l1literal; }
        COMPARE(r, r4);
    }
    void q_4_l1string() {
        QBENCHMARK { r = l1string + l1string + l1string + l1string; }
        COMPARE(r, r4);
    }

    void separator_5() { SEP("5 literals"); }

    void b_5_l1literal() {
        QBENCHMARK { r = l1literal P l1literal P l1literal P l1literal P l1literal; }
        COMPARE(r, r5);
    }

    void q_5_l1string() {
        QBENCHMARK { r = l1string + l1string + l1string + l1string + l1string; }
        COMPARE(r, r5);
    }

    void separator_6() { SEP("4 chars"); }

    void b_string_4_char() {
        QBENCHMARK { r = string + achar + achar + achar + achar; }
        COMPARE(r, QString(string P achar P achar P achar P achar));
    }

    void q_string_4_char() {
        QBENCHMARK { r = string + achar + achar + achar + achar; }
        COMPARE(r, QString(string P achar P achar P achar P achar));
    }

    void s_string_4_char() {
        QBENCHMARK { stdr = stdstring + 'c' + 'c' + 'c' + 'c'; }
        COMPARE(stdr, stdstring + 'c' + 'c' + 'c' + 'c');
    }

    void separator_7() { SEP("char + string + char"); }

    void b_char_string_char() {
        QBENCHMARK { r = achar + string + achar; }
        COMPARE(r, QString(achar P string P achar));
    }

    void q_char_string_char() {
        QBENCHMARK { r = achar + string + achar; }
        COMPARE(r, QString(achar P string P achar));
    }

    void s_char_string_char() {
        QBENCHMARK { stdr = 'c' + stdstring + 'c'; }
        COMPARE(stdr, 'c' + stdstring + 'c');
    }

    void separator_8() { SEP("string.arg"); }

    void b_string_arg() {
        const QString pattern = l1string + QString::fromLatin1("%1") + l1string;
        QBENCHMARK { r = l1literal P string P l1literal; }
        COMPARE(r, r3);
    }

    void q_string_arg() {
        const QString pattern = l1string + QLatin1String("%1") + l1string;
        QBENCHMARK { r = pattern.arg(string); }
        COMPARE(r, r3);
    }

    void q_bytearray_arg() {
        QByteArray result;
        QBENCHMARK { result = ba + ba + ba; }
    }

    void separator_9() { SEP("QString::reserve()"); }

    void b_reserve() {
        QBENCHMARK {
            r.clear();
            r = string P string P string P string;
        }
        COMPARE(r, r4);
    }
    void b_reserve_lit() {
        QBENCHMARK {
            r.clear();
            r = string P l1literal P string P string;
        }
        COMPARE(r, r4);
    }
    void s_reserve() {
        QBENCHMARK {
            r.clear();
            r.reserve(string.size() + string.size() + string.size() + string.size());
            r += string;
            r += string;
            r += string;
            r += string;
        }
        COMPARE(r, r4);
    }
    void s_reserve_lit() {
        QBENCHMARK {
            r.clear();
            //r.reserve(string.size() + qstrlen(l1string.latin1())
            //    + string.size() + string.size());
            r.reserve(1024);
            r += string;
            r += l1string;
            r += string;
            r += string;
        }
        COMPARE(r, r4);
    }

private:
    const QLatin1Literal l1literal;
    const QLatin1String l1string;
    const QByteArray ba;
    const QString string;
    const std::string stdstring;
    const QStringRef stringref;
    const QLatin1Char achar;
    const QString r2, r3, r4, r5;

    // short cuts for results
    QString r;
    std::string stdr;
};

//void operator%(QString, int) {}

int main(int argc, char *argv[])
{
    //qDebug() << (QString("xx") * QLatin1String("y")).toString();
    //42 % 3; // Sanity test, should always work.
    //QString("x") % 2; // Sanity test, should only compile when the
    // operator%(QString, int) is visible.

    if (argc == 2 && (QLatin1String(argv[1]) == QLatin1String("--run-builder")
                   || QLatin1String(argv[1]) == QLatin1String("-b"))) {
        tst_qstringbuilder test;
        return test.run_builder();
    }

    if (argc == 2 && (QLatin1String(argv[1]) == QLatin1String("--run-traditional")
                   || QLatin1String(argv[1]) == QLatin1String("-t"))) {
        tst_qstringbuilder test;
        return test.run_traditional();
    }

    if (argc == 1) {
        QCoreApplication app(argc, argv);
        QStringList args = app.arguments();
        tst_qstringbuilder test;
        return QTest::qExec(&test, argc, argv);
    }

    qDebug() << "Usage: " << argv[0] << " [--run-builder|-r|--run-traditional|-t]";
}

#include "main.moc"
<|endoftext|>


<commit_before>#include    <cstdlib>
#include    <cmath>
#include    <fstream>
#include    <sstream>
#include    <iostream>
#include    <iomanip>
#include    <string>
#include    <vector>
#include    <algorithm>
#include    <exception>
#include    <sys/time.h>
#include    "modules/htmTree.h"
#include    "modules/kdTree.h"
#include        "misc.h"
#include        "feat.h"
#include        "structs.h"
#include        "collision.h"
#include        "global.h"

//reduce redistributes, updates  07/02/15 rnc
int main(int argc, char **argv) {
    //// Initializations ---------------------------------------------
    srand48(1234); // Make sure we have reproducability
    check_args(argc);
    Time t, time; // t for global, time for local
    init_time(t);
    Feat F;
    MTL M;

    // Read parameters file //
    F.readInputFile(argv[1]);
    printFile(argv[1]);
    // Read input files for standards, skys and targets.
    // Try to read SS and SF before targets to avoid wasting time if these
    // smaller files can't be read.
    init_time_at(time,"# Read target, SS, SF files",t);
    MTL SStars = read_MTLfile(F.SStarsfile,F,1,0);
    MTL SkyF   = read_MTLfile(F.SkyFfile,  F,0,1);
    MTL Targ   = read_MTLfile(F.Targfile,  F,0,0);
    print_time(time,"# ... took :");
    //combine the three input files
    M=Targ;
    printf(" Target size %d \n",M.size());
    M.insert(M.end(),SStars.begin(),SStars.end());
    printf(" Standard Star size %d \n",M.size());
    M.insert(M.end(),SkyF.begin(),SkyF.end());
    printf(" Sky Fiber size %d \n",M.size());

    F.Ngal = M.size();
    assign_priority_class(M);
    std::vector <int> count_class(M.priority_list.size(),0);
    for(int i=0;i<M.size();++i){
        if(!M[i].SS&&!M[i].SF){
            count_class[M[i].priority_class]+=1;
        }
    }
    for(int i=0;i<M.priority_list.size();++i){
        printf("  class  %d  number  %d\n",i,count_class[i]);
    }
    print_time(time,"# ... took :");

    // fiber positioners
    PP pp;
    pp.read_fiber_positions(F);
    F.Nfiber = pp.fp.size()/2;
    F.Npetal = max(pp.spectrom)+1;
    F.Nfbp = (int) (F.Nfiber/F.Npetal);// fibers per petal = 500
    pp.get_neighbors(F);
    pp.compute_fibsofsp(F);

    //P is original list of plates
    Plates P = read_plate_centers(F);
    F.Nplate=P.size();
    printf("# Read %s plate centers from %s and %d fibers from %s\n",f(F.Nplate).c_str(),F.tileFile.c_str(),F.Nfiber,F.fibFile.c_str());
    // Computes geometries of cb and fh: pieces of positioner - used to determine possible collisions
    F.cb = create_cb(); // cb=central body
    F.fh = create_fh(); // fh=fiber holder
    const char *filecheck="/project/projectdirs/desi/users/rncahn/large_mock_test/tmp/fiberassign/save_av_gals_00004.fits";
    //// Collect available galaxies <-> tilefibers --------------------
    // HTM Tree of galaxies

    std::ifstream infile(filecheck);
    if(!infile.good()){//av_gals has not been saved yet ************************

    const double MinTreeSize = 0.01;
    init_time_at(time,"# Start building HTM tree",t);
    htmTree<struct target> T(M,MinTreeSize);
    print_time(time,"# ... took :");//T.stats();
    init_time_at(time,"# collect galaxies at ",t);

    // For plates/fibers, collect available galaxies; done in parallel  P[plate j].av_gal[k]=[g1,g2,..]
    collect_galaxies_for_all(M,T,P,pp,F);
    print_time(time,"# ... took :");//T.stats();
    init_time_at(time,"# collect available tile-fibers at",t);

    // For each galaxy, computes available tilefibers  G[i].av_tfs = [(j1,k1),(j2,k2),..]
    collect_available_tilefibers(M,P,F);
    // DIAGNOSTIC
/*
    printf("SPECIAL  \n");
    for(int j=0;j<F.Nplate;++j){
      if(P[j].tileid==13937){
	printf(" this tile %d  j %d\n",P[j].tileid,j);
    for(int k=0;k<F.Nfiber;++k){
      printf("k %d\n",k);
      for(int m=0;m<P[j].av_gals[k].size();++m){
	printf(" galaxy %d \n",P[j].av_gals[k][m]);
      }
      }
      }
      }*/

    } else { //  av_gals have been saved
          // each new epoch has shorter list of tiles
          size_t cfilesize = 512;
	  char filename[cfilesize];
          printf(" F.Nplate = %d \n",F.Nplate);
	  std::cout.flush();
	  for(int j=0;j<F.Nplate;j++){
	    Table av_gals;
	    bool diagnose;/*
	    if(P[j].tileid==13937){
	      diagnose = true;}
	    else diagnose = false;
	    if(diagnose)printf(" j %d diagnose %d\n",j,diagnose);
	    if(diagnose)printf("j  %d  P[j].tileid %d \n",j,P[j].tileid);
			  */
	    int ret = snprintf(filename, cfilesize, "%s/save_av_gals_%05d.fits", F.outDir.c_str(), P[j].tileid);
	    //if(diagnose)printf(" saved file %s \n",filename);
	    read_save_av_gals(filename,  F,av_gals,diagnose);
	    P[j].av_gals=av_gals;
	    //if(diagnose)printf(" after read_save \n");
	    std::cout.flush();
	  }
    }
    //results_on_inputs("doc/figs/",G,P,F,true);

    //save available galaxies for each tile-fiber

    if(!infile.good()){//first epoch only, write files
        printf("no files there\n");
        for (int j=0; j<F.Nplate; j++){
	    write_save_av_gals(j,F.outDir,M,P,pp,F);

        }
    }else{
      printf("save files already there\n");
      std::cout.flush();

    }

    //// Assignment |||||||||||||||||||||||||||||||||||||||||||||||||||
    printf(" Nplate %d  Ngal %d   Nfiber %d \n", F.Nplate, F.Ngal, F.Nfiber);
    Assignment A(M,F);
    // Make a plan ----------------------------------------------------
    print_time(t,"# Start assignment at : ");
    simple_assign(M,P,pp,F,A);

    //check to see if there are tiles with no galaxies
    //need to keep mapping of old tile list to new tile list
    //and inverse map
    A.inv_order=initList(F.Nplate,-1);
    int inv_count=0;
    for (int j=0;j<F.Nplate ;++j){

        bool not_done=true;
        for(int k=0;k<F.Nfiber && not_done;++k){
            if(A.TF[j][k]!=-1){
                A.suborder.push_back(j);//suborder[jused] is jused-th used plate
                not_done=false;
                A.inv_order[j]=inv_count;//inv_order[j] is -1 unless used
                inv_count++;
            }
        }
    }
    F.NUsedplate=A.suborder.size();
    printf(" Plates actually used %d \n",F.NUsedplate);

    // Smooth out distribution of free fibers, and increase the number of assignments

    for (int i=0; i<1; i++) redistribute_tf(M,P,pp,F,A,0);// more iterations will improve performance slightly
    for (int i=0; i<3; i++) {
        improve(M,P,pp,F,A,0);
        redistribute_tf(M,P,pp,F,A,0);
    }
    init_time_at(time,"# assign SS and SF ",t);

    //try assigning SF and SS before real time assignment
    for (int jused=0;jused<F.NUsedplate;++jused){

        int j=A.suborder[jused];
        assign_sf_ss(j,M,P,pp,F,A); // Assign SS and SF for each tile
        assign_unused(j,M,P,pp,F,A);
    }

    // Results -------------------------------------------------------*/
    std::vector <int> total_used_by_class(M.priority_list.size(),0);
    int total_used_SS=0;
    int total_used_SF=0;
    for (int jused=0;jused<F.NUsedplate;++jused){
        std::vector <int> used_by_class(M.priority_list.size(),0);
        int used_SS=0;
        int used_SF=0;
        int j=A.suborder[jused];
        for(int k=0;k<F.Nfiber;++k){
            int g=A.TF[j][k];
            if(g!=-1){
                if(M[g].SS){
                    total_used_SS++;
                    used_SS++;
                    }
                    else if(M[g].SF){
                        used_SF++;
                        total_used_SF++;
                    }
                    else{
                        used_by_class[M[g].priority_class]++;
                        total_used_by_class[M[g].priority_class]++;
                    }
            }
        }
       /* printf(" plate jused %5d j %5d  SS   %4d    SF   %4d",jused,j,used_SS,used_SF);
        for (int pr=0;pr<M.priority_list.size();++pr){
            printf(" class %2d   %5d",pr,used_by_class[pr]);
        }
        printf("\n");
        */
    }
    init_time_at(time,"# count SS and SF ",t);
    printf(" Totals SS   %4d    SF   %4d",total_used_SS,total_used_SF);
    std::cout.flush();
    for (int pr=0;pr<M.priority_list.size();++pr){
        printf(" class %2d   %5d",pr,total_used_by_class[pr]);
        std::cout.flush();
    }

    printf("\n");
    init_time_at(time,"# print txt files ",t);
    if (F.PrintAscii) for (int jused=0; jused<F.NUsedplate; jused++){
        int j=A.suborder[jused];
        write_FAtile_ascii(j,F.outDir,M,P,pp,F,A);
        }
    init_time_at(time,"# print fits files ",t);
    if (F.PrintFits) for (int jused=0; jused<F.NUsedplate; jused++){
        int j=A.suborder[jused];
        fa_write(j,F.outDir,M,P,pp,F,A); // Write output
    }

  print_time(t,"# Finished !... in");

  return(0);
}
<commit_msg>probably need to fix relation between targets before and after first epoch<commit_after>#include    <cstdlib>
#include    <cmath>
#include    <fstream>
#include    <sstream>
#include    <iostream>
#include    <iomanip>
#include    <string>
#include    <vector>
#include    <algorithm>
#include    <exception>
#include    <sys/time.h>
#include    "modules/htmTree.h"
#include    "modules/kdTree.h"
#include        "misc.h"
#include        "feat.h"
#include        "structs.h"
#include        "collision.h"
#include        "global.h"

//reduce redistributes, updates  07/02/15 rnc
int main(int argc, char **argv) {
    //// Initializations ---------------------------------------------
    srand48(1234); // Make sure we have reproducability
    check_args(argc);
    Time t, time; // t for global, time for local
    init_time(t);
    Feat F;
    MTL M;

    // Read parameters file //
    F.readInputFile(argv[1]);
    printFile(argv[1]);
    // Read input files for standards, skys and targets.
    // Try to read SS and SF before targets to avoid wasting time if these
    // smaller files can't be read.
    init_time_at(time,"# Read target, SS, SF files",t);
    MTL SStars = read_MTLfile(F.SStarsfile,F,1,0);
    MTL SkyF   = read_MTLfile(F.SkyFfile,  F,0,1);
    MTL Targ   = read_MTLfile(F.Targfile,  F,0,0);
    print_time(time,"# ... took :");
    //combine the three input files
    M=Targ;
    printf(" Target size %d \n",M.size());
    M.insert(M.end(),SStars.begin(),SStars.end());
    printf(" Standard Star size %d \n",M.size());
    M.insert(M.end(),SkyF.begin(),SkyF.end());
    printf(" Sky Fiber size %d \n",M.size());

    F.Ngal = M.size();
    assign_priority_class(M);
    std::vector <int> count_class(M.priority_list.size(),0);
    for(int i=0;i<M.size();++i){
        if(!M[i].SS&&!M[i].SF){
            count_class[M[i].priority_class]+=1;
        }
    }
    for(int i=0;i<M.priority_list.size();++i){
        printf("  class  %d  number  %d\n",i,count_class[i]);
    }
    print_time(time,"# ... took :");

    // fiber positioners
    PP pp;
    pp.read_fiber_positions(F);
    F.Nfiber = pp.fp.size()/2;
    F.Npetal = max(pp.spectrom)+1;
    F.Nfbp = (int) (F.Nfiber/F.Npetal);// fibers per petal = 500
    pp.get_neighbors(F);
    pp.compute_fibsofsp(F);

    //P is original list of plates
    bool savetime=true;
    Plates P = read_plate_centers(F);
    F.Nplate=P.size();
    printf("# Read %s plate centers from %s and %d fibers from %s\n",f(F.Nplate).c_str(),F.tileFile.c_str(),F.Nfiber,F.fibFile.c_str());
    // Computes geometries of cb and fh: pieces of positioner - used to determine possible collisions
    F.cb = create_cb(); // cb=central body
    F.fh = create_fh(); // fh=fiber holder
    const char *filecheck="/project/projectdirs/desi/users/rncahn/large_mock_test/tmp/fiberassign/save_av_gals_00004.fits";
    //// Collect available galaxies <-> tilefibers --------------------
    // HTM Tree of galaxies

    std::ifstream infile(filecheck);
    if(!infile.good()||!savetime){//av_gals has not been saved yet or not saving time *************

    const double MinTreeSize = 0.01;
    init_time_at(time,"# Start building HTM tree",t);
    htmTree<struct target> T(M,MinTreeSize);
    print_time(time,"# ... took :");//T.stats();
    init_time_at(time,"# collect galaxies at ",t);

    // For plates/fibers, collect available galaxies; done in parallel  P[plate j].av_gal[k]=[g1,g2,..]
    collect_galaxies_for_all(M,T,P,pp,F);

    print_time(time,"# ... took :");//T.stats();
    init_time_at(time,"# collect available tile-fibers at",t);

    // For each galaxy, computes available tilefibers  G[i].av_tfs = [(j1,k1),(j2,k2),..]
    collect_available_tilefibers(M,P,F);

    } else { //  av_gals have been saved
          // each new epoch has shorter list of tiles
          size_t cfilesize = 512;
	  char filename[cfilesize];
          printf(" F.Nplate = %d \n",F.Nplate);
	  std::cout.flush();
	  for(int j=0;j<F.Nplate;j++){
	    Table av_gals;
	    bool diagnose;
	    int ret = snprintf(filename, cfilesize, "%s/save_av_gals_%05d.fits", F.outDir.c_str(), P[j].tileid);
	    //if(diagnose)printf(" saved file %s \n",filename);
	    read_save_av_gals(filename,  F,av_gals,diagnose);
	    P[j].av_gals=av_gals;
	    //if(diagnose)printf(" after read_save \n");
	    std::cout.flush();
	  }
    }
    //results_on_inputs("doc/figs/",G,P,F,true);

    //save available galaxies for each tile-fiber

    if(!infile.good() && savetime){//first epoch only, write files
        printf("no files there\n");
        for (int j=0; j<F.Nplate; j++){
	    write_save_av_gals(j,F.outDir,M,P,pp,F);

        }
    }else{
      printf("save files already there\n");
      std::cout.flush();

    }
    //search for particular targetid
    for(int j=0;j<F.Nplate;++j){
      for(int k=0;k<F.Nfiber;++k){
	for(int m=0;m<P[j].av_gals[k].size();++m){
	  int g=P[j].av_gals[k][m];
	  if(M[g].id==62801214049073){
	    printf(" **** TARGETID = 62801214049073, j = %d, k= %d, P[j].tileid= %d  new? %d\n",j,k,P[j].tileid,infile.good());
	  }
	}
      }
    }

    //// Assignment |||||||||||||||||||||||||||||||||||||||||||||||||||
    printf(" Nplate %d  Ngal %d   Nfiber %d \n", F.Nplate, F.Ngal, F.Nfiber);
    Assignment A(M,F);
    // Make a plan ----------------------------------------------------
    print_time(t,"# Start assignment at : ");
    simple_assign(M,P,pp,F,A);

    //check to see if there are tiles with no galaxies
    //need to keep mapping of old tile list to new tile list
    //and inverse map
    A.inv_order=initList(F.Nplate,-1);
    int inv_count=0;
    for (int j=0;j<F.Nplate ;++j){

        bool not_done=true;
        for(int k=0;k<F.Nfiber && not_done;++k){
            if(A.TF[j][k]!=-1){
                A.suborder.push_back(j);//suborder[jused] is jused-th used plate
                not_done=false;
                A.inv_order[j]=inv_count;//inv_order[j] is -1 unless used
                inv_count++;
            }
        }
    }
    F.NUsedplate=A.suborder.size();
    printf(" Plates actually used %d \n",F.NUsedplate);

    // Smooth out distribution of free fibers, and increase the number of assignments

    for (int i=0; i<1; i++) redistribute_tf(M,P,pp,F,A,0);// more iterations will improve performance slightly
    for (int i=0; i<3; i++) {
        improve(M,P,pp,F,A,0);
        redistribute_tf(M,P,pp,F,A,0);
    }
    init_time_at(time,"# assign SS and SF ",t);

    //try assigning SF and SS before real time assignment
    for (int jused=0;jused<F.NUsedplate;++jused){

        int j=A.suborder[jused];
        assign_sf_ss(j,M,P,pp,F,A); // Assign SS and SF for each tile
        assign_unused(j,M,P,pp,F,A);
    }

    // Results -------------------------------------------------------*/
    std::vector <int> total_used_by_class(M.priority_list.size(),0);
    int total_used_SS=0;
    int total_used_SF=0;
    for (int jused=0;jused<F.NUsedplate;++jused){
        std::vector <int> used_by_class(M.priority_list.size(),0);
        int used_SS=0;
        int used_SF=0;
        int j=A.suborder[jused];
        for(int k=0;k<F.Nfiber;++k){
            int g=A.TF[j][k];
            if(g!=-1){
	      //search for particular targetid
	      if(M[g].id==62801214049073){
		printf(" **** TARGETID = 62801214049073, j = %d, k= %d, P[j].tileid= %d chosen\n",j,k,P[j].tileid);
	      }

                if(M[g].SS){
                    total_used_SS++;
                    used_SS++;
                    }
                    else if(M[g].SF){
                        used_SF++;
                        total_used_SF++;
                    }
                    else{
                        used_by_class[M[g].priority_class]++;
                        total_used_by_class[M[g].priority_class]++;
                    }
            }
        }
       /* printf(" plate jused %5d j %5d  SS   %4d    SF   %4d",jused,j,used_SS,used_SF);
        for (int pr=0;pr<M.priority_list.size();++pr){
            printf(" class %2d   %5d",pr,used_by_class[pr]);
        }
        printf("\n");
        */
    }
    init_time_at(time,"# count SS and SF ",t);
    printf(" Totals SS   %4d    SF   %4d",total_used_SS,total_used_SF);
    std::cout.flush();
    for (int pr=0;pr<M.priority_list.size();++pr){
        printf(" class %2d   %5d",pr,total_used_by_class[pr]);
        std::cout.flush();
    }

    printf("\n");
    init_time_at(time,"# print txt files ",t);
    if (F.PrintAscii) for (int jused=0; jused<F.NUsedplate; jused++){
        int j=A.suborder[jused];
        write_FAtile_ascii(j,F.outDir,M,P,pp,F,A);
        }
    init_time_at(time,"# print fits files ",t);
    if (F.PrintFits) for (int jused=0; jused<F.NUsedplate; jused++){
        int j=A.suborder[jused];
        fa_write(j,F.outDir,M,P,pp,F,A); // Write output
    }

  print_time(t,"# Finished !... in");

  return(0);
}
<|endoftext|>