<commit_before>// Copyright 2016-2019 Francesco Biscani (bluescarni@gmail.com)
//
// This file is part of the mp++ library.
//
// This Source Code Form is subject to the terms of the Mozilla
// Public License v. 2.0. If a copy of the MPL was not distributed
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.

#include <cstddef>
#include <gmp.h>
#include <random>
#include <tuple>
#include <type_traits>

#include <mp++/integer.hpp>

#include "test_utils.hpp"

#define CATCH_CONFIG_MAIN
#include "catch.hpp"

static int ntries = 1000;

using namespace mppp;
using namespace mppp_test;

using sizes = std::tuple<std::integral_constant<std::size_t, 1>, std::integral_constant<std::size_t, 2>,
                         std::integral_constant<std::size_t, 3>, std::integral_constant<std::size_t, 6>,
                         std::integral_constant<std::size_t, 10>>;

static std::mt19937 rng;

template <std::size_t SSize>
static inline bool check_cmp(const integer<SSize> &a, const integer<SSize> &b, int c2)
{
    const auto c1 = cmp(a, b);

    // Check that the result of cmp is
    // consistent with the operators.
    if (c1 < 0 && !(a < b)) {
        return false;
    }
    if (c1 == 0 && (a != b)) {
        return false;
    }
    if (c1 > 0 && !(a > b)) {
        return false;
    }

    if (c1 < 0) {
        return c2 < 0;
    }
    if (c1 == 0) {
        return c2 == 0;
    }
    return c2 > 0;
}

struct cmp_tester {
    template <typename S>
    inline void operator()(const S &) const
    {
        using integer = integer<S::value>;
        // Start with all zeroes.
        detail::mpz_raii m1, m2;
        integer n1, n2;
        REQUIRE(check_cmp(n1, n2, ::mpz_cmp(&m1.m_mpz, &m2.m_mpz)));
        REQUIRE(n1.is_static());
        REQUIRE(n2.is_static());
        detail::mpz_raii tmp;
        std::uniform_int_distribution<int> sdist(0, 1);
        // Run a variety of tests with operands with x and y number of limbs.
        auto random_xy = [&](unsigned x, unsigned y) {
            for (int i = 0; i < ntries; ++i) {
                random_integer(tmp, x, rng);
                ::mpz_set(&m1.m_mpz, &tmp.m_mpz);
                n1 = integer(detail::mpz_to_str(&tmp.m_mpz));
                if (sdist(rng)) {
                    ::mpz_neg(&m1.m_mpz, &m1.m_mpz);
                    n1.neg();
                }
                if (n1.is_static() && sdist(rng)) {
                    // Promote sometimes, if possible.
                    n1.promote();
                }
                random_integer(tmp, y, rng);
                ::mpz_set(&m2.m_mpz, &tmp.m_mpz);
                n2 = integer(detail::mpz_to_str(&tmp.m_mpz));
                if (sdist(rng)) {
                    ::mpz_neg(&m2.m_mpz, &m2.m_mpz);
                    n2.neg();
                }
                if (n2.is_static() && sdist(rng)) {
                    // Promote sometimes, if possible.
                    n2.promote();
                }
                REQUIRE(check_cmp(n1, n2, ::mpz_cmp(&m1.m_mpz, &m2.m_mpz)));
                REQUIRE(check_cmp(n1, n1, ::mpz_cmp(&m1.m_mpz, &m1.m_mpz)));
                REQUIRE(check_cmp(n2, n2, ::mpz_cmp(&m2.m_mpz, &m2.m_mpz)));
                REQUIRE((n1 == n1));
                REQUIRE((n2 == n2));
                if (::mpz_cmp(&m1.m_mpz, &m2.m_mpz)) {
                    REQUIRE((n1 != n2));
                } else {
                    REQUIRE((n1 == n2));
                }
                n2 = n1;
                ::mpz_set(&m2.m_mpz, &m1.m_mpz);
                if (sdist(rng) && n2.is_static()) {
                    n2.promote();
                }
                REQUIRE(check_cmp(n1, n2, ::mpz_cmp(&m1.m_mpz, &m2.m_mpz)));
                // Overlap.
                REQUIRE(check_cmp(n1, n1, ::mpz_cmp(&m1.m_mpz, &m1.m_mpz)));
            }
        };

        random_xy(0, 0);

        random_xy(1, 0);
        random_xy(0, 1);
        random_xy(1, 1);

        random_xy(0, 2);
        random_xy(1, 2);
        random_xy(2, 0);
        random_xy(2, 1);
        random_xy(2, 2);

        random_xy(0, 3);
        random_xy(1, 3);
        random_xy(2, 3);
        random_xy(3, 0);
        random_xy(3, 1);
        random_xy(3, 2);
        random_xy(3, 3);

        random_xy(0, 4);
        random_xy(1, 4);
        random_xy(2, 4);
        random_xy(3, 4);
        random_xy(4, 0);
        random_xy(4, 1);
        random_xy(4, 2);
        random_xy(4, 3);
        random_xy(4, 4);
    }
};

TEST_CASE("cmp")
{
    tuple_for_each(sizes{}, cmp_tester{});
}
<commit_msg>Last minute test addition.<commit_after>// Copyright 2016-2019 Francesco Biscani (bluescarni@gmail.com)
//
// This file is part of the mp++ library.
//
// This Source Code Form is subject to the terms of the Mozilla
// Public License v. 2.0. If a copy of the MPL was not distributed
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.

#include <cstddef>
#include <gmp.h>
#include <random>
#include <tuple>
#include <type_traits>

#include <mp++/integer.hpp>

#include "test_utils.hpp"

#define CATCH_CONFIG_MAIN
#include "catch.hpp"

static int ntries = 1000;

using namespace mppp;
using namespace mppp_test;

using sizes = std::tuple<std::integral_constant<std::size_t, 1>, std::integral_constant<std::size_t, 2>,
                         std::integral_constant<std::size_t, 3>, std::integral_constant<std::size_t, 6>,
                         std::integral_constant<std::size_t, 10>>;

static std::mt19937 rng;

template <std::size_t SSize>
static inline bool check_cmp(const integer<SSize> &a, const integer<SSize> &b, int c2)
{
    const auto c1 = cmp(a, b);

    // Check that the result of cmp is
    // consistent with the operators.
    if (c1 < 0 && !(a < b)) {
        return false;
    }
    if (c1 == 0 && ((a != b) || !(a == b))) {
        return false;
    }
    if (c1 > 0 && !(a > b)) {
        return false;
    }

    if (c1 < 0) {
        return c2 < 0;
    }
    if (c1 == 0) {
        return c2 == 0;
    }
    return c2 > 0;
}

struct cmp_tester {
    template <typename S>
    inline void operator()(const S &) const
    {
        using integer = integer<S::value>;
        // Start with all zeroes.
        detail::mpz_raii m1, m2;
        integer n1, n2;
        REQUIRE(check_cmp(n1, n2, ::mpz_cmp(&m1.m_mpz, &m2.m_mpz)));
        REQUIRE(n1.is_static());
        REQUIRE(n2.is_static());
        detail::mpz_raii tmp;
        std::uniform_int_distribution<int> sdist(0, 1);
        // Run a variety of tests with operands with x and y number of limbs.
        auto random_xy = [&](unsigned x, unsigned y) {
            for (int i = 0; i < ntries; ++i) {
                random_integer(tmp, x, rng);
                ::mpz_set(&m1.m_mpz, &tmp.m_mpz);
                n1 = integer(detail::mpz_to_str(&tmp.m_mpz));
                if (sdist(rng)) {
                    ::mpz_neg(&m1.m_mpz, &m1.m_mpz);
                    n1.neg();
                }
                if (n1.is_static() && sdist(rng)) {
                    // Promote sometimes, if possible.
                    n1.promote();
                }
                random_integer(tmp, y, rng);
                ::mpz_set(&m2.m_mpz, &tmp.m_mpz);
                n2 = integer(detail::mpz_to_str(&tmp.m_mpz));
                if (sdist(rng)) {
                    ::mpz_neg(&m2.m_mpz, &m2.m_mpz);
                    n2.neg();
                }
                if (n2.is_static() && sdist(rng)) {
                    // Promote sometimes, if possible.
                    n2.promote();
                }
                REQUIRE(check_cmp(n1, n2, ::mpz_cmp(&m1.m_mpz, &m2.m_mpz)));
                REQUIRE(check_cmp(n1, n1, ::mpz_cmp(&m1.m_mpz, &m1.m_mpz)));
                REQUIRE(check_cmp(n2, n2, ::mpz_cmp(&m2.m_mpz, &m2.m_mpz)));
                REQUIRE((n1 == n1));
                REQUIRE((n2 == n2));
                if (::mpz_cmp(&m1.m_mpz, &m2.m_mpz)) {
                    REQUIRE((n1 != n2));
                } else {
                    REQUIRE((n1 == n2));
                }
                n2 = n1;
                ::mpz_set(&m2.m_mpz, &m1.m_mpz);
                if (sdist(rng) && n2.is_static()) {
                    n2.promote();
                }
                REQUIRE(check_cmp(n1, n2, ::mpz_cmp(&m1.m_mpz, &m2.m_mpz)));
                // Overlap.
                REQUIRE(check_cmp(n1, n1, ::mpz_cmp(&m1.m_mpz, &m1.m_mpz)));
            }
        };

        random_xy(0, 0);

        random_xy(1, 0);
        random_xy(0, 1);
        random_xy(1, 1);

        random_xy(0, 2);
        random_xy(1, 2);
        random_xy(2, 0);
        random_xy(2, 1);
        random_xy(2, 2);

        random_xy(0, 3);
        random_xy(1, 3);
        random_xy(2, 3);
        random_xy(3, 0);
        random_xy(3, 1);
        random_xy(3, 2);
        random_xy(3, 3);

        random_xy(0, 4);
        random_xy(1, 4);
        random_xy(2, 4);
        random_xy(3, 4);
        random_xy(4, 0);
        random_xy(4, 1);
        random_xy(4, 2);
        random_xy(4, 3);
        random_xy(4, 4);
    }
};

TEST_CASE("cmp")
{
    tuple_for_each(sizes{}, cmp_tester{});
}
<|endoftext|>


<commit_before>#include "tester.hpp"
#include "../sago/platform_folders.h"
#include <string>
#include <vector>

// This is all tests in one
int main() {
	// Test plain functions
	run_test(sago::getConfigHome());
	run_test(sago::getDataHome());
	run_test(sago::getCacheDir());
	// Test non-member functions
	run_test(sago::getDesktopFolder());
	run_test(sago::getDocumentsFolder());
	run_test(sago::getDownloadFolder1());
	run_test(sago::getPicturesFolder());
	run_test(sago::getMusicFolder());
	run_test(sago::getVideoFolder());
	run_test(sago::getSaveGamesFolder1());
	// Test class methods
	sago::PlatformFolders p;
	run_test(p.getDocumentsFolder());
	run_test(p.getDesktopFolder());
	run_test(p.getPicturesFolder());
	run_test(p.getMusicFolder());
	run_test(p.getVideoFolder());
	run_test(p.getDownloadFolder1());
	run_test(p.getSaveGamesFolder1());
	// Test vector function
	std::vector<std::string> extraData;
	sago::appendAdditionalDataDirectories(extraData);
	run_test(extraData);
	return 0;
}
<commit_msg>Added the new functions to test<commit_after>#include "tester.hpp"
#include "../sago/platform_folders.h"
#include <string>
#include <vector>

// This is all tests in one
int main() {
	// Test plain functions
	run_test(sago::getConfigHome());
	run_test(sago::getDataHome());
	run_test(sago::getCacheDir());
	// Test non-member functions
	run_test(sago::getDesktopFolder());
	run_test(sago::getDocumentsFolder());
	run_test(sago::getDownloadFolder());
	run_test(sago::getDownloadFolder1());
	run_test(sago::getPicturesFolder());
	run_test(sago::getMusicFolder());
	run_test(sago::getVideoFolder());
	run_test(sago::getSaveGamesFolder1());
	run_test(sago::getSaveGamesFolder2());
	// Test class methods
	sago::PlatformFolders p;
	run_test(p.getDocumentsFolder());
	run_test(p.getDesktopFolder());
	run_test(p.getPicturesFolder());
	run_test(p.getMusicFolder());
	run_test(p.getVideoFolder());
	run_test(p.getDownloadFolder1());
	run_test(p.getSaveGamesFolder1());
	// Test vector function
	std::vector<std::string> extraData;
	sago::appendAdditionalDataDirectories(extraData);
	run_test(extraData);
	return 0;
}
<|endoftext|>


<commit_before>/* Copyright 2007-2015 QReal Research Group
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License. */

#include "paletteTreeWidgets.h"

#include <models/exploser.h>

#include <qrgui/models/models.h>

#include "mainWindow/palette/paletteTree.h"
#include "mainWindow/palette/draggableElement.h"

using namespace qReal;
using namespace gui;

PaletteTreeWidgets::PaletteTreeWidgets(PaletteTree &parent, MainWindow *mainWindow
		, EditorManagerInterface &editorManagerProxy)
	: QSplitter(Qt::Vertical)
	, mEditorManager(&editorManagerProxy)
	, mParentPalette(&parent)
	, mMainWindow(mainWindow)
	, mEditorTree(new PaletteTreeWidget(parent, *mainWindow, editorManagerProxy, false))
	, mUserTree(new PaletteTreeWidget(parent, *mainWindow, editorManagerProxy, true))
{
	initWidgets();
}

PaletteTreeWidgets::PaletteTreeWidgets(PaletteTree &parent, MainWindow *mainWindow
		, EditorManagerInterface &editorManagerProxy
		, const Id &editor, const Id &diagram)
	: QSplitter(Qt::Vertical)
	, mParentPalette(&parent)
	, mMainWindow(mainWindow)
	, mEditor(editor)
	, mDiagram(diagram)
	, mEditorTree(new PaletteTreeWidget(parent, *mainWindow, editorManagerProxy, false))
	, mUserTree(new PaletteTreeWidget(parent, *mainWindow, editorManagerProxy, true))
{
	mEditorManager = &editorManagerProxy;
	initWidgets();
	initEditorTree();
	initUserTree();
}

void PaletteTreeWidgets::initWidgets()
{
	initWidget(mEditorTree);
	initWidget(mUserTree);
}

void PaletteTreeWidgets::initWidget(PaletteTreeWidget * const tree)
{
	tree->setHeaderHidden(true);
	tree->setSelectionMode(QAbstractItemView::NoSelection);
	addWidget(tree);
}

void PaletteTreeWidgets::initEditorTree()
{
	IdList elements = mEditorManager->elements(mDiagram) + mEditorManager->groups(mDiagram);
	const bool sort = mEditorManager->shallPaletteBeSorted(mEditor, mDiagram);
	if (sort) {
		PaletteTreeWidget::sortByFriendlyName(elements);
	}

	if (!mEditorManager->paletteGroups(mEditor, mDiagram).empty()) {
		QList<QPair<QString, QList<PaletteElement>>> groups;
		QMap<QString, QString> descriptions;
		for (const QString &group : mEditorManager->paletteGroups(mEditor, mDiagram)) {
			const QStringList paletteGroup = mEditorManager->paletteGroupList(mEditor, mDiagram, group);
			QList<PaletteElement> groupElements;
			for (const QString &name : paletteGroup) {
				for (const Id &element : elements) {
					if (element.element() == name) {
						groupElements << PaletteElement(*mEditorManager, element);
						break;
					}
				}
			}

			groups << qMakePair(group, groupElements);
			descriptions[group] = mEditorManager->paletteGroupDescription(mEditor, mDiagram, group);
		}

		mEditorTree->addGroups(groups, descriptions, false, mEditorManager->friendlyName(mDiagram), sort);
	} else {
		for (const Id &element : elements) {
			addTopItemType(PaletteElement(*mEditorManager, element), mEditorTree);
		}
	}
}

void PaletteTreeWidgets::initUserTree()
{
	refreshUserPalette();
	connect(&mMainWindow->models().exploser(), &models::Exploser::explosionsSetCouldChange
			, this, &PaletteTreeWidgets::refreshUserPalette);
}

void PaletteTreeWidgets::addTopItemType(const PaletteElement &data, QTreeWidget *tree)
{
	QTreeWidgetItem *item = new QTreeWidgetItem;
	DraggableElement *element = new DraggableElement(*mMainWindow, data
			, mParentPalette->iconsView(), *mEditorManager);

	mPaletteElements.insert(data.id(), element);

	tree->addTopLevelItem(item);
	tree->setItemWidget(item, 0, element);
}

void PaletteTreeWidgets::resizeIcons()
{
	if (mParentPalette->iconsView() && mParentPalette->itemsCountInARow() > 1) {
		const int iconSize = 48;
		const int widgetSize = this->size().width() - (iconSize << 1);
		const int itemsCount = maxItemsCountInARow();
		const int newSize = (widgetSize < itemsCount * iconSize)
				? (widgetSize / itemsCount) : iconSize;
		for (int i = 0; i < mEditorTree->topLevelItemCount(); i++) {
			for (int j = 0; j < mEditorTree->topLevelItem(i)->childCount(); j++) {
				QWidget *field = mEditorTree->itemWidget(mEditorTree->topLevelItem(i)->child(j), 0);
				if (!field) {
					break;
				}

				foreach (QObject *child, field->children()) {
					DraggableElement *element = dynamic_cast<DraggableElement*>(child);
					if (element) {
						element->setIconSize(newSize);
					}
				}
			}
		}
	}
}

int PaletteTreeWidgets::maxItemsCountInARow() const
{
	int max = 0;
	for (int i = 0; i < mEditorTree->topLevelItemCount(); i++) {
		for (int j = 0; j < mEditorTree->topLevelItem(i)->childCount(); j++) {
			QWidget *field = mEditorTree->itemWidget(mEditorTree->topLevelItem(i)->child(j), 0);
			if (!field) {
				break;
			}

			int itemsCount = field->children().count();
			if (itemsCount > max) {
				max = itemsCount;
			}
		}
	}
	return max;
}

void PaletteTreeWidgets::expand()
{
	mEditorTree->expand();
	mEditorTree->expand();
}

void PaletteTreeWidgets::collapse()
{
	mEditorTree->collapse();
	mUserTree->collapse();
}

void PaletteTreeWidgets::saveConfiguration(const QString &title) const
{
	saveConfiguration(mEditorTree, title);
	saveConfiguration(mUserTree, title);
}

void PaletteTreeWidgets::saveConfiguration(const PaletteTreeWidget *tree, const QString &title) const
{
	for (int j = 0; j < tree->topLevelItemCount(); j++) {
		const QTreeWidgetItem *topItem = tree->topLevelItem(j);
		if (topItem) {
			SettingsManager::setValue(title, topItem->isExpanded());
		}
	}
}

void PaletteTreeWidgets::setElementVisible(const Id &metatype, bool visible)
{
	if (mPaletteElements.contains(metatype)) {
		mPaletteElements[metatype]->setVisible(visible);
	} else {
		mEditorTree->setElementVisible(metatype, visible);
	}
}

void PaletteTreeWidgets::setVisibleForAllElements(bool visible)
{
	for (QWidget * const element : mPaletteElements.values()) {
		element->setVisible(visible);
	}

	mEditorTree->setVisibleForAllElements(visible);
}

void PaletteTreeWidgets::setElementEnabled(const Id &metatype, bool enabled)
{
	if (mPaletteElements.contains(metatype)) {
		mPaletteElements[metatype]->setEnabled(enabled);
	} else {
		mEditorTree->setElementEnabled(metatype, enabled);
	}
}

void PaletteTreeWidgets::setEnabledForAllElements(bool enabled)
{
	for (QWidget * const element : mPaletteElements.values()) {
		element->setEnabled(enabled);
	}

	mEditorTree->setEnabledForAllElements(enabled);
}

void PaletteTreeWidgets::customizeExplosionTitles(const QString &userGroupTitle, const QString &userGroupDescription)
{
	mUserGroupTitle = userGroupTitle;
	mUserGroupDescription = userGroupDescription;
}

void PaletteTreeWidgets::refreshUserPalette()
{
	QList<QPair<QString, QList<gui::PaletteElement>>> groups;
	QMap<QString, QString> descriptions = { { mUserGroupTitle, mUserGroupDescription } };
	QList<gui::PaletteElement> groupElements;

	QMultiMap<Id, Id> const types = mMainWindow->models().exploser().explosions(mDiagram);
	for (const Id &source : types.uniqueKeys()) {
		for (const Id &target : types.values(source)) {
			groupElements << gui::PaletteElement(source
					, mMainWindow->models().logicalRepoApi().name(target)
					, QString(), mEditorManager->icon(source)
					, mEditorManager->iconSize(source)
					, target);
		}
	}

	if (!groupElements.isEmpty()) {
		groups << qMakePair(mUserGroupTitle, groupElements);
	}

	// This condition will fiter out most of the cases.
	if (groupElements.toSet() != mUserTree->elementsSet()) {
		mUserTree->addGroups(groups, descriptions, true, mEditorManager->friendlyName(mDiagram), true);
	} else if (groupElements.isEmpty()) {
		mUserTree->hide();
	}
}

void PaletteTreeWidgets::filter(const QRegExp &regexp)
{
	mEditorTree->filter(regexp);
	mUserTree->filter(regexp);
}
<commit_msg>Typo fixed<commit_after>/* Copyright 2007-2015 QReal Research Group
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License. */

#include "paletteTreeWidgets.h"

#include <models/exploser.h>

#include <qrgui/models/models.h>

#include "mainWindow/palette/paletteTree.h"
#include "mainWindow/palette/draggableElement.h"

using namespace qReal;
using namespace gui;

PaletteTreeWidgets::PaletteTreeWidgets(PaletteTree &parent, MainWindow *mainWindow
		, EditorManagerInterface &editorManagerProxy)
	: QSplitter(Qt::Vertical)
	, mEditorManager(&editorManagerProxy)
	, mParentPalette(&parent)
	, mMainWindow(mainWindow)
	, mEditorTree(new PaletteTreeWidget(parent, *mainWindow, editorManagerProxy, false))
	, mUserTree(new PaletteTreeWidget(parent, *mainWindow, editorManagerProxy, true))
{
	initWidgets();
}

PaletteTreeWidgets::PaletteTreeWidgets(PaletteTree &parent, MainWindow *mainWindow
		, EditorManagerInterface &editorManagerProxy
		, const Id &editor, const Id &diagram)
	: QSplitter(Qt::Vertical)
	, mParentPalette(&parent)
	, mMainWindow(mainWindow)
	, mEditor(editor)
	, mDiagram(diagram)
	, mEditorTree(new PaletteTreeWidget(parent, *mainWindow, editorManagerProxy, false))
	, mUserTree(new PaletteTreeWidget(parent, *mainWindow, editorManagerProxy, true))
{
	mEditorManager = &editorManagerProxy;
	initWidgets();
	initEditorTree();
	initUserTree();
}

void PaletteTreeWidgets::initWidgets()
{
	initWidget(mEditorTree);
	initWidget(mUserTree);
}

void PaletteTreeWidgets::initWidget(PaletteTreeWidget * const tree)
{
	tree->setHeaderHidden(true);
	tree->setSelectionMode(QAbstractItemView::NoSelection);
	addWidget(tree);
}

void PaletteTreeWidgets::initEditorTree()
{
	IdList elements = mEditorManager->elements(mDiagram) + mEditorManager->groups(mDiagram);
	const bool sort = mEditorManager->shallPaletteBeSorted(mEditor, mDiagram);
	if (sort) {
		PaletteTreeWidget::sortByFriendlyName(elements);
	}

	if (!mEditorManager->paletteGroups(mEditor, mDiagram).empty()) {
		QList<QPair<QString, QList<PaletteElement>>> groups;
		QMap<QString, QString> descriptions;
		for (const QString &group : mEditorManager->paletteGroups(mEditor, mDiagram)) {
			const QStringList paletteGroup = mEditorManager->paletteGroupList(mEditor, mDiagram, group);
			QList<PaletteElement> groupElements;
			for (const QString &name : paletteGroup) {
				for (const Id &element : elements) {
					if (element.element() == name) {
						groupElements << PaletteElement(*mEditorManager, element);
						break;
					}
				}
			}

			groups << qMakePair(group, groupElements);
			descriptions[group] = mEditorManager->paletteGroupDescription(mEditor, mDiagram, group);
		}

		mEditorTree->addGroups(groups, descriptions, false, mEditorManager->friendlyName(mDiagram), sort);
	} else {
		for (const Id &element : elements) {
			addTopItemType(PaletteElement(*mEditorManager, element), mEditorTree);
		}
	}
}

void PaletteTreeWidgets::initUserTree()
{
	refreshUserPalette();
	connect(&mMainWindow->models().exploser(), &models::Exploser::explosionsSetCouldChange
			, this, &PaletteTreeWidgets::refreshUserPalette);
}

void PaletteTreeWidgets::addTopItemType(const PaletteElement &data, QTreeWidget *tree)
{
	QTreeWidgetItem *item = new QTreeWidgetItem;
	DraggableElement *element = new DraggableElement(*mMainWindow, data
			, mParentPalette->iconsView(), *mEditorManager);

	mPaletteElements.insert(data.id(), element);

	tree->addTopLevelItem(item);
	tree->setItemWidget(item, 0, element);
}

void PaletteTreeWidgets::resizeIcons()
{
	if (mParentPalette->iconsView() && mParentPalette->itemsCountInARow() > 1) {
		const int iconSize = 48;
		const int widgetSize = this->size().width() - (iconSize << 1);
		const int itemsCount = maxItemsCountInARow();
		const int newSize = (widgetSize < itemsCount * iconSize)
				? (widgetSize / itemsCount) : iconSize;
		for (int i = 0; i < mEditorTree->topLevelItemCount(); i++) {
			for (int j = 0; j < mEditorTree->topLevelItem(i)->childCount(); j++) {
				QWidget *field = mEditorTree->itemWidget(mEditorTree->topLevelItem(i)->child(j), 0);
				if (!field) {
					break;
				}

				foreach (QObject *child, field->children()) {
					DraggableElement *element = dynamic_cast<DraggableElement*>(child);
					if (element) {
						element->setIconSize(newSize);
					}
				}
			}
		}
	}
}

int PaletteTreeWidgets::maxItemsCountInARow() const
{
	int max = 0;
	for (int i = 0; i < mEditorTree->topLevelItemCount(); i++) {
		for (int j = 0; j < mEditorTree->topLevelItem(i)->childCount(); j++) {
			QWidget *field = mEditorTree->itemWidget(mEditorTree->topLevelItem(i)->child(j), 0);
			if (!field) {
				break;
			}

			int itemsCount = field->children().count();
			if (itemsCount > max) {
				max = itemsCount;
			}
		}
	}
	return max;
}

void PaletteTreeWidgets::expand()
{
	mEditorTree->expand();
	mEditorTree->expand();
}

void PaletteTreeWidgets::collapse()
{
	mEditorTree->collapse();
	mUserTree->collapse();
}

void PaletteTreeWidgets::saveConfiguration(const QString &title) const
{
	saveConfiguration(mEditorTree, title);
	saveConfiguration(mUserTree, title);
}

void PaletteTreeWidgets::saveConfiguration(const PaletteTreeWidget *tree, const QString &title) const
{
	for (int j = 0; j < tree->topLevelItemCount(); j++) {
		const QTreeWidgetItem *topItem = tree->topLevelItem(j);
		if (topItem) {
			SettingsManager::setValue(title, topItem->isExpanded());
		}
	}
}

void PaletteTreeWidgets::setElementVisible(const Id &metatype, bool visible)
{
	if (mPaletteElements.contains(metatype)) {
		mPaletteElements[metatype]->setVisible(visible);
	} else {
		mEditorTree->setElementVisible(metatype, visible);
	}
}

void PaletteTreeWidgets::setVisibleForAllElements(bool visible)
{
	for (QWidget * const element : mPaletteElements.values()) {
		element->setVisible(visible);
	}

	mEditorTree->setVisibleForAllElements(visible);
}

void PaletteTreeWidgets::setElementEnabled(const Id &metatype, bool enabled)
{
	if (mPaletteElements.contains(metatype)) {
		mPaletteElements[metatype]->setEnabled(enabled);
	} else {
		mEditorTree->setElementEnabled(metatype, enabled);
	}
}

void PaletteTreeWidgets::setEnabledForAllElements(bool enabled)
{
	for (QWidget * const element : mPaletteElements.values()) {
		element->setEnabled(enabled);
	}

	mEditorTree->setEnabledForAllElements(enabled);
}

void PaletteTreeWidgets::customizeExplosionTitles(const QString &userGroupTitle, const QString &userGroupDescription)
{
	mUserGroupTitle = userGroupTitle;
	mUserGroupDescription = userGroupDescription;
}

void PaletteTreeWidgets::refreshUserPalette()
{
	QList<QPair<QString, QList<gui::PaletteElement>>> groups;
	QMap<QString, QString> descriptions = { { mUserGroupTitle, mUserGroupDescription } };
	QList<gui::PaletteElement> groupElements;

	QMultiMap<Id, Id> const types = mMainWindow->models().exploser().explosions(mDiagram);
	for (const Id &source : types.uniqueKeys()) {
		for (const Id &target : types.values(source)) {
			groupElements << gui::PaletteElement(source
					, mMainWindow->models().logicalRepoApi().name(target)
					, QString(), mEditorManager->icon(source)
					, mEditorManager->iconSize(source)
					, target);
		}
	}

	if (!groupElements.isEmpty()) {
		groups << qMakePair(mUserGroupTitle, groupElements);
	}

	// This condition will filter out most of the cases.
	if (groupElements.toSet() != mUserTree->elementsSet()) {
		mUserTree->addGroups(groups, descriptions, true, mEditorManager->friendlyName(mDiagram), true);
	} else if (groupElements.isEmpty()) {
		mUserTree->hide();
	}
}

void PaletteTreeWidgets::filter(const QRegExp &regexp)
{
	mEditorTree->filter(regexp);
	mUserTree->filter(regexp);
}
<|endoftext|>


<commit_before>/*=========================================================================

Program:   Medical Imaging & Interaction Toolkit
Module:    $RCSfile$
Language:  C++
Date:      $Date$
Version:   $Revision$

Copyright (c) German Cancer Research Center, Division of Medickal and
Biological Informatics. All rights reserved.
See MITKCopyright.txt or http://www.mitk.org/ for details.

This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE.  See the above copyright notices for more information.

=========================================================================*/

#include "SampleApp.h"

#include <QmitkStdMultiWidget.h>
#include <QmitkSelectableGLWidget.h>
#include <QmitkCommonFunctionality.h>

#include <mitkStatusBar.h>

#include <QmitkFunctionality.h>
#include <QmitkFunctionalityFactory.h>
#include <QmitkFctMediator.h>
#include <QmitkControlsRightFctLayoutTemplate.h>
#include <QmitkControlsLeftFctLayoutTemplate.h>

#include <qlayout.h>

void RegisterFunctionalities();

SampleApp::SampleApp( QWidget* parent, const char* name, WFlags fl, const char* testingParameter ):
QmitkMainTemplate( parent, name, fl ), m_ControlsLeft ( false ), m_TestingParameter(testingParameter)
{
  RegisterFunctionalities();
  this->setCaption("MITK Application");
  std::cout << "Instantiating new SampleApp..." << std::endl;

  QmitkMainTemplate::Initialize();

  parseCommandLine();

  connect (this, SIGNAL(ShowWidgetPlanesToggled(bool)), this, SLOT(SetWidgetPlanesEnabled(bool)));
  resize(1024,768);

}
/*
*  Destroys the object and frees any allocated resources
*/
SampleApp::~SampleApp()
{
  // no need to delete child widgets, Qt does it all for us
}

void SampleApp::InitializeFunctionality()
{
  m_MultiWidget->mitkWidget4->GetRenderer()->SetMapperID(2);
  //create and add functionalities. Functionalities are also invisible objects, which can be asked to
  //create their different parts (main widget, control widget, toolbutton for selection).
  mitk::DataTreePreOrderIterator iterator(m_Tree);

  QmitkFunctionalityFactory& qff = QmitkFunctionalityFactory::GetInstance();
  for (std::list<QmitkFunctionalityFactory::CreateFunctionalityPtr>::const_iterator it = qff.GetCreateFunctionalityPtrList().begin() ; it != qff.GetCreateFunctionalityPtrList().end(); it++) {
    QmitkFunctionality* functionalityInstance = (*it)(qfm,m_MultiWidget,&iterator);
    if (!m_TestingParameter || strcmp(m_TestingParameter,functionalityInstance->GetFunctionalityName().ascii()) == 0) {
      qfm->AddFunctionality(functionalityInstance);
    }
  }

  mitk::StatusBar::GetInstance()->DisplayText("Functionalities added",3000);
}

void SampleApp::InitializeQfm()
{
  if (m_ControlsLeft) {
    //create an QmitkFctMediator. This is an invisible object that controls, manages and mediates functionalities
    qfm=new QmitkFctMediator(this);

    //create an QmitkButtonFctLayoutTemplate. This is an simple example for an layout of the different widgets, of which
    //a functionality and the management consists: the main widget, the control widget and a menu for selecting the
    //active functionality.
    QmitkControlsLeftFctLayoutTemplate* layoutTemplate=new QmitkControlsLeftFctLayoutTemplate(this, "LayoutTemplate");
    setCentralWidget(layoutTemplate);

    //let the QmitkFctMediator know about the layout. This includes the toolbar and the layoutTemplate.
    qfm->Initialize(this);
  }
  else
  {
    QmitkMainTemplate::InitializeQfm();
  }
}

void SampleApp::SetWidgetPlanesEnabled(bool enable)
{
  CommonFunctionality::SetWidgetPlanesEnabled(m_Tree, enable);
  mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
<commit_msg>FIX: check QObject::name() instead of (possibly) different GetFunctionalityName() for testing mode<commit_after>/*=========================================================================

Program:   Medical Imaging & Interaction Toolkit
Module:    $RCSfile$
Language:  C++
Date:      $Date$
Version:   $Revision$

Copyright (c) German Cancer Research Center, Division of Medickal and
Biological Informatics. All rights reserved.
See MITKCopyright.txt or http://www.mitk.org/ for details.

This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE.  See the above copyright notices for more information.

=========================================================================*/

#include "SampleApp.h"

#include <QmitkStdMultiWidget.h>
#include <QmitkSelectableGLWidget.h>
#include <QmitkCommonFunctionality.h>

#include <mitkStatusBar.h>

#include <QmitkFunctionality.h>
#include <QmitkFunctionalityFactory.h>
#include <QmitkFctMediator.h>
#include <QmitkControlsRightFctLayoutTemplate.h>
#include <QmitkControlsLeftFctLayoutTemplate.h>

#include <qlayout.h>

void RegisterFunctionalities();

SampleApp::SampleApp( QWidget* parent, const char* name, WFlags fl, const char* testingParameter ):
QmitkMainTemplate( parent, name, fl ), m_ControlsLeft ( false ), m_TestingParameter(testingParameter)
{
  RegisterFunctionalities();
  this->setCaption("MITK Application");
  std::cout << "Instantiating new SampleApp..." << std::endl;

  QmitkMainTemplate::Initialize();

  parseCommandLine();

  connect (this, SIGNAL(ShowWidgetPlanesToggled(bool)), this, SLOT(SetWidgetPlanesEnabled(bool)));
  resize(1024,768);

}
/*
*  Destroys the object and frees any allocated resources
*/
SampleApp::~SampleApp()
{
  // no need to delete child widgets, Qt does it all for us
}

void SampleApp::InitializeFunctionality()
{
  m_MultiWidget->mitkWidget4->GetRenderer()->SetMapperID(2);
  //create and add functionalities. Functionalities are also invisible objects, which can be asked to
  //create their different parts (main widget, control widget, toolbutton for selection).
  mitk::DataTreePreOrderIterator iterator(m_Tree);

  QmitkFunctionalityFactory& qff = QmitkFunctionalityFactory::GetInstance();
  for (std::list<QmitkFunctionalityFactory::CreateFunctionalityPtr>::const_iterator it = qff.GetCreateFunctionalityPtrList().begin() ; it != qff.GetCreateFunctionalityPtrList().end(); it++) {
    QmitkFunctionality* functionalityInstance = (*it)(qfm,m_MultiWidget,&iterator);
    if (!m_TestingParameter) {
      qfm->AddFunctionality(functionalityInstance);
    } else if (strcmp(m_TestingParameter,functionalityInstance->name()) == 0) {
      std::cout << "adding selected " << functionalityInstance->name() << std::endl;
      qfm->AddFunctionality(functionalityInstance);
    } else {
      std::cout << "rejecting functionality " << functionalityInstance->name() << std::endl;
    }
  }

  mitk::StatusBar::GetInstance()->DisplayText("Functionalities added",3000);
}

void SampleApp::InitializeQfm()
{
  if (m_ControlsLeft) {
    //create an QmitkFctMediator. This is an invisible object that controls, manages and mediates functionalities
    qfm=new QmitkFctMediator(this);

    //create an QmitkButtonFctLayoutTemplate. This is an simple example for an layout of the different widgets, of which
    //a functionality and the management consists: the main widget, the control widget and a menu for selecting the
    //active functionality.
    QmitkControlsLeftFctLayoutTemplate* layoutTemplate=new QmitkControlsLeftFctLayoutTemplate(this, "LayoutTemplate");
    setCentralWidget(layoutTemplate);

    //let the QmitkFctMediator know about the layout. This includes the toolbar and the layoutTemplate.
    qfm->Initialize(this);
  }
  else
  {
    QmitkMainTemplate::InitializeQfm();
  }
}

void SampleApp::SetWidgetPlanesEnabled(bool enable)
{
  CommonFunctionality::SetWidgetPlanesEnabled(m_Tree, enable);
  mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
<|endoftext|>


<commit_before>/*
 * DroidMaintenanceSessionImplementation.cpp
 *
 *  Created on: 1 13, 2015
 *      Author: Klivian
 */

#include "server/zone/objects/player/sessions/DroidMaintenanceSession.h"
#include "server/zone/Zone.h"
#include "server/zone/objects/creature/CreatureObject.h"
#include "server/zone/objects/player/PlayerObject.h"
#include "server/zone/objects/player/sui/SuiWindowType.h"
#include "server/zone/objects/player/sessions/sui/DroidMaintenanceSessionRunMenuSuiCallback.h"
#include "server/zone/objects/player/sessions/sui/DroidMaintenanceSessionAddCreditsSuiCallback.h"
#include "server/zone/objects/player/sui/listbox/SuiListBox.h"
#include "server/zone/objects/player/sui/transferbox/SuiTransferBox.h"
#include "server/zone/objects/tangible/components/droid/DroidMaintenanceModuleDataComponent.h"
#include "server/zone/objects/structure/StructureObject.h"
#include "server/zone/objects/intangible/tasks/StorePetTask.h"
#include "server/zone/managers/planet/PlanetManager.h"

void DroidMaintenanceSessionImplementation::initialize() {
	ManagedReference<CreatureObject*> creature = this->player.get();
	ManagedReference<DroidMaintenanceModuleDataComponent*> module = this->maintModule.get();
	// get the total credits this guy has right now!
	availableCredits = creature->getCashCredits() + creature->getBankCredits();
	module->getStructureList(&structures, creature->getZoneServer(),creature->getZone()->getZoneCRC());
	maintenance.removeAll();
	selectedFees = 0;
	fees.removeAll();
}

void DroidMaintenanceSessionImplementation::sendMaintanceRunBox(){
	// main ui
	selectedStructure = NULL;

	ManagedReference<CreatureObject*> creature = this->player.get();

	if (structures.size() == 0 && maintenance.isEmpty()) {
		creature->sendSystemMessage("@pet/droid_modules:droid_maint_no_valid_struct");
		cancelSession();
		return;
	}

	ManagedReference<DroidMaintenanceModuleDataComponent*> module = this->maintModule.get();

	ManagedReference<SuiListBox*> box = new SuiListBox(creature, SuiWindowType::DROID_MAINTENANCE_RUN_LIST, SuiListBox::HANDLETHREEBUTTON);
	box->setCallback(new DroidMaintenanceSessionRunMenuSuiCallback(creature->getZoneServer()));
	// we need to add additional text i think
	StringBuffer promptText;
	box->setPromptTitle("@pet/droid_modules:droid_maint_list_title"); // Maintenance Run
	SuiListBox* b;
	box->setOkButton(true, "@go");
	box->setOtherButton(true,"@add");
	box->setCancelButton(true, "@cancel");
	// we have all we need in the session.
	int addCount = 0;
	// we need to add a line item for every structure on this droids list, then track amount per structure + fees + interplanetary. i.e. if not interplanetary capable, dont show them.
	//Vector<StructureObject*> list = module->getStructureList(creature->getZoneServer(),creature->getZone()->getZoneCRC());
	for(int i=0;i<structures.size();i++) {
		ManagedReference<StructureObject*> obj = structures.elementAt(i);
		StringBuffer buff;
		String zoneName = "the void";
		if (obj->getZone() != NULL) {
			zoneName = obj->getZone()->getZoneName();
		}
		// assume 30 chars per section, 3 sections so 90 chars.
		int nameLength = obj->getDisplayedName().length();
		int zoneNameLength = zoneName.length();
		buff << obj->getDisplayedName();
		if (nameLength < 30) {
			// pad the diff to teh end
			for(int x=0;x<30-nameLength;x++)
				buff << " ";
			nameLength = 30;
		}
		int finalOffset = zoneName.length() + 15;

		buff << "\t" << zoneName << "(" << String::valueOf((int)obj->getPositionX()) << "," << String::valueOf((int)obj->getPositionY()) << ")";
		if (maintenance.contains(obj->getObjectID())) {
			if (addCount == 0)
				promptText << "@pet/droid_modules:droid_maint_list_header\n\n";
			addCount += 1;
			promptText << buff.toString();
			if (finalOffset < 30) {
				for(int x=0;x<30-finalOffset;x++)
					promptText << " ";
			}
			promptText << "+" << maintenance.get(obj->getObjectID()) << "\n";
		} else {
			box->addMenuItem( buff.toString(), obj->getObjectID());
		}
	}
	if (addCount > 0)
		promptText << "\n";
	promptText << "@pet/droid_modules:droid_maint_list_prompt"; // Please select a structure to perform a maintenance run on. Once all structures to be maintained have been selected, press the Go button.
	box->setPromptText(promptText.toString());
	creature->getPlayerObject()->addSuiBox(box);
	creature->sendMessage(box->generateMessage());
}

void DroidMaintenanceSessionImplementation::sendMaintenanceTransferBox(){
	// add result
	if (selectedStructure == NULL) {
		cancelSession();
		return;
	}
	ManagedReference<CreatureObject*> creature = this->player.get();
	ManagedReference<DroidMaintenanceModuleDataComponent*> module = this->maintModule.get();
	// create transfer box
	ManagedReference<SuiTransferBox*> sui = new SuiTransferBox(creature,SuiWindowType::DROID_ADD_STRUCTURE_AMOUNT);
	sui->setCallback(new DroidMaintenanceSessionAddCreditsSuiCallback(creature->getZoneServer()));
	sui->setPromptTitle("@pet/droid_modules:droid_maint_amount_title"); //Select Amount
	bool offplanet = false;
	if (selectedStructure->getZone()->getZoneName() != creature->getZone()->getZoneName())
		offplanet = true;
	StringBuffer promptText = "@pet/droid_modules:droid_maint_amount_prompt \n@player_structure:current_maint_pool "+ String::valueOf(selectedStructure->getSurplusMaintenance())+"cr";
	selectedFees = 0;
	if (offplanet) {
		PlanetManager* planetManager = creature->getZone()->getPlanetManager();
		if (planetManager == NULL) {
			return;
		}
		int fee = planetManager->getTravelFare(selectedStructure->getZone()->getZoneName(),creature->getZone()->getZoneName());
		selectedFees = fee;
		promptText << "\n@pet/droid_modules:droid_maint_diff_planet_prefix " << fee << " @pet/droid_modules:droid_maint_diff_planet_suffix \n";
	}
	sui->setPromptText(promptText.toString());
	// check for off planet, it has a fee
	sui->addFrom("@player_structure:total_funds",String::valueOf(availableCredits),String::valueOf(availableCredits), "1");
	sui->addTo("@player_structure:to_pay", "0", "0", "1");
	creature->getPlayerObject()->addSuiBox(sui);
	creature->sendMessage(sui->generateMessage());
}
void DroidMaintenanceSessionImplementation::addCreditsToCurrentStructure(int amount) {
	// WE know the current structure add it to our pay list.
	if (selectedStructure == NULL) {
		cancelSession();
		return;
	}
	this->maintenance.put(selectedStructure->getObjectID(),amount);
	if (selectedFees > 0){
		fees.add(selectedFees);
	}
}
void DroidMaintenanceSessionImplementation::performMaintenanceRun(){
    // launch the task and set droid cooldown.
	ManagedReference<CreatureObject*> creature = this->player.get();
	if (maintenance.size() == 0) {
		creature->sendSystemMessage("@pet/droid_modules:droid_maint_empty_maint_run");
		sendMaintanceRunBox();
		return;
	}
	// pay all structures
	long totalCosts = 0;
	long totalFees = 0;
	for(int i=0;i<fees.size();i++)
		totalFees += fees.elementAt(i);
	for(int i =0; i< maintenance.size();i++)
		totalCosts += maintenance.elementAt(i).getValue();
	// pay fees
	if (availableCredits < totalCosts + totalFees) {
		if (availableCredits > totalCosts)
			creature->sendSystemMessage("@pet/droid_modules:droid_maint_cant_travel");
		else
			creature->sendSystemMessage("@pet/droid_modules:droid_maint_not_enough_cash");
		cancelSession();
		return;
	}
	// he had enough credits, so lets perform the run .
	ManagedReference<DroidMaintenanceModuleDataComponent*> module = this->maintModule.get();
	ManagedReference<DroidObject*> droid = module->getDroidObject();
	long time = module->calculateRunTime(maintenance);
	long powerCost = time/1000/60/15;
	// check for power now as it may hit zero while we are in the menu
	if (!droid->hasPower()) {
		creature->sendSystemMessage("@pet/droid_modules:not_enough_power"); // Your droid dosnt have enough power to do that.
		cancelSession();
		return;
	}
	// we might get killed off due to no power, do we let it run anyways and jsut leave droid as drained for later.
	// that seems ok he wont be able to touch the droid for a long time anyways so lets roleplay out it just runs out in low power situation.
	// we had enough to run.
	if (creature->getCashCredits() >= totalFees) {
		creature->subtractCashCredits(totalFees);
	} else {
		int payedSoFar = creature->getCashCredits();
		creature->subtractCashCredits(payedSoFar);
		creature->subtractBankCredits(totalFees - payedSoFar);
	}
	// now the structures.
	Locker clock(creature);
	module->payStructures(creature,maintenance);
	// calculate time
	// we got milliseconds convert to minutes
	long minutes = time/1000; // seconds
	String abbrvs[3] = { "seconds", "minutes, ", "hours" };
	int intervals[3] = { 1, 60, 3600 };
	int values[3] = { 0, 0, 0 };
	StringBuffer str;
	str << "Maintenance run started. Completion ETA: ";
	for (int i = 2; i > -1; --i) {
		values[i] = floor((float) minutes / intervals[i]);
		minutes -= values[i] * intervals[i];
		if (values[i] > 0) {
			if (str.length() > 0){
				str << " ";
			}
			str << values[i] << " " << abbrvs[i];
		}
	}

	creature->sendSystemMessage(str.toString());
	// store the pet off and set the call cooldown.
	droid->getCooldownTimerMap()->updateToCurrentAndAddMili("call_cooldown",time);
	Reference<StorePetTask*> task = new StorePetTask(this->player.get(), droid);
	droid->usePower(DroidObject::MAX_POWER); // According to what i read, doing the run drains all power from teh droid.
	task->execute();
}
int DroidMaintenanceSessionImplementation::cancelSession() {
	player.get()->dropActiveSession(SessionFacadeType::DROIDMAINTENANCERUN);
	selectedStructure = NULL;
	structures.removeAll();
	maintenance.removeAll();
	return 0;
}
<commit_msg>[fixed] stability issue<commit_after>/*
 * DroidMaintenanceSessionImplementation.cpp
 *
 *  Created on: 1 13, 2015
 *      Author: Klivian
 */

#include "server/zone/objects/player/sessions/DroidMaintenanceSession.h"
#include "server/zone/Zone.h"
#include "server/zone/objects/creature/CreatureObject.h"
#include "server/zone/objects/player/PlayerObject.h"
#include "server/zone/objects/player/sui/SuiWindowType.h"
#include "server/zone/objects/player/sessions/sui/DroidMaintenanceSessionRunMenuSuiCallback.h"
#include "server/zone/objects/player/sessions/sui/DroidMaintenanceSessionAddCreditsSuiCallback.h"
#include "server/zone/objects/player/sui/listbox/SuiListBox.h"
#include "server/zone/objects/player/sui/transferbox/SuiTransferBox.h"
#include "server/zone/objects/tangible/components/droid/DroidMaintenanceModuleDataComponent.h"
#include "server/zone/objects/structure/StructureObject.h"
#include "server/zone/objects/intangible/tasks/StorePetTask.h"
#include "server/zone/managers/planet/PlanetManager.h"

void DroidMaintenanceSessionImplementation::initialize() {
	ManagedReference<CreatureObject*> creature = this->player.get();
	ManagedReference<DroidMaintenanceModuleDataComponent*> module = this->maintModule.get();
	// get the total credits this guy has right now!
	availableCredits = creature->getCashCredits() + creature->getBankCredits();
	module->getStructureList(&structures, creature->getZoneServer(),creature->getZone()->getZoneCRC());
	maintenance.removeAll();
	selectedFees = 0;
	fees.removeAll();
}

void DroidMaintenanceSessionImplementation::sendMaintanceRunBox(){
	// main ui
	selectedStructure = NULL;

	ManagedReference<CreatureObject*> creature = this->player.get();

	if (structures.size() == 0 && maintenance.isEmpty()) {
		creature->sendSystemMessage("@pet/droid_modules:droid_maint_no_valid_struct");
		cancelSession();
		return;
	}

	ManagedReference<DroidMaintenanceModuleDataComponent*> module = this->maintModule.get();

	ManagedReference<SuiListBox*> box = new SuiListBox(creature, SuiWindowType::DROID_MAINTENANCE_RUN_LIST, SuiListBox::HANDLETHREEBUTTON);
	box->setCallback(new DroidMaintenanceSessionRunMenuSuiCallback(creature->getZoneServer()));
	// we need to add additional text i think
	StringBuffer promptText;
	box->setPromptTitle("@pet/droid_modules:droid_maint_list_title"); // Maintenance Run
	SuiListBox* b;
	box->setOkButton(true, "@go");
	box->setOtherButton(true,"@add");
	box->setCancelButton(true, "@cancel");
	// we have all we need in the session.
	int addCount = 0;
	// we need to add a line item for every structure on this droids list, then track amount per structure + fees + interplanetary. i.e. if not interplanetary capable, dont show them.
	//Vector<StructureObject*> list = module->getStructureList(creature->getZoneServer(),creature->getZone()->getZoneCRC());
	for(int i=0;i<structures.size();i++) {
		ManagedReference<StructureObject*> obj = structures.elementAt(i);
		StringBuffer buff;
		String zoneName = "the void";
		if (obj->getZone() != NULL) {
			zoneName = obj->getZone()->getZoneName();
		}
		// assume 30 chars per section, 3 sections so 90 chars.
		int nameLength = obj->getDisplayedName().length();
		int zoneNameLength = zoneName.length();
		buff << obj->getDisplayedName();
		if (nameLength < 30) {
			// pad the diff to teh end
			for(int x=0;x<30-nameLength;x++)
				buff << " ";
			nameLength = 30;
		}
		int finalOffset = zoneName.length() + 15;

		buff << "\t" << zoneName << "(" << String::valueOf((int)obj->getPositionX()) << "," << String::valueOf((int)obj->getPositionY()) << ")";
		if (maintenance.contains(obj->getObjectID())) {
			if (addCount == 0)
				promptText << "@pet/droid_modules:droid_maint_list_header\n\n";
			addCount += 1;
			promptText << buff.toString();
			if (finalOffset < 30) {
				for(int x=0;x<30-finalOffset;x++)
					promptText << " ";
			}
			promptText << "+" << maintenance.get(obj->getObjectID()) << "\n";
		} else {
			box->addMenuItem( buff.toString(), obj->getObjectID());
		}
	}
	if (addCount > 0)
		promptText << "\n";
	promptText << "@pet/droid_modules:droid_maint_list_prompt"; // Please select a structure to perform a maintenance run on. Once all structures to be maintained have been selected, press the Go button.
	box->setPromptText(promptText.toString());
	creature->getPlayerObject()->addSuiBox(box);
	creature->sendMessage(box->generateMessage());
}

void DroidMaintenanceSessionImplementation::sendMaintenanceTransferBox(){
	// add result
	if (selectedStructure == NULL) {
		cancelSession();
		return;
	}
	ManagedReference<CreatureObject*> creature = this->player.get();
	ManagedReference<DroidMaintenanceModuleDataComponent*> module = this->maintModule.get();
	// create transfer box
	ManagedReference<SuiTransferBox*> sui = new SuiTransferBox(creature,SuiWindowType::DROID_ADD_STRUCTURE_AMOUNT);
	sui->setCallback(new DroidMaintenanceSessionAddCreditsSuiCallback(creature->getZoneServer()));
	sui->setPromptTitle("@pet/droid_modules:droid_maint_amount_title"); //Select Amount
	bool offplanet = false;
	if (selectedStructure->getZone()->getZoneName() != creature->getZone()->getZoneName())
		offplanet = true;
	StringBuffer promptText = "@pet/droid_modules:droid_maint_amount_prompt \n@player_structure:current_maint_pool "+ String::valueOf(selectedStructure->getSurplusMaintenance())+"cr";
	selectedFees = 0;
	if (offplanet) {
		PlanetManager* planetManager = creature->getZone()->getPlanetManager();
		if (planetManager == NULL) {
			return;
		}
		int fee = planetManager->getTravelFare(selectedStructure->getZone()->getZoneName(),creature->getZone()->getZoneName());
		selectedFees = fee;
		promptText << "\n@pet/droid_modules:droid_maint_diff_planet_prefix " << fee << " @pet/droid_modules:droid_maint_diff_planet_suffix \n";
	}
	sui->setPromptText(promptText.toString());
	// check for off planet, it has a fee
	sui->addFrom("@player_structure:total_funds",String::valueOf(availableCredits),String::valueOf(availableCredits), "1");
	sui->addTo("@player_structure:to_pay", "0", "0", "1");
	creature->getPlayerObject()->addSuiBox(sui);
	creature->sendMessage(sui->generateMessage());
}
void DroidMaintenanceSessionImplementation::addCreditsToCurrentStructure(int amount) {
	// WE know the current structure add it to our pay list.
	if (selectedStructure == NULL) {
		cancelSession();
		return;
	}
	this->maintenance.put(selectedStructure->getObjectID(),amount);
	if (selectedFees > 0){
		fees.add(selectedFees);
	}
}
void DroidMaintenanceSessionImplementation::performMaintenanceRun(){
    // launch the task and set droid cooldown.
	ManagedReference<CreatureObject*> creature = this->player.get();
	if (maintenance.size() == 0) {
		creature->sendSystemMessage("@pet/droid_modules:droid_maint_empty_maint_run");
		sendMaintanceRunBox();
		return;
	}
	// pay all structures
	long totalCosts = 0;
	long totalFees = 0;
	for(int i=0;i<fees.size();i++)
		totalFees += fees.elementAt(i);
	for(int i =0; i< maintenance.size();i++)
		totalCosts += maintenance.elementAt(i).getValue();
	// pay fees
	if (availableCredits < totalCosts + totalFees) {
		if (availableCredits > totalCosts)
			creature->sendSystemMessage("@pet/droid_modules:droid_maint_cant_travel");
		else
			creature->sendSystemMessage("@pet/droid_modules:droid_maint_not_enough_cash");
		cancelSession();
		return;
	}
	// he had enough credits, so lets perform the run .
	ManagedReference<DroidMaintenanceModuleDataComponent*> module = this->maintModule.get();
	ManagedReference<DroidObject*> droid = module->getDroidObject();
	long time = module->calculateRunTime(maintenance);
	long powerCost = time/1000/60/15;
	// check for power now as it may hit zero while we are in the menu
	if (!droid->hasPower()) {
		creature->sendSystemMessage("@pet/droid_modules:not_enough_power"); // Your droid dosnt have enough power to do that.
		cancelSession();
		return;
	}
	// we might get killed off due to no power, do we let it run anyways and jsut leave droid as drained for later.
	// that seems ok he wont be able to touch the droid for a long time anyways so lets roleplay out it just runs out in low power situation.
	// we had enough to run.
	if (creature->getCashCredits() >= totalFees) {
		creature->subtractCashCredits(totalFees);
	} else {
		int payedSoFar = creature->getCashCredits();
		creature->subtractCashCredits(payedSoFar);
		creature->subtractBankCredits(totalFees - payedSoFar);
	}
	// now the structures.
	Locker clock(creature);
	module->payStructures(creature,maintenance);
	// calculate time
	// we got milliseconds convert to minutes
	long minutes = time/1000; // seconds
	const static String abbrvs[3] = { "seconds", "minutes, ", "hours" };
	const static int intervals[3] = { 1, 60, 3600 };
	int values[3] = { 0, 0, 0 };
	StringBuffer str;
	str << "Maintenance run started. Completion ETA: ";
	for (int i = 2; i > -1; --i) {
		values[i] = floor((float) minutes / intervals[i]);
		minutes -= values[i] * intervals[i];
		if (values[i] > 0) {
			if (str.length() > 0){
				str << " ";
			}
			str << values[i] << " " << abbrvs[i];
		}
	}

	creature->sendSystemMessage(str.toString());

	Locker droidLock(droid, creature);

	// store the pet off and set the call cooldown.
	droid->getCooldownTimerMap()->updateToCurrentAndAddMili("call_cooldown",time);
	Reference<StorePetTask*> task = new StorePetTask(this->player.get(), droid);
	droid->usePower(DroidObject::MAX_POWER); // According to what i read, doing the run drains all power from teh droid.
	task->execute();
}
int DroidMaintenanceSessionImplementation::cancelSession() {
	player.get()->dropActiveSession(SessionFacadeType::DROIDMAINTENANCERUN);
	selectedStructure = NULL;
	structures.removeAll();
	maintenance.removeAll();
	return 0;
}
<|endoftext|>


<commit_before>#include"all_defines.hpp"

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

#include<errno.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<unistd.h>
#include<stdlib.h>

/*
 * print a fail and exit
 */
void fail(const char* f) {
	std::cerr << "hl: " << f << std::endl;
	exit(1);
}

/*
 * determines if the given file exists
 */
bool find_file(std::string path) {
	char const* c_path = path.c_str();
	struct stat buf;
	if(stat(c_path, &buf) == 0) {
		return 1;
	} else {
		/*assume that all errors are "file not found"*/
		errno = 0;
		return 0;
	}
}

/*
 * given argv[0], attempts to extract the path of the
 * executable.
 */
std::string get_argv0_path(std::string const& argv0) {
	/*reverse iterators can be confusing to handle when
	converting back-and-forth with forward iterators,
	so we just take advantage of bidirectionality
	*/
	std::string::const_iterator slash = argv0.end();
	do {
		--slash;
		if(*slash == '/' || *slash == '\\') {
			/*limit it to just past the / or \ */
			++slash;
			/*copy*/
			return std::string(argv0.begin(), slash);
		}
	} while(slash != argv0.begin());
	return std::string("");
}

#ifndef EXE_EXT
	#define EXE_EXT
#endif

/*
 * searches for the `hlvma` executable
 */
std::string find_hlvma(std::string const& argv0) {
	/*first, find it in the directory we are in*/
	std::string argv0_path = get_argv0_path(argv0);
	if(argv0_path != "") {
		std::string path = argv0_path + ("hlvma" EXE_EXT);
		if(find_file(path)) {
			return path;
		}
	}
	/*look for it in HLVMA_LIBEXECDIR*/
	char const* c_hlvma_libexecdir = getenv("HLVMA_LIBEXECDIR");
	if(c_hlvma_libexecdir) {
		std::string hlvma_libexecdir = c_hlvma_libexecdir;
		std::string path = hlvma_libexecdir + ("/hlvma" EXE_EXT);
		if(find_file(path)) {
			return path;
		}
	}
	/*Finally, look for it in the LIBEXECDIR*/
	#ifdef LIBEXECDIR
	{
		std::string path = ((std::string) LIBEXECDIR) + ("/hlvma" EXE_EXT);
		if(find_file(path)) {
			return path;
		}
	}
	#endif
	fail("Unable to find `hlvma` executable; please check your installation");
}

/*
 * searches for the hlvma boot files, hlvma?.hlbc
 * returns the directory where they are found
 */
std::string find_bootdir(std::string const& argv0) {
	/*find it at ../hl2b/ from the directory we are in*/
	std::string argv0_path = get_argv0_path(argv0);
	if(argv0_path != "" && argv0_path != "/") {
		std::string path = argv0_path + "../hl2b/";
		std::string file = path + "hlvma0.hlbc";
		if(find_file(file)) {
			return path;
		}
	}
	/*find it at the given HLVMA_BOOTDIR*/
	char const* c_hlvma_bootdir = getenv("HLVMA_BOOTDIR");
	if(c_hlvma_bootdir) {
		std::string hlvma_bootdir = c_hlvma_bootdir;
		std::string file = hlvma_bootdir + "/hlvma0.hlbc";
		if(find_file(file)) {
			return hlvma_bootdir;
		}
	}
	/*find it at the given DATADIR*/
	#ifdef DATADIR
	{
		std::string path = (DATADIR "/hlvmaboot/");
		std::string file = path + "hlvma0.hlbc";
		if(find_file(file)) {
			return path;
		}
	}
	#endif
	fail("Unable to find `hlvma` bootstrap directory; please check your installation");
}

void cpp_exec(std::vector<std::string> const& argv) {
	typedef std::vector<std::string> argv_t;
	/*construct a basic C array of char* */
	char** c_argv = new char*[argv.size() + 1];
	char** c_argvp = c_argv;
	for(argv_t::const_iterator ss = argv.begin(); ss != argv.end(); ++ss) {
		std::string const& s = *ss;
		char* c_argvn = new char[s.size() + 1];
		*c_argvp = c_argvn;
		for(
				std::string::const_iterator cs = s.begin();
				cs != s.end();
				++cs) {
			*c_argvn = *cs;
			++c_argvn;
		}
		*c_argvn = (char)0;
		++c_argvp;
	}
	*c_argvp = (char*)0;
	execv(c_argv[0], c_argv);
	fail("unable to execute main program");
}

/*
 * wraps the string and indents any wrapped substring:
 *   "foo bar nitz koo quux qux niaw woof bar foo foobar."
 * =>
 *   foo bar nitz koo quux qux niaw woof
 *       bar foo foobar.
 * we use this instead of manually handling word-wrap so
 * that we can just splice in gettext() without worrying
 * about having a sentence split across strings.
 */
std::string wrap(std::string const& s) {
	static const int line_width = 60;
	if(s.size() < line_width) return s;

	std::stringstream oss;
	std::string::const_iterator cs = s.begin();
	int remaining = s.size();
	int width = line_width;

	bool first = 1;
	do {
		if(remaining < width) {
			for(; cs != s.end(); ++cs) {
				oss << *cs;
			}
			break;
		} else {
			std::string::const_iterator ics = cs + width;
			int line = width;
			/*note: if a word is more than `width' characters
			long, we will have problems.  We don't expect any
			human language word to take up more than 57 or so
			bytes.
			*/
			while(*ics != ' ') {
				--ics; --line;
			}
			for(; cs != ics; ++cs) {
				oss << *cs;
			}
			remaining -= line;
		}
		if(first) {
			width -= 3;
			first = 0;
		}
		oss << std::endl << "   ";
	} while(1);
	return oss.str();
}

int main(int argc, char* argv[]) {
	/*check options*/
	if(argc > 1 && argv[1][0] == '-') {
		std::string argv1 = argv[1];
		if(argv1 == "--version") {
			std::cout << "hl virtual machine A " << PACKAGE_VERSION << std::endl;
			exit(0);
		}
		if(argv1 == "--help") {
			std::cout
				<< "Usage:" << std::endl
				<< "    hl [--version] [ignored-arguments*]"
				<< std::endl
				<< "    hl [--help] [ignored-arguments*]"
				<< std::endl
				<< "    hl [--] [script [script-arguments]]"
				<< std::endl << std::endl
				<< wrap("`hl', without any script argument, "
					"boots the virtual machine REPL.  "
					"You can exit the REPL by typing "
					"`(exit)' at the prompt."
				)
				<< std::endl
				<< wrap("`hl -- [script]' allows you to "
					"launch a script file that begins "
					"with a `-' character."
				)
				<< std::endl
				<< wrap("`hl --version' prints the hl virtual "
					"machine name and version to standard "
					"output, then exits."
				)
				<< std::endl
				<< wrap("`hl --help' prints this help, then exits.")
				<< std::endl
			;
			exit(0);
		}
		/*if the argument is "--", just shift arguments and continue*/
		if(argv1 == "--") {
			--argc;
			for(int i = 1; i < argc; ++i) {
				argv[i] = argv[i + 1];
			}
			goto process_args;
		}
		/*unknown option*/
		fail("Given option was not recognized as a valid option");
	}

process_args:
	std::vector<std::string> new_argv;
	std::string argv0 = argv[0];
	new_argv.push_back(find_hlvma(argv0));
	new_argv.push_back("--bootdir");
	new_argv.push_back(find_bootdir(argv0));
	if(argc > 1) {
		new_argv.push_back("--args");
		for(int i = 1; i < argc; ++i) {
			new_argv.push_back(argv[i]);
		}
	}
	cpp_exec(new_argv);
}

<commit_msg>src/hl.cpp: look for a different file in the bootstrap<commit_after>#include"all_defines.hpp"

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

#include<errno.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<unistd.h>
#include<stdlib.h>

/*
 * print a fail and exit
 */
void fail(const char* f) {
	std::cerr << "hl: " << f << std::endl;
	exit(1);
}

/*
 * determines if the given file exists
 */
bool find_file(std::string path) {
	char const* c_path = path.c_str();
	struct stat buf;
	if(stat(c_path, &buf) == 0) {
		return 1;
	} else {
		/*assume that all errors are "file not found"*/
		errno = 0;
		return 0;
	}
}

/*
 * given argv[0], attempts to extract the path of the
 * executable.
 */
std::string get_argv0_path(std::string const& argv0) {
	/*reverse iterators can be confusing to handle when
	converting back-and-forth with forward iterators,
	so we just take advantage of bidirectionality
	*/
	std::string::const_iterator slash = argv0.end();
	do {
		--slash;
		if(*slash == '/' || *slash == '\\') {
			/*limit it to just past the / or \ */
			++slash;
			/*copy*/
			return std::string(argv0.begin(), slash);
		}
	} while(slash != argv0.begin());
	return std::string("");
}

#ifndef EXE_EXT
	#define EXE_EXT
#endif

/*
 * searches for the `hlvma` executable
 */
std::string find_hlvma(std::string const& argv0) {
	/*first, find it in the directory we are in*/
	std::string argv0_path = get_argv0_path(argv0);
	if(argv0_path != "") {
		std::string path = argv0_path + ("hlvma" EXE_EXT);
		if(find_file(path)) {
			return path;
		}
	}
	/*look for it in HLVMA_LIBEXECDIR*/
	char const* c_hlvma_libexecdir = getenv("HLVMA_LIBEXECDIR");
	if(c_hlvma_libexecdir) {
		std::string hlvma_libexecdir = c_hlvma_libexecdir;
		std::string path = hlvma_libexecdir + ("/hlvma" EXE_EXT);
		if(find_file(path)) {
			return path;
		}
	}
	/*Finally, look for it in the LIBEXECDIR*/
	#ifdef LIBEXECDIR
	{
		std::string path = ((std::string) LIBEXECDIR) + ("/hlvma" EXE_EXT);
		if(find_file(path)) {
			return path;
		}
	}
	#endif
	fail("Unable to find `hlvma` executable; please check your installation");
}

/*
 * searches for the hlvma boot files, hlvma?.hlbc
 * returns the directory where they are found
 */
char const* boot_file_to_find = "000500-default-error-handler.hlbc";
std::string find_bootdir(std::string const& argv0) {
	/*find it at ../hl2b/ from the directory we are in*/
	std::string argv0_path = get_argv0_path(argv0);
	if(argv0_path != "" && argv0_path != "/") {
		std::string path = argv0_path + "../hl2b/cs/";
		std::string file = path + boot_file_to_find;
		if(find_file(file)) {
			return path;
		}
	}
	/*find it at the given HLVMA_BOOTDIR*/
	char const* c_hlvma_bootdir = getenv("HLVMA_BOOTDIR");
	if(c_hlvma_bootdir) {
		std::string hlvma_bootdir = c_hlvma_bootdir;
		std::string file = hlvma_bootdir + "/" + boot_file_to_find;
		if(find_file(file)) {
			return hlvma_bootdir;
		}
	}
	/*find it at the given DATADIR*/
	#ifdef DATADIR
	{
		std::string path = (DATADIR "/hlvmaboot/");
		std::string file = path + boot_file_to_find;
		if(find_file(file)) {
			return path;
		}
	}
	#endif
	fail("Unable to find `hlvma` bootstrap directory; please check your installation");
}

void cpp_exec(std::vector<std::string> const& argv) {
	typedef std::vector<std::string> argv_t;
	/*construct a basic C array of char* */
	char** c_argv = new char*[argv.size() + 1];
	char** c_argvp = c_argv;
	for(argv_t::const_iterator ss = argv.begin(); ss != argv.end(); ++ss) {
		std::string const& s = *ss;
		char* c_argvn = new char[s.size() + 1];
		*c_argvp = c_argvn;
		for(
				std::string::const_iterator cs = s.begin();
				cs != s.end();
				++cs) {
			*c_argvn = *cs;
			++c_argvn;
		}
		*c_argvn = (char)0;
		++c_argvp;
	}
	*c_argvp = (char*)0;
	execv(c_argv[0], c_argv);
	fail("unable to execute main program");
}

/*
 * wraps the string and indents any wrapped substring:
 *   "foo bar nitz koo quux qux niaw woof bar foo foobar."
 * =>
 *   foo bar nitz koo quux qux niaw woof
 *       bar foo foobar.
 * we use this instead of manually handling word-wrap so
 * that we can just splice in gettext() without worrying
 * about having a sentence split across strings.
 */
std::string wrap(std::string const& s) {
	static const int line_width = 60;
	if(s.size() < line_width) return s;

	std::stringstream oss;
	std::string::const_iterator cs = s.begin();
	int remaining = s.size();
	int width = line_width;

	bool first = 1;
	do {
		if(remaining < width) {
			for(; cs != s.end(); ++cs) {
				oss << *cs;
			}
			break;
		} else {
			std::string::const_iterator ics = cs + width;
			int line = width;
			/*note: if a word is more than `width' characters
			long, we will have problems.  We don't expect any
			human language word to take up more than 57 or so
			bytes.
			*/
			while(*ics != ' ') {
				--ics; --line;
			}
			for(; cs != ics; ++cs) {
				oss << *cs;
			}
			remaining -= line;
		}
		if(first) {
			width -= 3;
			first = 0;
		}
		oss << std::endl << "   ";
	} while(1);
	return oss.str();
}

int main(int argc, char* argv[]) {
	/*check options*/
	if(argc > 1 && argv[1][0] == '-') {
		std::string argv1 = argv[1];
		if(argv1 == "--version") {
			std::cout << "hl virtual machine A " << PACKAGE_VERSION << std::endl;
			exit(0);
		}
		if(argv1 == "--help") {
			std::cout
				<< "Usage:" << std::endl
				<< "    hl [--version] [ignored-arguments*]"
				<< std::endl
				<< "    hl [--help] [ignored-arguments*]"
				<< std::endl
				<< "    hl [--] [script [script-arguments]]"
				<< std::endl << std::endl
				<< wrap("`hl', without any script argument, "
					"boots the virtual machine REPL.  "
					"You can exit the REPL by typing "
					"`(exit)' at the prompt."
				)
				<< std::endl
				<< wrap("`hl -- [script]' allows you to "
					"launch a script file that begins "
					"with a `-' character."
				)
				<< std::endl
				<< wrap("`hl --version' prints the hl virtual "
					"machine name and version to standard "
					"output, then exits."
				)
				<< std::endl
				<< wrap("`hl --help' prints this help, then exits.")
				<< std::endl
			;
			exit(0);
		}
		/*if the argument is "--", just shift arguments and continue*/
		if(argv1 == "--") {
			--argc;
			for(int i = 1; i < argc; ++i) {
				argv[i] = argv[i + 1];
			}
			goto process_args;
		}
		/*unknown option*/
		fail("Given option was not recognized as a valid option");
	}

process_args:
	std::vector<std::string> new_argv;
	std::string argv0 = argv[0];
	new_argv.push_back(find_hlvma(argv0));
	new_argv.push_back("--bootdir");
	new_argv.push_back(find_bootdir(argv0));
	if(argc > 1) {
		new_argv.push_back("--args");
		for(int i = 1; i < argc; ++i) {
			new_argv.push_back(argv[i]);
		}
	}
	cpp_exec(new_argv);
}

<|endoftext|>


<commit_before>#include "primitives.h"

#include <stdarg.h>

extern "C" {
	#include "neko.h"
	#include "neko_vm.h"
	#include "neko_mod.h"
	#include "vm.h"

	value neko_append_int( neko_vm *vm, value str, int x, bool way );
	value neko_append_strings( value s1, value s2 );
}

extern field id_add, id_radd, id_sub, id_rsub, id_mult, id_rmult, id_div, id_rdiv, id_mod, id_rmod;

typedef int_val (*c_prim0)();
typedef int_val (*c_prim1)(int_val);
typedef int_val (*c_prim2)(int_val,int_val);
typedef int_val (*c_prim3)(int_val,int_val,int_val);
typedef int_val (*c_prim4)(int_val,int_val,int_val,int_val);
typedef int_val (*c_prim5)(int_val,int_val,int_val,int_val,int_val);
typedef int_val (*c_primN)(value*,int);
typedef int_val (*jit_prim)( neko_vm *, void *, value , neko_module *m );

extern char *jit_boot_seq;

static int_val jit_run( neko_vm *vm, vfunction *acc ) {
	neko_module *m = (neko_module*)acc->module;
	return ((jit_prim)jit_boot_seq)(vm,acc->addr,(value)acc,m);
}

int_val add(void * vm_, int_val a, int_val b) {
	neko_vm * vm = (neko_vm *) vm_;

	if( (b & 1) && (a & 1) ) {
		return (int_val)alloc_int(val_int(a) + val_int(b));
	} else if( b & 1 ) {
		if( val_tag(a) == VAL_FLOAT ) {
			return (int_val)alloc_float(val_float(a) + val_int(b));
		} else if( (val_tag(a)&7) == VAL_STRING  ) {
			return (int_val)neko_append_int(vm,(value)a,val_int(b),true);
		} else if( val_tag(a) == VAL_OBJECT ) {
			value _o = (value)a;
			value _arg = (value)b;
			value _f = val_field(_o,id_add);
			if( _f == val_null ) {
				val_throw(alloc_string("Unsupported operation"));
			} else {
				return (int_val)val_callEx(_o,_f,&_arg,1,NULL);
			}
		} else {
			val_throw(alloc_string("+"));
		}
	} else if( a & 1 ) {
		if( val_tag(b) == VAL_FLOAT )
			return (int_val)alloc_float(val_int(a) + val_float(b));
		else if( (val_tag(b)&7) == VAL_STRING )
			return (int_val)neko_append_int(vm,(value)b,val_int(a),false);
		else if( val_tag(b) == VAL_OBJECT ) {
			value _o = (value)b;
			value _arg = (value)a;
			value _f = val_field(_o,id_radd);
			if( _f == val_null ) {
				val_throw(alloc_string("Unsupported operation"));
			} else {
				return (int_val)val_callEx(_o,_f,&_arg,1,NULL);
			}
		} else {
			val_throw(alloc_string("+"));
		}
	} else if( val_tag(b) == VAL_FLOAT && val_tag(a) == VAL_FLOAT )
		return (int_val)alloc_float(val_float(a) + val_float(b));
	else if( (val_tag(b)&7) == VAL_STRING && (val_tag(a)&7) == VAL_STRING )
		return (int_val)neko_append_strings((value)a,(value)b);
	else {
		if( val_tag(a) == VAL_OBJECT ) {
			value _o = (value)a;
			value _arg = (value)b;
			value _f = val_field(_o,id_add);
			if( _f != val_null ) {
				return (int_val)val_callEx(_o,_f,&_arg,1,NULL);
			}
		}

		if( val_tag(b) == VAL_OBJECT ) {
			value _o = (value)b;
			value _arg = (value)a;
			value _f = val_field(_o,id_radd);
			if( _f != val_null ) {
				return (int_val)val_callEx(_o,_f,&_arg,1,NULL);
			}
		}

		if( (val_tag(b)&7) == VAL_STRING || (val_tag(a)&7) == VAL_STRING ) {
			buffer b = alloc_buffer(NULL);
			val_buffer(b,(value)a);
			val_buffer(b,(value)b);
			return (int_val)buffer_to_string(b);
		} else {
			val_throw(alloc_string("+"));
		}
	}
	return 0;
}

int_val call(void * vm_, int_val f, int_val n, ...) {
	vfunction* func = (vfunction*)f;
	neko_vm * vm = (neko_vm *) vm_;

	if( f & 1 ) {
		val_throw(alloc_string("Invalid call"));
	} else if( val_tag(f) == VAL_FUNCTION && n == func->nargs ) {
		neko_module * m = (neko_module*)func->module;
		int_val* pc = (int_val*)func->addr;
		vm->env = func->env;
		return (int)neko_interp(vm, m, f, pc);
	} else if( val_tag(f) == VAL_PRIMITIVE ) {
		if( n == func->nargs ) {
			va_list argp;
			va_start(argp, n);

			int_val result = 0;
			switch( n ) {
				case 0:
					result = ((c_prim0)func->addr)();
					break;
				case 1:
					result = ((c_prim1)func->addr)(va_arg(argp, int_val));
					break;
				case 2:
					result = ((c_prim2)func->addr)(va_arg(argp, int_val),va_arg(argp, int_val));
					break;
				case 3:
					result = ((c_prim3)func->addr)(va_arg(argp, int_val),va_arg(argp, int_val), va_arg(argp, int_val));
					break;
				case 4:
					result = ((c_prim4)func->addr)(va_arg(argp, int_val),va_arg(argp, int_val), va_arg(argp, int_val),va_arg(argp, int_val));
					break;
				case 5:
					result = ((c_prim5)func->addr)(va_arg(argp, int_val),va_arg(argp, int_val), va_arg(argp, int_val),va_arg(argp, int_val),va_arg(argp, int_val));
					break;
				}
			va_end(argp);
			return result;
		} else if( func->nargs == VAR_ARGS ) {
			va_list argp;
			va_start(argp, n);

			int_val args[CALL_MAX_ARGS];
			for (int i = 0; i < n; i++) {
				args[i] = va_arg(argp, int_val);
			}
			va_end(argp);

			return ((c_primN)func->addr)((value*)(void*)args, n);
		} else {
			val_throw(alloc_string("Invalid call"));
		}
	} else if( val_tag(f) == VAL_JITFUN ) {
		if( n == func->nargs ) {
			return jit_run(vm,func);
		} else {
			val_throw(alloc_string("Invalid call"));
		}
	} else {
		val_throw(alloc_string("Invalid call"));
	}

	return 0;
}

<commit_msg>one more step to 64b glory<commit_after>#include "primitives.h"

#include <stdarg.h>

extern "C" {
	#include "neko.h"
	#include "neko_vm.h"
	#include "neko_mod.h"
	#include "vm.h"

	value neko_append_int( neko_vm *vm, value str, int x, bool way );
	value neko_append_strings( value s1, value s2 );
}

extern field id_add, id_radd, id_sub, id_rsub, id_mult, id_rmult, id_div, id_rdiv, id_mod, id_rmod;

typedef int_val (*c_prim0)();
typedef int_val (*c_prim1)(int_val);
typedef int_val (*c_prim2)(int_val,int_val);
typedef int_val (*c_prim3)(int_val,int_val,int_val);
typedef int_val (*c_prim4)(int_val,int_val,int_val,int_val);
typedef int_val (*c_prim5)(int_val,int_val,int_val,int_val,int_val);
typedef int_val (*c_primN)(value*,int);
typedef int_val (*jit_prim)( neko_vm *, void *, value , neko_module *m );

extern char *jit_boot_seq;

static int_val jit_run( neko_vm *vm, vfunction *acc ) {
	neko_module *m = (neko_module*)acc->module;
	return ((jit_prim)jit_boot_seq)(vm,acc->addr,(value)acc,m);
}

int_val add(void * vm_, int_val a, int_val b) {
	neko_vm * vm = (neko_vm *) vm_;

	if( (b & 1) && (a & 1) ) {
		return (int_val)alloc_int(val_int(a) + val_int(b));
	} else if( b & 1 ) {
		if( val_tag(a) == VAL_FLOAT ) {
			return (int_val)alloc_float(val_float(a) + val_int(b));
		} else if( (val_tag(a)&7) == VAL_STRING  ) {
			return (int_val)neko_append_int(vm,(value)a,val_int(b),true);
		} else if( val_tag(a) == VAL_OBJECT ) {
			value _o = (value)a;
			value _arg = (value)b;
			value _f = val_field(_o,id_add);
			if( _f == val_null ) {
				val_throw(alloc_string("Unsupported operation"));
			} else {
				return (int_val)val_callEx(_o,_f,&_arg,1,NULL);
			}
		} else {
			val_throw(alloc_string("+"));
		}
	} else if( a & 1 ) {
		if( val_tag(b) == VAL_FLOAT )
			return (int_val)alloc_float(val_int(a) + val_float(b));
		else if( (val_tag(b)&7) == VAL_STRING )
			return (int_val)neko_append_int(vm,(value)b,val_int(a),false);
		else if( val_tag(b) == VAL_OBJECT ) {
			value _o = (value)b;
			value _arg = (value)a;
			value _f = val_field(_o,id_radd);
			if( _f == val_null ) {
				val_throw(alloc_string("Unsupported operation"));
			} else {
				return (int_val)val_callEx(_o,_f,&_arg,1,NULL);
			}
		} else {
			val_throw(alloc_string("+"));
		}
	} else if( val_tag(b) == VAL_FLOAT && val_tag(a) == VAL_FLOAT )
		return (int_val)alloc_float(val_float(a) + val_float(b));
	else if( (val_tag(b)&7) == VAL_STRING && (val_tag(a)&7) == VAL_STRING )
		return (int_val)neko_append_strings((value)a,(value)b);
	else {
		if( val_tag(a) == VAL_OBJECT ) {
			value _o = (value)a;
			value _arg = (value)b;
			value _f = val_field(_o,id_add);
			if( _f != val_null ) {
				return (int_val)val_callEx(_o,_f,&_arg,1,NULL);
			}
		}

		if( val_tag(b) == VAL_OBJECT ) {
			value _o = (value)b;
			value _arg = (value)a;
			value _f = val_field(_o,id_radd);
			if( _f != val_null ) {
				return (int_val)val_callEx(_o,_f,&_arg,1,NULL);
			}
		}

		if( (val_tag(b)&7) == VAL_STRING || (val_tag(a)&7) == VAL_STRING ) {
			buffer b = alloc_buffer(NULL);
			val_buffer(b,(value)a);
			val_buffer(b,(value)b);
			return (int_val)buffer_to_string(b);
		} else {
			val_throw(alloc_string("+"));
		}
	}
	return 0;
}

int_val call(void * vm_, int_val f, int_val n, ...) {
	vfunction* func = (vfunction*)f;
	neko_vm * vm = (neko_vm *) vm_;

	if( f & 1 ) {
		val_throw(alloc_string("Invalid call"));
	} else if( val_tag(f) == VAL_FUNCTION && n == func->nargs ) {
		neko_module * m = (neko_module*)func->module;
		int_val* pc = (int_val*)func->addr;
		vm->env = func->env;
		return (int_val)neko_interp(vm, m, f, pc);
	} else if( val_tag(f) == VAL_PRIMITIVE ) {
		if( n == func->nargs ) {
			va_list argp;
			va_start(argp, n);

			int_val result = 0;
			switch( n ) {
				case 0:
					result = ((c_prim0)func->addr)();
					break;
				case 1:
					result = ((c_prim1)func->addr)(va_arg(argp, int_val));
					break;
				case 2:
					result = ((c_prim2)func->addr)(va_arg(argp, int_val),va_arg(argp, int_val));
					break;
				case 3:
					result = ((c_prim3)func->addr)(va_arg(argp, int_val),va_arg(argp, int_val), va_arg(argp, int_val));
					break;
				case 4:
					result = ((c_prim4)func->addr)(va_arg(argp, int_val),va_arg(argp, int_val), va_arg(argp, int_val),va_arg(argp, int_val));
					break;
				case 5:
					result = ((c_prim5)func->addr)(va_arg(argp, int_val),va_arg(argp, int_val), va_arg(argp, int_val),va_arg(argp, int_val),va_arg(argp, int_val));
					break;
				}
			va_end(argp);
			return result;
		} else if( func->nargs == VAR_ARGS ) {
			va_list argp;
			va_start(argp, n);

			int_val args[CALL_MAX_ARGS];
			for (int i = 0; i < n; i++) {
				args[i] = va_arg(argp, int_val);
			}
			va_end(argp);

			return ((c_primN)func->addr)((value*)(void*)args, n);
		} else {
			val_throw(alloc_string("Invalid call"));
		}
	} else if( val_tag(f) == VAL_JITFUN ) {
		if( n == func->nargs ) {
			return jit_run(vm,func);
		} else {
			val_throw(alloc_string("Invalid call"));
		}
	} else {
		val_throw(alloc_string("Invalid call"));
	}

	return 0;
}

<|endoftext|>


<commit_before>/* -*- C++ -*-
 *
 *  NsaReader.cpp - Reader from a NSA archive
 *
 *  Copyright (c) 2001-2014 Ogapee. All rights reserved.
 *
 *  ogapee@aqua.dti2.ne.jp
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include "NsaReader.h"
#include <string.h>
#define NSA_ARCHIVE_NAME "arc"
#define NSA_ARCHIVE_NAME2 "arc%d"

NsaReader::NsaReader( unsigned int nsa_offset, char *path, int archive_type, const unsigned char *key_table )
        :SarReader( path, key_table )
{
    sar_flag = true;
    this->nsa_offset = nsa_offset;
    this->archive_type = archive_type;
    num_of_nsa_archives = 0;
    num_of_ns2_archives = 0;

    if (key_table)
        nsa_archive_ext = "___";
    else
        nsa_archive_ext = "nsa";

    ns2_archive_ext = "ns2";
}

NsaReader::~NsaReader()
{
}

int NsaReader::open( const char *nsa_path )
{
    int i;
    bool archive_found = false;
    char archive_name[256], archive_name2[256];

    if ( !SarReader::open( "arc.sar" ) ) return 0;

    sar_flag = false;

    if (archive_type & ARCHIVE_TYPE_NS2){
        for ( i=0 ; i<MAX_NS2_ARCHIVE ; i++ ){
            sprintf( archive_name, "%s%02d.%s", nsa_path?nsa_path:"", i, ns2_archive_ext );
            if ( ( archive_info_ns2[i].file_handle = fopen( archive_name, "rb" ) ) == NULL ) break;

            archive_found = true;
            archive_info_ns2[i].file_name = new char[strlen(archive_name)+1];
            memcpy(archive_info_ns2[i].file_name, archive_name, strlen(archive_name)+1);
            readArchive( &archive_info_ns2[i], ARCHIVE_TYPE_NS2, nsa_offset );
            num_of_ns2_archives = i+1;
        }
    }

    if (num_of_ns2_archives ==0 && archive_type & ARCHIVE_TYPE_NSA){
        for ( i=-1 ; i<MAX_EXTRA_ARCHIVE ; i++ ){
            ArchiveInfo *ai;

            if (i == -1){
                sprintf( archive_name, "%s%s.%s", nsa_path?nsa_path:"", NSA_ARCHIVE_NAME, nsa_archive_ext );
                ai = &archive_info;
            }
            else{
                sprintf( archive_name2, NSA_ARCHIVE_NAME2, i+1 );
                sprintf( archive_name, "%s%s.%s", nsa_path?nsa_path:"", archive_name2, nsa_archive_ext );
                ai = &archive_info2[i];
            }

            if ( ( ai->file_handle = fopen( archive_name, "rb" ) ) == NULL ) break;

            archive_found = true;
            ai->file_name = new char[strlen(archive_name)+1];
            memcpy(ai->file_name, archive_name, strlen(archive_name)+1);
            readArchive( ai, ARCHIVE_TYPE_NSA, nsa_offset );
            num_of_nsa_archives = i+1;
        }
    }

    if (!archive_found) return -1;

    return 0;
}

int NsaReader::openForConvert( char *nsa_name, int archive_type, unsigned int nsa_offset )
{
    sar_flag = false;
    if ( ( archive_info.file_handle = ::fopen( nsa_name, "rb" ) ) == NULL ){
        fprintf( stderr, "can't open file %s\n", nsa_name );
        return -1;
    }

    readArchive( &archive_info, archive_type, nsa_offset );

    return 0;
}

int NsaReader::writeHeader( FILE *fp, int archive_type, int nsa_offset )
{
    ArchiveInfo *ai = &archive_info;
    return writeHeaderSub( ai, fp, archive_type, nsa_offset );
}

size_t NsaReader::putFile( FILE *fp, int no, size_t offset, size_t length, size_t original_length, int compression_type, bool modified_flag, unsigned char *buffer )
{
    ArchiveInfo *ai = &archive_info;
    return putFileSub( ai, fp, no, offset, length, original_length , compression_type, modified_flag, buffer );
}

const char *NsaReader::getArchiveName() const
{
    return "nsa";
}

int NsaReader::getNumFiles(){
    int total = archive_info.num_of_files, i;

    for ( i=0 ; i<num_of_nsa_archives ; i++ ) total += archive_info2[i].num_of_files;
    for ( i=0 ; i<num_of_ns2_archives ; i++ ) total += archive_info_ns2[i].num_of_files;

    return total;
}

size_t NsaReader::getFileLengthSub( ArchiveInfo *ai, const char *file_name )
{
    unsigned int i = getIndexFromFile( ai, file_name );

    if ( i == ai->num_of_files ) return 0;

    if ( ai->fi_list[i].original_length != 0 )
        return ai->fi_list[i].original_length;

    int type = ai->fi_list[i].compression_type;
    if ( type == NO_COMPRESSION )
        type = getRegisteredCompressionType( file_name );
    if ( type == NBZ_COMPRESSION || type == SPB_COMPRESSION ) {
        ai->fi_list[i].original_length = getDecompressedFileLength( type, ai->file_handle, ai->fi_list[i].offset );
    }

    return ai->fi_list[i].original_length;
}

size_t NsaReader::getFileLength( const char *file_name )
{
    if ( sar_flag ) return SarReader::getFileLength( file_name );

    size_t ret;
    int i;

    if ( ( ret = DirectReader::getFileLength( file_name ) ) ) return ret;

    for ( i=0 ; i<num_of_ns2_archives ; i++ ){
        if ( (ret = getFileLengthSub( &archive_info_ns2[i], file_name )) ) return ret;
    }

    if ( ( ret = getFileLengthSub( &archive_info, file_name )) ) return ret;

    for ( i=0 ; i<num_of_nsa_archives ; i++ ){
        if ( (ret = getFileLengthSub( &archive_info2[i], file_name )) ) return ret;
    }

    return 0;
}

size_t NsaReader::getFile( const char *file_name, unsigned char *buffer, int *location )
{
    size_t ret;

    if ( sar_flag ) return SarReader::getFile( file_name, buffer, location );

    if ( ( ret = DirectReader::getFile( file_name, buffer, location ) ) ) return ret;

    for ( int i=0 ; i<num_of_ns2_archives ; i++ ){
        if ( (ret = getFileSub( &archive_info_ns2[i], file_name, buffer )) ){
            if ( location ) *location = ARCHIVE_TYPE_NS2;
            return ret;
        }
    }

    if ( (ret = getFileSub( &archive_info, file_name, buffer )) ){
        if ( location ) *location = ARCHIVE_TYPE_NSA;
        return ret;
    }

    for ( int i=0 ; i<num_of_nsa_archives ; i++ ){
        if ( (ret = getFileSub( &archive_info2[i], file_name, buffer )) ){
            if ( location ) *location = ARCHIVE_TYPE_NSA;
            return ret;
        }
    }

    return 0;
}

NsaReader::FileInfo NsaReader::getFileByIndex( unsigned int index )
{
    int i;

    for ( i=0 ; i<num_of_ns2_archives ; i++ ){
        if ( index < archive_info_ns2[i].num_of_files ) return archive_info_ns2[i].fi_list[index];
        index -= archive_info_ns2[i].num_of_files;
    }

    if ( index < archive_info.num_of_files ) return archive_info.fi_list[index];
    index -= archive_info.num_of_files;

    for ( i=0 ; i<num_of_nsa_archives ; i++ ){
        if ( index < archive_info2[i].num_of_files ) return archive_info2[i].fi_list[index];
        index -= archive_info2[i].num_of_files;
    }
    logw( stderr, "NsaReader::getFileByIndex  Index %d is out of range\n", index );

    return archive_info.fi_list[0];
}
<commit_msg>Allows .nsa and .sar files to coexist without being mutually exclusive (fixed tsukihime)<commit_after>/* -*- C++ -*-
 *
 *  NsaReader.cpp - Reader from a NSA archive
 *
 *  Copyright (c) 2001-2014 Ogapee. All rights reserved.
 *
 *  ogapee@aqua.dti2.ne.jp
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include "NsaReader.h"
#include <string.h>
#define NSA_ARCHIVE_NAME "arc"
#define NSA_ARCHIVE_NAME2 "arc%d"

NsaReader::NsaReader( unsigned int nsa_offset, char *path, int archive_type, const unsigned char *key_table )
        :SarReader( path, key_table )
{
    sar_flag = true;
    this->nsa_offset = nsa_offset;
    this->archive_type = archive_type;
    num_of_nsa_archives = 0;
    num_of_ns2_archives = 0;

    if (key_table)
        nsa_archive_ext = "___";
    else
        nsa_archive_ext = "nsa";

    ns2_archive_ext = "ns2";
}

NsaReader::~NsaReader()
{
}

int NsaReader::open( const char *nsa_path )
{
    int i;
    bool archive_found = false;
    char archive_name[256], archive_name2[256];

    if ( SarReader::open( "arc.sar" ) )
        sar_flag = false;

    if (archive_type & ARCHIVE_TYPE_NS2){
        for ( i=0 ; i<MAX_NS2_ARCHIVE ; i++ ){
            sprintf( archive_name, "%s%02d.%s", nsa_path?nsa_path:"", i, ns2_archive_ext );
            if ( ( archive_info_ns2[i].file_handle = fopen( archive_name, "rb" ) ) == NULL ) break;

            archive_found = true;
            archive_info_ns2[i].file_name = new char[strlen(archive_name)+1];
            memcpy(archive_info_ns2[i].file_name, archive_name, strlen(archive_name)+1);
            readArchive( &archive_info_ns2[i], ARCHIVE_TYPE_NS2, nsa_offset );
            num_of_ns2_archives = i+1;
        }
    }

    if (num_of_ns2_archives ==0 && archive_type & ARCHIVE_TYPE_NSA){
        for ( i=-1 ; i<MAX_EXTRA_ARCHIVE ; i++ ){
            ArchiveInfo *ai;

            if (i == -1){
                sprintf( archive_name, "%s%s.%s", nsa_path?nsa_path:"", NSA_ARCHIVE_NAME, nsa_archive_ext );
                ai = &archive_info;
            }
            else{
                sprintf( archive_name2, NSA_ARCHIVE_NAME2, i+1 );
                sprintf( archive_name, "%s%s.%s", nsa_path?nsa_path:"", archive_name2, nsa_archive_ext );
                ai = &archive_info2[i];
            }

            if ( ( ai->file_handle = fopen( archive_name, "rb" ) ) == NULL ) break;

            archive_found = true;
            ai->file_name = new char[strlen(archive_name)+1];
            memcpy(ai->file_name, archive_name, strlen(archive_name)+1);
            readArchive( ai, ARCHIVE_TYPE_NSA, nsa_offset );
            num_of_nsa_archives = i+1;
        }
    }

    if (!archive_found) return -1;

    return 0;
}

int NsaReader::openForConvert( char *nsa_name, int archive_type, unsigned int nsa_offset )
{
    sar_flag = false;
    if ( ( archive_info.file_handle = ::fopen( nsa_name, "rb" ) ) == NULL ){
        fprintf( stderr, "can't open file %s\n", nsa_name );
        return -1;
    }

    readArchive( &archive_info, archive_type, nsa_offset );

    return 0;
}

int NsaReader::writeHeader( FILE *fp, int archive_type, int nsa_offset )
{
    ArchiveInfo *ai = &archive_info;
    return writeHeaderSub( ai, fp, archive_type, nsa_offset );
}

size_t NsaReader::putFile( FILE *fp, int no, size_t offset, size_t length, size_t original_length, int compression_type, bool modified_flag, unsigned char *buffer )
{
    ArchiveInfo *ai = &archive_info;
    return putFileSub( ai, fp, no, offset, length, original_length , compression_type, modified_flag, buffer );
}

const char *NsaReader::getArchiveName() const
{
    return "nsa";
}

int NsaReader::getNumFiles(){
    int total = archive_info.num_of_files, i;

    for ( i=0 ; i<num_of_nsa_archives ; i++ ) total += archive_info2[i].num_of_files;
    for ( i=0 ; i<num_of_ns2_archives ; i++ ) total += archive_info_ns2[i].num_of_files;

    return total;
}

size_t NsaReader::getFileLengthSub( ArchiveInfo *ai, const char *file_name )
{
    unsigned int i = getIndexFromFile( ai, file_name );

    if ( i == ai->num_of_files ) return 0;

    if ( ai->fi_list[i].original_length != 0 )
        return ai->fi_list[i].original_length;

    int type = ai->fi_list[i].compression_type;
    if ( type == NO_COMPRESSION )
        type = getRegisteredCompressionType( file_name );
    if ( type == NBZ_COMPRESSION || type == SPB_COMPRESSION ) {
        ai->fi_list[i].original_length = getDecompressedFileLength( type, ai->file_handle, ai->fi_list[i].offset );
    }

    return ai->fi_list[i].original_length;
}

size_t NsaReader::getFileLength( const char *file_name )
{
    size_t ret;
    if ( sar_flag && (ret = SarReader::getFileLength( file_name ))) {
        return ret;
    }

    int i;

    if ( ( ret = DirectReader::getFileLength( file_name ) ) ) return ret;

    for ( i=0 ; i<num_of_ns2_archives ; i++ ){
        if ( (ret = getFileLengthSub( &archive_info_ns2[i], file_name )) ) return ret;
    }

    if ( ( ret = getFileLengthSub( &archive_info, file_name )) ) return ret;

    for ( i=0 ; i<num_of_nsa_archives ; i++ ){
        if ( (ret = getFileLengthSub( &archive_info2[i], file_name )) ) return ret;
    }

    return 0;
}

size_t NsaReader::getFile( const char *file_name, unsigned char *buffer, int *location )
{
    size_t ret;

    if ( sar_flag && (ret = SarReader::getFile( file_name, buffer, location ))) {
        return ret;
    }

    if ( ( ret = DirectReader::getFile( file_name, buffer, location ) ) ) return ret;

    for ( int i=0 ; i<num_of_ns2_archives ; i++ ){
        if ( (ret = getFileSub( &archive_info_ns2[i], file_name, buffer )) ){
            if ( location ) *location = ARCHIVE_TYPE_NS2;
            return ret;
        }
    }

    if ( (ret = getFileSub( &archive_info, file_name, buffer )) ){
        if ( location ) *location = ARCHIVE_TYPE_NSA;
        return ret;
    }

    for ( int i=0 ; i<num_of_nsa_archives ; i++ ){
        if ( (ret = getFileSub( &archive_info2[i], file_name, buffer )) ){
            if ( location ) *location = ARCHIVE_TYPE_NSA;
            return ret;
        }
    }

    return 0;
}

NsaReader::FileInfo NsaReader::getFileByIndex( unsigned int index )
{
    int i;

    for ( i=0 ; i<num_of_ns2_archives ; i++ ){
        if ( index < archive_info_ns2[i].num_of_files ) return archive_info_ns2[i].fi_list[index];
        index -= archive_info_ns2[i].num_of_files;
    }

    if ( index < archive_info.num_of_files ) return archive_info.fi_list[index];
    index -= archive_info.num_of_files;

    for ( i=0 ; i<num_of_nsa_archives ; i++ ){
        if ( index < archive_info2[i].num_of_files ) return archive_info2[i].fi_list[index];
        index -= archive_info2[i].num_of_files;
    }
    logw( stderr, "NsaReader::getFileByIndex  Index %d is out of range\n", index );

    return archive_info.fi_list[0];
}
<|endoftext|>


<commit_before>#include "Controler.h"
#include "Exceptions.h"

const char* HELP = "help";
bool Controler::option_o;
bool Controler::option_a;
bool Controler::option_p;
bool Controler::option_e;

Controler::Controler()
{
    input_file = new File();
    rules = new Dictionary();
	com_parser = new Parser();
	automate = new Automate();
}

Controler::~Controler()
{

}

void Controler::configurate (int argc, char ** argv)
{
    // Contr�le du nombre maxi d'arguments
    if (argc > MAX_ARGS)
    {
        throw MaxArgsException;
    }
    // Contr�le mini
    else if (argc == 1)
    {
        com_parser->show_options();
        exit(0);
    }
    //Pr�sence d'arguments
    else
    {
        vector<string> opt;
        for (int i = 1; i< argc - 1;i++)
        {
            opt.push_back(argv[i]);
        }
        try
        {
             com_parser->parsing_options(opt);
        }
        catch (int i)
        {
            throw IllegalArgException;
        }
    }
}

void Controler::run(char* path)
{
	try
	{
		input_file->setPath(path);
		input_file->openParse();
	}
	catch (int i)
	{
		throw BadFileException;
	}
    analyse_lexsyn();
    memload();
    if (option_o)
    {
        transformation();
    }
    if (option_p)
    {
        affichage();
    }

    if (option_a)
    {
        analyse_statique();
    }
    if (option_e)
    {
        execution();
    }

    //Test maps MARCO /!\ JE VAIS LE SUPPRIMER!!!!
    //this->testsMapsMarco();

}

//Test maps MARCO /!\ JE VAIS LE SUPPRIMER!!!!
void Controler::testsMapsMarco()
{
    cout << "TEST MARCO" << endl;

    for (int i=0; i<10; i++)
    {

        automate->addDeclaration("marco"+std::to_string(i), 0);
    }

    automate->displayMap();

}
// Private/static functions

void Controler::enable_o ()
{
    if(!option_o)
    {
        option_o = true;
    }
    else
    {
        throw IllegalArgException;
    }
}

void Controler::enable_p ()
{
    if (!option_p)
    {
        option_p = true;
    }
    else
    {
        throw IllegalArgException;
    }
}

void Controler::enable_e ()
{
    if (!option_e)
    {
        option_e = true;
    }
    else
    {
        throw IllegalArgException;
    }
}

void Controler::enable_a ()
{
    if (!option_a)
    {
        option_a = true;
    }
    else
    {
        throw IllegalArgException;
    }
}

void Controler::analyse_lexsyn()
{
    cout<< "j'execute l'analyse lexsyn :" <<endl;

}
void Controler::memload()
{
    cout<<"j'execute la mem representation" <<endl;
}
void Controler::transformation()
{
    cout<<"j'execute la transformation" <<endl;
}
void Controler::affichage()
{
    cout<<"j'execute l'affichage" <<endl;
}
void Controler::execution()
{
    cout<<"j'execute le prog" <<endl;
}
void Controler::analyse_statique()
{
    cout<<"j'execute l'analyse syn" <<endl;
}
<commit_msg>comment<commit_after>#include "Controler.h"
#include "Exceptions.h"

const char* HELP = "help";
bool Controler::option_o;
bool Controler::option_a;
bool Controler::option_p;
bool Controler::option_e;

Controler::Controler()
{
    input_file = new File();
    rules = new Dictionary();
	com_parser = new Parser();
	automate = new Automate();
}

Controler::~Controler()
{

}
/*
Méthode de configuration du controleur
argc : nombre d'arguments en ligne de commande
argv : les arguments
*/
void Controler::configurate (int argc, char ** argv)
{
    // Contr�le du nombre maxi d'arguments
    if (argc > MAX_ARGS)
    {
        throw MaxArgsException;
    }
    // Contr�le mini
    else if (argc == 1)
    {
        com_parser->show_options();
        exit(0);
    }
    //Pr�sence d'arguments
    else
    {
        vector<string> opt;
        for (int i = 1; i< argc - 1;i++)
        {
            opt.push_back(argv[i]);
        }
        try
        {
             com_parser->parsing_options(opt);
        }
        catch (int i)
        {
            throw IllegalArgException;
        }
    }
}
/*
Méthode principale du controleur, les actions sont executées séquentiellement
Lecture Fichier -> Analyse lexicale/syntaxique -> RepMémoire -> Affichage -> analyse statique -> Execution
path : chemin du fichier lutin à analyser
*/
void Controler::run(char* path)
{
	try
	{
		input_file->setPath(path);
		input_file->openParse();
	}
	catch (int i)
	{
		throw BadFileException;
	}
    analyse_lexsyn();
    memload();
    if (option_o)
    {
        transformation();
    }
    if (option_p)
    {
        affichage();
    }
    if (option_a)
    {
        analyse_statique();
    }
    if (option_e)
    {
        execution();
    }
    //Test maps MARCO /!\ JE VAIS LE SUPPRIMER!!!!
    //this->testsMapsMarco();
}

//Test maps MARCO /!\ JE VAIS LE SUPPRIMER!!!!
void Controler::testsMapsMarco()
{
    cout << "TEST MARCO" << endl;

    for (int i=0; i<10; i++)
    {

        automate->addDeclaration("marco"+std::to_string(i), 0);
    }

    automate->displayMap();

}
//<<<<<<<<<< Private/static functions >>>>>>>>>>>>>>>>

void Controler::enable_o ()
{
    if(!option_o)
    {
        option_o = true;
    }
    else
    {
        throw IllegalArgException;
    }
}

void Controler::enable_p ()
{
    if (!option_p)
    {
        option_p = true;
    }
    else
    {
        throw IllegalArgException;
    }
}

void Controler::enable_e ()
{
    if (!option_e)
    {
        option_e = true;
    }
    else
    {
        throw IllegalArgException;
    }
}

void Controler::enable_a ()
{
    if (!option_a)
    {
        option_a = true;
    }
    else
    {
        throw IllegalArgException;
    }
}

void Controler::analyse_lexsyn()
{
    cout<< "j'execute l'analyse lexsyn :" <<endl;
}
void Controler::memload()
{
    cout<<"j'execute la mem representation" <<endl;
}
void Controler::transformation()
{
    cout<<"j'execute la transformation" <<endl;
}
void Controler::affichage()
{
    cout<<"j'execute l'affichage" <<endl;
}
void Controler::execution()
{
    cout<<"j'execute le prog" <<endl;
}
void Controler::analyse_statique()
{
    cout<<"j'execute l'analyse syn" <<endl;
}
<|endoftext|>