<commit_before>/*

Copyright (c) 2007, Un Shyam
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in
      the documentation and/or other materials provided with the distribution.
    * Neither the name of the author nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

*/

#include <algorithm>
#include <iostream>

#include "libtorrent/hasher.hpp"
#include "libtorrent/pe_crypto.hpp"
#include "libtorrent/session.hpp"

#include "setup_transfer.hpp"
#include "test.hpp"

#ifndef TORRENT_DISABLE_ENCRYPTION

char const* pe_policy(libtorrent::pe_settings::enc_policy policy)
{
	using namespace libtorrent;

	if (policy == pe_settings::disabled) return "disabled";
	else if (policy == pe_settings::enabled) return "enabled";
	else if (policy == pe_settings::forced) return "forced";
	return "unknown";
}

void display_pe_settings(libtorrent::pe_settings s)
{
	using namespace libtorrent;

	fprintf(stderr, "out_enc_policy - %s\tin_enc_policy - %s\n"
		, pe_policy(s.out_enc_policy), pe_policy(s.in_enc_policy));

	fprintf(stderr, "enc_level - %s\t\tprefer_rc4 - %s\n"
		, s.allowed_enc_level == pe_settings::plaintext ? "plaintext"
		: s.allowed_enc_level == pe_settings::rc4 ? "rc4"
		: s.allowed_enc_level == pe_settings::both ? "both" : "unknown"
		, s.prefer_rc4 ? "true": "false");
}

void test_transfer(libtorrent::pe_settings::enc_policy policy,
		   libtorrent::pe_settings::enc_level level = libtorrent::pe_settings::both,
		   bool pref_rc4 = false)
{
	using namespace libtorrent;

	// these are declared before the session objects
	// so that they are destructed last. This enables
	// the sessions to destruct in parallel
	session_proxy p1;
	session_proxy p2;

	session ses1(fingerprint("LT", 0, 1, 0, 0), std::make_pair(48800, 49000), "0.0.0.0", 0);
	session ses2(fingerprint("LT", 0, 1, 0, 0), std::make_pair(49800, 50000), "0.0.0.0", 0);
	pe_settings s;

	s.out_enc_policy = libtorrent::pe_settings::enabled;
	s.in_enc_policy = libtorrent::pe_settings::enabled;

	s.allowed_enc_level = pe_settings::both;
	ses2.set_pe_settings(s);

	s.out_enc_policy = policy;
	s.in_enc_policy = policy;
	s.allowed_enc_level = level;
	s.prefer_rc4 = pref_rc4;
	ses1.set_pe_settings(s);

	s = ses1.get_pe_settings();
	fprintf(stderr, " Session1 \n");
	display_pe_settings(s);
	s = ses2.get_pe_settings();
	fprintf(stderr, " Session2 \n");
	display_pe_settings(s);

	torrent_handle tor1;
	torrent_handle tor2;

	using boost::tuples::ignore;
	boost::tie(tor1, tor2, ignore) = setup_transfer(&ses1, &ses2, 0, true, false, true
		, "_pe", 16 * 1024, 0, false, 0, true);

	fprintf(stderr, "waiting for transfer to complete\n");

	for (int i = 0; i < 50; ++i)
	{
		torrent_status s = tor2.status();
		print_alerts(ses1, "ses1");
		print_alerts(ses2, "ses2");

		if (s.is_seeding) break;
		test_sleep(1000);
	}

	TEST_CHECK(tor2.status().is_seeding);
 	if (tor2.status().is_seeding) fprintf(stderr, "done\n");
	ses1.remove_torrent(tor1);
	ses2.remove_torrent(tor2);

	// this allows shutting down the sessions in parallel
	p1 = ses1.abort();
	p2 = ses2.abort();

	error_code ec;
	remove_all("tmp1_pe", ec);
	remove_all("tmp2_pe", ec);
	remove_all("tmp3_pe", ec);
}

void test_enc_handler(libtorrent::encryption_handler* a, libtorrent::encryption_handler* b)
{
	int repcount = 128;
	for (int rep = 0; rep < repcount; ++rep)
	{
		std::size_t buf_len = rand() % (512 * 1024);
		char* buf = new char[buf_len];
		char* cmp_buf = new char[buf_len];

		std::generate(buf, buf + buf_len, &std::rand);
		std::memcpy(cmp_buf, buf, buf_len);

		a->encrypt(buf, buf_len);
		TEST_CHECK(!std::equal(buf, buf + buf_len, cmp_buf));
		b->decrypt(buf, buf_len);
		TEST_CHECK(std::equal(buf, buf + buf_len, cmp_buf));

		b->encrypt(buf, buf_len);
		TEST_CHECK(!std::equal(buf, buf + buf_len, cmp_buf));
		a->decrypt(buf, buf_len);
		TEST_CHECK(std::equal(buf, buf + buf_len, cmp_buf));

		delete[] buf;
		delete[] cmp_buf;
	}
}

#endif

int test_main()
{
	using namespace libtorrent;

#ifndef TORRENT_DISABLE_ENCRYPTION
	int repcount = 128;

	for (int rep = 0; rep < repcount; ++rep)
	{
		dh_key_exchange DH1, DH2;

		DH1.compute_secret(DH2.get_local_key());
		DH2.compute_secret(DH1.get_local_key());

		TEST_CHECK(std::equal(DH1.get_secret(), DH1.get_secret() + 96, DH2.get_secret()));
	}

	dh_key_exchange DH1, DH2;
	DH1.compute_secret(DH2.get_local_key());
	DH2.compute_secret(DH1.get_local_key());

	TEST_CHECK(std::equal(DH1.get_secret(), DH1.get_secret() + 96, DH2.get_secret()));

	sha1_hash test1_key = hasher("test1_key",8).final();
	sha1_hash test2_key = hasher("test2_key",8).final();

	fprintf(stderr, "testing RC4 handler\n");
	rc4_handler rc41;
	rc41.set_incoming_key(&test2_key[0], 20);
	rc41.set_outgoing_key(&test1_key[0], 20);
	rc4_handler rc42;
	rc42.set_incoming_key(&test1_key[0], 20);
	rc42.set_outgoing_key(&test2_key[0], 20);
	test_enc_handler(&rc41, &rc42);

	test_transfer(pe_settings::disabled);

	test_transfer(pe_settings::forced, pe_settings::plaintext);
	test_transfer(pe_settings::forced, pe_settings::rc4);
	test_transfer(pe_settings::forced, pe_settings::both, false);
	test_transfer(pe_settings::forced, pe_settings::both, true);

	test_transfer(pe_settings::enabled, pe_settings::plaintext);
	test_transfer(pe_settings::enabled, pe_settings::rc4);
	test_transfer(pe_settings::enabled, pe_settings::both, false);
	test_transfer(pe_settings::enabled, pe_settings::both, true);
#else
	fprintf(stderr, "PE test not run because it's disabled\n");
#endif

	return 0;
}

<commit_msg>attempt to make test_pe_crypto pass under valgrind in reasonable time<commit_after>/*

Copyright (c) 2007, Un Shyam
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in
      the documentation and/or other materials provided with the distribution.
    * Neither the name of the author nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

*/

#include <algorithm>
#include <iostream>

#include "libtorrent/hasher.hpp"
#include "libtorrent/pe_crypto.hpp"
#include "libtorrent/session.hpp"

#include "setup_transfer.hpp"
#include "test.hpp"

#ifndef TORRENT_DISABLE_ENCRYPTION

char const* pe_policy(libtorrent::pe_settings::enc_policy policy)
{
	using namespace libtorrent;

	if (policy == pe_settings::disabled) return "disabled";
	else if (policy == pe_settings::enabled) return "enabled";
	else if (policy == pe_settings::forced) return "forced";
	return "unknown";
}

void display_pe_settings(libtorrent::pe_settings s)
{
	using namespace libtorrent;

	fprintf(stderr, "out_enc_policy - %s\tin_enc_policy - %s\n"
		, pe_policy(s.out_enc_policy), pe_policy(s.in_enc_policy));

	fprintf(stderr, "enc_level - %s\t\tprefer_rc4 - %s\n"
		, s.allowed_enc_level == pe_settings::plaintext ? "plaintext"
		: s.allowed_enc_level == pe_settings::rc4 ? "rc4"
		: s.allowed_enc_level == pe_settings::both ? "both" : "unknown"
		, s.prefer_rc4 ? "true": "false");
}

void test_transfer(libtorrent::pe_settings::enc_policy policy
	, int timeout
	, libtorrent::pe_settings::enc_level level = libtorrent::pe_settings::both
	, bool pref_rc4 = false)
{
	using namespace libtorrent;

	// these are declared before the session objects
	// so that they are destructed last. This enables
	// the sessions to destruct in parallel
	session_proxy p1;
	session_proxy p2;

	session ses1(fingerprint("LT", 0, 1, 0, 0), std::make_pair(48800, 49000), "0.0.0.0", 0);
	session ses2(fingerprint("LT", 0, 1, 0, 0), std::make_pair(49800, 50000), "0.0.0.0", 0);
	pe_settings s;

	s.out_enc_policy = libtorrent::pe_settings::enabled;
	s.in_enc_policy = libtorrent::pe_settings::enabled;

	s.allowed_enc_level = pe_settings::both;
	ses2.set_pe_settings(s);

	s.out_enc_policy = policy;
	s.in_enc_policy = policy;
	s.allowed_enc_level = level;
	s.prefer_rc4 = pref_rc4;
	ses1.set_pe_settings(s);

	s = ses1.get_pe_settings();
	fprintf(stderr, " Session1 \n");
	display_pe_settings(s);
	s = ses2.get_pe_settings();
	fprintf(stderr, " Session2 \n");
	display_pe_settings(s);

	torrent_handle tor1;
	torrent_handle tor2;

	using boost::tuples::ignore;
	boost::tie(tor1, tor2, ignore) = setup_transfer(&ses1, &ses2, 0, true, false, true
		, "_pe", 16 * 1024, 0, false, 0, true);

	fprintf(stderr, "waiting for transfer to complete\n");

	for (int i = 0; i < timeout * 10; ++i)
	{
		torrent_status s = tor2.status();
		print_alerts(ses1, "ses1");
		print_alerts(ses2, "ses2");

		if (s.is_seeding) break;
		test_sleep(100);
	}

	TEST_CHECK(tor2.status().is_seeding);
 	if (tor2.status().is_seeding) fprintf(stderr, "done\n");
	ses1.remove_torrent(tor1);
	ses2.remove_torrent(tor2);

	// this allows shutting down the sessions in parallel
	p1 = ses1.abort();
	p2 = ses2.abort();

	error_code ec;
	remove_all("tmp1_pe", ec);
	remove_all("tmp2_pe", ec);
	remove_all("tmp3_pe", ec);
}

void test_enc_handler(libtorrent::encryption_handler* a, libtorrent::encryption_handler* b)
{
#ifdef TORRENT_USE_VALGRIND
	const int repcount = 10;
#else
	const int repcount = 128;
#endif
	for (int rep = 0; rep < repcount; ++rep)
	{
		std::size_t buf_len = rand() % (512 * 1024);
		char* buf = new char[buf_len];
		char* cmp_buf = new char[buf_len];

		std::generate(buf, buf + buf_len, &std::rand);
		std::memcpy(cmp_buf, buf, buf_len);

		a->encrypt(buf, buf_len);
		TEST_CHECK(!std::equal(buf, buf + buf_len, cmp_buf));
		b->decrypt(buf, buf_len);
		TEST_CHECK(std::equal(buf, buf + buf_len, cmp_buf));

		b->encrypt(buf, buf_len);
		TEST_CHECK(!std::equal(buf, buf + buf_len, cmp_buf));
		a->decrypt(buf, buf_len);
		TEST_CHECK(std::equal(buf, buf + buf_len, cmp_buf));

		delete[] buf;
		delete[] cmp_buf;
	}
}

#endif

int test_main()
{
	using namespace libtorrent;

#ifndef TORRENT_DISABLE_ENCRYPTION

#ifdef TORRENT_USE_VALGRIND
	const int repcount = 10;
#else
	const int repcount = 128;
#endif

	for (int rep = 0; rep < repcount; ++rep)
	{
		dh_key_exchange DH1, DH2;

		DH1.compute_secret(DH2.get_local_key());
		DH2.compute_secret(DH1.get_local_key());

		TEST_CHECK(std::equal(DH1.get_secret(), DH1.get_secret() + 96, DH2.get_secret()));
	}

	dh_key_exchange DH1, DH2;
	DH1.compute_secret(DH2.get_local_key());
	DH2.compute_secret(DH1.get_local_key());

	TEST_CHECK(std::equal(DH1.get_secret(), DH1.get_secret() + 96, DH2.get_secret()));

	sha1_hash test1_key = hasher("test1_key",8).final();
	sha1_hash test2_key = hasher("test2_key",8).final();

	fprintf(stderr, "testing RC4 handler\n");
	rc4_handler rc41;
	rc41.set_incoming_key(&test2_key[0], 20);
	rc41.set_outgoing_key(&test1_key[0], 20);
	rc4_handler rc42;
	rc42.set_incoming_key(&test1_key[0], 20);
	rc42.set_outgoing_key(&test2_key[0], 20);
	test_enc_handler(&rc41, &rc42);

#ifdef TORRENT_USE_VALGRIND
	const int timeout = 10;
#else
	const int timeout = 5;
#endif

	test_transfer(pe_settings::disabled, timeout);

	test_transfer(pe_settings::forced, timeout, pe_settings::plaintext);
	test_transfer(pe_settings::forced, timeout, pe_settings::rc4);
	test_transfer(pe_settings::forced, timeout, pe_settings::both, false);
	test_transfer(pe_settings::forced, timeout, pe_settings::both, true);

	test_transfer(pe_settings::enabled, timeout, pe_settings::plaintext);
	test_transfer(pe_settings::enabled, timeout, pe_settings::rc4);
	test_transfer(pe_settings::enabled, timeout, pe_settings::both, false);
	test_transfer(pe_settings::enabled, timeout, pe_settings::both, true);
#else
	fprintf(stderr, "PE test not run because it's disabled\n");
#endif

	return 0;
}

<|endoftext|>


<commit_before>/******************************************************************************
* Copyright (c) 2011, Michael P. Gerlek (mpg@flaxen.com)
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following
* conditions are met:
*
*     * Redistributions of source code must retain the above copyright
*       notice, this list of conditions and the following disclaimer.
*     * Redistributions in binary form must reproduce the above copyright
*       notice, this list of conditions and the following disclaimer in
*       the documentation and/or other materials provided
*       with the distribution.
*     * Neither the name of Hobu, Inc. or Flaxen Geo Consulting nor the
*       names of its contributors may be used to endorse or promote
*       products derived from this software without specific prior
*       written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
****************************************************************************/

#include <sstream>

#include <boost/test/unit_test.hpp>
#include <boost/cstdint.hpp>

#include <libpc/Range.hpp>

using namespace libpc;

BOOST_AUTO_TEST_SUITE(UtilsTest)

BOOST_AUTO_TEST_CASE(test_random)
{
    const double rangeMin = 0.0;
    const double rangeMax = 100.0;
    const double avg = (rangeMax - rangeMin) / 2.0;
    const int iters = 1000;

    Utils::random_seed(17);

    // make sure we treat the bounds as inclusive
    double sum=0;
    for (int i=0; i<iters; i++)
    {
        const double x = Utils::random(rangeMin, rangeMax);
        BOOST_CHECK(x >= rangeMin);
        BOOST_CHECK(x <= rangeMax);

        sum += x;
    }

    sum = sum / iters;

    BOOST_CHECK(sum <= avg + 0.1*avg);
    BOOST_CHECK(sum >= avg - 0.1*avg);
}

BOOST_AUTO_TEST_CASE(test_comparators)
{
    bool ok;

    {
        ok = Utils::compare_distance<float>(1.000001f, 1.0f);
        BOOST_CHECK(!ok);

        ok = Utils::compare_distance<float>(1.0000001f, 1.0f);
        BOOST_CHECK(ok);

        ok = Utils::compare_distance<float>(1.00000001f, 1.0f);
        BOOST_CHECK(ok);
    }

    {
        ok = Utils::compare_approx<float>(1.001f, 1.0f, 0.0001f);
        BOOST_CHECK(!ok);

        ok = Utils::compare_approx<float>(1.001f, 1.0f, 0.001f);
        BOOST_CHECK(!ok);

        ok = Utils::compare_approx<float>(1.001f, 1.0f, 0.01f);
        BOOST_CHECK(ok);

        ok = Utils::compare_approx<float>(1.001f, 1.0f, 0.1f);
        BOOST_CHECK(ok);
    }
}

BOOST_AUTO_TEST_CASE(test_buffer_read_write)
{
    const char buf[] = "quick brown fox";
    std::string bufstr(buf);

    std::ostringstream ostr;
    Utils::write_n(ostr, buf, 15);

    BOOST_CHECK(memcmp(buf, ostr.str().c_str(), 15) == 0);

    std::istringstream istr;
    istr.str(bufstr);
    boost::uint8_t tmp[30];
    Utils::read_n(tmp, istr, 15);
    BOOST_CHECK(memcmp(buf, tmp, 15) == 0);

    return;
}

BOOST_AUTO_TEST_CASE(test_field_read_write)
{
    boost::uint8_t buffer[100];
    boost::uint8_t* p = buffer;

    boost::uint8_t one = 1;
    double two = 2.0;

    Utils::write_field<boost::uint8_t>(p, one);
    Utils::write_field<double>(p, two);

    p = buffer;

    boost::uint8_t x = Utils::read_field<boost::uint8_t>(p);
    double y = Utils::read_field<double>(p);

    BOOST_CHECK(x==one);
    BOOST_CHECK(y==two);

    return;
}

BOOST_AUTO_TEST_CASE(test_file_ops)
{
    std::string tmp1 = "unittest1.tmp";
    std::string tmp2 = "unittest2.tmp";

    // first, clean up from any previous test run
    Utils::deleteFile(tmp1);
    Utils::deleteFile(tmp2);
    BOOST_CHECK(Utils::fileExists(tmp1)==false);
    BOOST_CHECK(Utils::fileExists(tmp2)==false);

    // write test
    std::ostream* ostr = Utils::createFile(tmp1);
    *ostr << "yow";
    Utils::closeFile(ostr);

    BOOST_CHECK(Utils::fileExists(tmp1)==true);
    BOOST_CHECK(Utils::fileSize(tmp1)==3);

    // rename test
    Utils::renameFile(tmp2,tmp1);
    BOOST_CHECK(Utils::fileExists(tmp1)==false);
    BOOST_CHECK(Utils::fileExists(tmp2)==true);

    // read test
    std::istream* istr = Utils::openFile(tmp2);
    std::string yow;
    *istr >> yow;
    Utils::closeFile(istr);
    BOOST_CHECK(yow=="yow");

    // delete test
    Utils::deleteFile(tmp2);
    BOOST_CHECK(Utils::fileExists(tmp2)==false);
}

BOOST_AUTO_TEST_SUITE_END()
<commit_msg>do an epsilon compare for testing doubles<commit_after>/******************************************************************************
* Copyright (c) 2011, Michael P. Gerlek (mpg@flaxen.com)
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following
* conditions are met:
*
*     * Redistributions of source code must retain the above copyright
*       notice, this list of conditions and the following disclaimer.
*     * Redistributions in binary form must reproduce the above copyright
*       notice, this list of conditions and the following disclaimer in
*       the documentation and/or other materials provided
*       with the distribution.
*     * Neither the name of Hobu, Inc. or Flaxen Geo Consulting nor the
*       names of its contributors may be used to endorse or promote
*       products derived from this software without specific prior
*       written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
****************************************************************************/

#include <sstream>

#include <boost/test/unit_test.hpp>
#include <boost/cstdint.hpp>

#include <libpc/Range.hpp>

using namespace libpc;

BOOST_AUTO_TEST_SUITE(UtilsTest)

BOOST_AUTO_TEST_CASE(test_random)
{
    const double rangeMin = 0.0;
    const double rangeMax = 100.0;
    const double avg = (rangeMax - rangeMin) / 2.0;
    const int iters = 1000;

    Utils::random_seed(17);

    // make sure we treat the bounds as inclusive
    double sum=0;
    for (int i=0; i<iters; i++)
    {
        const double x = Utils::random(rangeMin, rangeMax);
        BOOST_CHECK(x >= rangeMin);
        BOOST_CHECK(x <= rangeMax);

        sum += x;
    }

    sum = sum / iters;

    BOOST_CHECK(sum <= avg + 0.1*avg);
    BOOST_CHECK(sum >= avg - 0.1*avg);
}

BOOST_AUTO_TEST_CASE(test_comparators)
{
    bool ok;

    {
        ok = Utils::compare_distance<float>(1.000001f, 1.0f);
        BOOST_CHECK(!ok);

        ok = Utils::compare_distance<float>(1.0000001f, 1.0f);
        BOOST_CHECK(ok);

        ok = Utils::compare_distance<float>(1.00000001f, 1.0f);
        BOOST_CHECK(ok);
    }

    {
        ok = Utils::compare_approx<float>(1.001f, 1.0f, 0.0001f);
        BOOST_CHECK(!ok);

        ok = Utils::compare_approx<float>(1.001f, 1.0f, 0.001f);
        BOOST_CHECK(!ok);

        ok = Utils::compare_approx<float>(1.001f, 1.0f, 0.01f);
        BOOST_CHECK(ok);

        ok = Utils::compare_approx<float>(1.001f, 1.0f, 0.1f);
        BOOST_CHECK(ok);
    }
}

BOOST_AUTO_TEST_CASE(test_buffer_read_write)
{
    const char buf[] = "quick brown fox";
    std::string bufstr(buf);

    std::ostringstream ostr;
    Utils::write_n(ostr, buf, 15);

    BOOST_CHECK(memcmp(buf, ostr.str().c_str(), 15) == 0);

    std::istringstream istr;
    istr.str(bufstr);
    boost::uint8_t tmp[30];
    Utils::read_n(tmp, istr, 15);
    BOOST_CHECK(memcmp(buf, tmp, 15) == 0);

    return;
}

BOOST_AUTO_TEST_CASE(test_field_read_write)
{
    boost::uint8_t buffer[100];
    boost::uint8_t* p = buffer;

    boost::uint8_t one = 1;
    double two = 2.0;

    Utils::write_field<boost::uint8_t>(p, one);
    Utils::write_field<double>(p, two);

    p = buffer;

    boost::uint8_t x = Utils::read_field<boost::uint8_t>(p);
    double y = Utils::read_field<double>(p);

    BOOST_CHECK(x==one);
    BOOST_CHECK(Utils::compare_approx(y, two, (double) 0.00001) == true);

    return;
}

BOOST_AUTO_TEST_CASE(test_file_ops)
{
    std::string tmp1 = "unittest1.tmp";
    std::string tmp2 = "unittest2.tmp";

    // first, clean up from any previous test run
    Utils::deleteFile(tmp1);
    Utils::deleteFile(tmp2);
    BOOST_CHECK(Utils::fileExists(tmp1)==false);
    BOOST_CHECK(Utils::fileExists(tmp2)==false);

    // write test
    std::ostream* ostr = Utils::createFile(tmp1);
    *ostr << "yow";
    Utils::closeFile(ostr);

    BOOST_CHECK(Utils::fileExists(tmp1)==true);
    BOOST_CHECK(Utils::fileSize(tmp1)==3);

    // rename test
    Utils::renameFile(tmp2,tmp1);
    BOOST_CHECK(Utils::fileExists(tmp1)==false);
    BOOST_CHECK(Utils::fileExists(tmp2)==true);

    // read test
    std::istream* istr = Utils::openFile(tmp2);
    std::string yow;
    *istr >> yow;
    Utils::closeFile(istr);
    BOOST_CHECK(yow=="yow");

    // delete test
    Utils::deleteFile(tmp2);
    BOOST_CHECK(Utils::fileExists(tmp2)==false);
}

BOOST_AUTO_TEST_SUITE_END()
<|endoftext|>


<commit_before>#include <iostream>
#include "../../Grammatica/Grammar Structure/Grammar-with-Map/cfgzero.h"
#include "../../Grammatica/Syntax-Tree/parser.h"
#include "../../Grammatica/Syntax-Tree/syntaxtree.h"

using namespace std;

void testTN();
void testTree();
void testSyntax();
void testParser();

int main()
{

//    testTN();

//    testTree();
//    testSyntax();
    testParser();
    return 0;
}

void
testTN()
{
    //Testing TreeNode Functions
    cout << "Initialized TreeNode with 4" << endl;
    TreeNode<int>* tr = new TreeNode<int>(4);
    cout << *tr << endl;

    cout << "Added Child 5" << endl;
    tr->addChild(5);
    cout << *tr << endl;
    cout << "Added Child 6" << endl;
    tr->addChild(6);
    cout << *tr << endl;
    cout << "Added Child 7" << endl;
    tr->addChild(7);
    cout << *tr << endl;

    cout << "The Children of 4" << endl;
    for(std::size_t i = 0; i < tr->children().size(); ++i){
        cout << *tr->children()[i] << "|";
    }
    cout << endl;

    cout << "Set Data of TreeNode to 10 from 4" << endl;
    tr->setData(4);
    cout << *tr << endl;

    cout << "Change children to 1,2,3" << endl;
    tr->setChildren({new TreeNode<int>(1),new TreeNode<int>(2),new TreeNode<int>(3)});
    cout << *tr << endl;

    //Testing Exterior TreeNode Functions of rt
    cout << "Copy the treeNode" << endl;
    TreeNode<int>* copy = rt::copy(tr);
    cout << tr << ": " << *tr << endl;
    cout << copy << ": " << *copy << endl;

    cout << "Clearing the copy" << endl;
    rt::clear(copy);
    cout << copy << endl;
    cout << *tr << endl;

    cout << "The size of tr" << endl;
    cout << rt::size(tr) << endl;
    cout << *tr << endl;

    cout << "Number of leaves of tr" <<endl;
    cout << rt::leaves(tr) << endl;
    cout << *tr << endl;

    cout << "Search for 3 in tr" << endl;
    cout << *rt::search(tr,3) << endl;

    cout << "Parent of 3 in tr" << endl;
    cout << *rt::parent(tr,rt::search(tr,3)) << endl;

    cout << "Vector of Leaves of tr" << endl;
    for(std::size_t i = 0; i < rt::allLeaves(tr).size(); ++i){
        cout << *rt::allLeaves(tr)[i] << "|";
    }
    cout << endl;
}

void
testTree()
{
    Tree<int> T;
    cout << "Add 10" << endl;
    T.addHere(10);
    cout << T << endl;
    cout << "Add 5 to 10" << endl;
    T.addHere(5);
    cout << T << endl;
    cout << "Add 15 to 10" << endl;
    T.addHere(15);
    cout << T << endl;
    cout << "Add 25 to 10" << endl;
    T.addHere(25);
    cout << T << endl;

    cout << "Add 30 to 15" << endl;
    T.addNode(T.search(15),30);
    cout << T << endl;

    cout << "This is current: " << endl;
    cout << *T.getCurrent() << endl;

    cout << "Shifting Current down to 25" << endl;
    T.shiftDown(2);
    cout << *T.getCurrent() << endl;

    cout << "Add 0 to 25" << endl;
    T.addHere(0);
    cout << T << endl;

    cout << "Search for 5" << endl;
    cout << *T.search(5) << endl;

    cout << "Set current to 3" << endl;
    T.set(3);
    cout << T << endl;

    cout << "Number of leaves" << endl;
    cout << T.leafNum() << endl;

    cout << "Shift to Root" << endl;
    T.shiftToRoot();
    cout << *T.getCurrent() << endl;

    cout << "Number of children of root" << endl;
    cout << T.childNum() << endl;
}

void
testSyntax()
{
    SyntaxTree T;
    cout << T << endl;

    cout << "Add Def of S->NP VP" << endl;
    T.addDef({NOUNPHRASE,VERBPHRASE});
    cout << T << endl;

    cout << "Remove Def of S" << endl;
    T.removeDef();
    cout << T << endl;

    cout << "Readding S->NP VP" << endl;
    T.addDef({NOUNPHRASE,VERBPHRASE});

    cout << "Get the Def of S" << endl;
    for(std::size_t i = 0; i < T.getDef().size(); ++i){
        cout << phraseLookUp[T.getDef()[i]] << "|";
    }
    cout << endl;

    cout << "Get Phrase of S" << endl;
    cout << phraseLookUp[T.getPhrase()] << endl;

    cout << "Get First Leaf" << endl;
    cout << *T.getFirstLeaf() << endl;

    cout << "Get Last Leaf" << endl;
    cout << *T.getLastLeaf() << endl;

    cout << "Add NP->D N" << endl;
    T.shiftDown(0);
    T.addDef({DETERMINER,NOUN});
    cout << T << endl;

    cout << "Get the leaves before VP" << endl;
    T.shiftUp();
    T.shiftDown(1);
    cout << *T.getCurrent() << endl;
    cout << T.leavesBefore() << endl;

    cout << "Testing assignHeads" << endl;
    T.assignHeads();
    cout << T << endl;
}

void
testParser()
{
    CFGZero Z;
    Wvector W;
    W.insert(W.end(),
//            {Word(Token("The",ALPHA),{determiner}),
//             Word(Token("cat",ALPHA),{noun}),
//             Word(Token("ate",ALPHA),{verb}),
//             Word(Token("an",ALPHA),{determiner}),
//             Word(Token("apple",ALPHA),{noun}),
//             Word(Token("on",ALPHA),{preposition}),
//             Word(Token("the",ALPHA),{determiner}),
//             Word(Token("tree",ALPHA),{noun})
//            {Word(Token("John",ALPHA),{verb,noun}),
//             Word(Token("kicks",ALPHA),{verb}),
//             Word(Token("ball",ALPHA),{noun}),
//             Word(Token("to",ALPHA),{preposition}),
//             Word(Token("Mark",ALPHA),{noun})
            {Word(Token("He",ALPHA),{noun}),
             Word(Token("walks",ALPHA),{verb})
             });
    Parser P(Z,W);
    cout << "Getting the Grammar" << endl;
    cout << P.getGrammar() << endl;

    cout << "Getting the Words" << endl;
    for(std::size_t i = 0; i < P.getSentence().size(); ++i){
        cout << P.getSentence()[i] << "|";
    }
    cout << endl;

    cout << "Parsing the Sentence based on Grammar" << endl;
    STvector S = P.parse();
    for(std::size_t i = 0; i < S.size(); ++i){
        cout << "#" << i+1 << ": " << S[i] << endl;
    }
    cout << endl;
}
<commit_msg>updated testing for getAll and getObj<commit_after>#include <iostream>
#include "../../Grammatica/Grammar Structure/Grammar-with-Map/cfgzero.h"
#include "../../Grammatica/Syntax-Tree/parser.h"
#include "../../Grammatica/Syntax-Tree/syntaxtree.h"

using namespace std;

void testTN();
void testTree();
void testSyntax();
void testParser();

int main()
{

//    testTN();

//    testTree();
//    testSyntax();
    testParser();
    return 0;
}

void
testTN()
{
    //Testing TreeNode Functions
    cout << "Initialized TreeNode with 4" << endl;
    TreeNode<int>* tr = new TreeNode<int>(4);
    cout << *tr << endl;

    cout << "Added Child 5" << endl;
    tr->addChild(5);
    cout << *tr << endl;
    cout << "Added Child 6" << endl;
    tr->addChild(6);
    cout << *tr << endl;
    cout << "Added Child 7" << endl;
    tr->addChild(7);
    cout << *tr << endl;

    cout << "The Children of 4" << endl;
    for(std::size_t i = 0; i < tr->children().size(); ++i){
        cout << *tr->children()[i] << "|";
    }
    cout << endl;

    cout << "Set Data of TreeNode to 10 from 4" << endl;
    tr->setData(4);
    cout << *tr << endl;

    cout << "Change children to 1,2,3" << endl;
    tr->setChildren({new TreeNode<int>(1),new TreeNode<int>(2),new TreeNode<int>(3)});
    cout << *tr << endl;

    //Testing Exterior TreeNode Functions of rt
    cout << "Copy the treeNode" << endl;
    TreeNode<int>* copy = rt::copy(tr);
    cout << tr << ": " << *tr << endl;
    cout << copy << ": " << *copy << endl;

    cout << "Clearing the copy" << endl;
    rt::clear(copy);
    cout << copy << endl;
    cout << *tr << endl;

    cout << "The size of tr" << endl;
    cout << rt::size(tr) << endl;
    cout << *tr << endl;

    cout << "Number of leaves of tr" <<endl;
    cout << rt::leaves(tr) << endl;
    cout << *tr << endl;

    cout << "Search for 3 in tr" << endl;
    cout << *rt::search(tr,3) << endl;

    cout << "Parent of 3 in tr" << endl;
    cout << *rt::parent(tr,rt::search(tr,3)) << endl;

    cout << "Vector of Leaves of tr" << endl;
    for(std::size_t i = 0; i < rt::allLeaves(tr).size(); ++i){
        cout << *rt::allLeaves(tr)[i] << "|";
    }
    cout << endl;
}

void
testTree()
{
    Tree<int> T;
    cout << "Add 10" << endl;
    T.addHere(10);
    cout << T << endl;
    cout << "Add 5 to 10" << endl;
    T.addHere(5);
    cout << T << endl;
    cout << "Add 15 to 10" << endl;
    T.addHere(15);
    cout << T << endl;
    cout << "Add 25 to 10" << endl;
    T.addHere(25);
    cout << T << endl;

    cout << "Add 30 to 15" << endl;
    T.addNode(T.search(15),30);
    cout << T << endl;

    cout << "This is current: " << endl;
    cout << *T.getCurrent() << endl;

    cout << "Shifting Current down to 25" << endl;
    T.shiftDown(2);
    cout << *T.getCurrent() << endl;

    cout << "Add 0 to 25" << endl;
    T.addHere(0);
    cout << T << endl;

    cout << "Search for 5" << endl;
    cout << *T.search(5) << endl;

    cout << "Set current to 3" << endl;
    T.set(3);
    cout << T << endl;

    cout << "Number of leaves" << endl;
    cout << T.leafNum() << endl;

    cout << "Shift to Root" << endl;
    T.shiftToRoot();
    cout << *T.getCurrent() << endl;

    cout << "Number of children of root" << endl;
    cout << T.childNum() << endl;
}

void
testSyntax()
{
    SyntaxTree T;
    cout << T << endl;

    cout << "Add Def of S->NP VP" << endl;
    T.addDef({NOUNPHRASE,VERBPHRASE});
    cout << T << endl;

    cout << "Remove Def of S" << endl;
    T.removeDef();
    cout << T << endl;

    cout << "Readding S->NP VP" << endl;
    T.addDef({NOUNPHRASE,VERBPHRASE});

    cout << "Get the Def of S" << endl;
    for(std::size_t i = 0; i < T.getDef().size(); ++i){
        cout << phraseLookUp[T.getDef()[i]] << "|";
    }
    cout << endl;

    cout << "Get Phrase of S" << endl;
    cout << phraseLookUp[T.getPhrase()] << endl;

    cout << "Get First Leaf" << endl;
    cout << *T.getFirstLeaf() << endl;

    cout << "Get Last Leaf" << endl;
    cout << *T.getLastLeaf() << endl;

    cout << "Add NP->D N" << endl;
    T.shiftDown(0);
    T.addDef({DETERMINER,NOUN});
    cout << T << endl;

    cout << "Get the leaves before VP" << endl;
    T.shiftUp();
    T.shiftDown(1);
    cout << *T.getCurrent() << endl;
    cout << T.leavesBefore() << endl;

    cout << "Testing assignHeads" << endl;
    T.assignHeads();
    cout << T << endl;
}

void
testParser()
{
    CFGZero Z;
    Wvector W;
    W.insert(W.end(),
//            {Word(Token("The",ALPHA),{determiner}),
//             Word(Token("cat",ALPHA),{noun}),
//             Word(Token("ate",ALPHA),{verb}),
//             Word(Token("an",ALPHA),{determiner}),
//             Word(Token("apple",ALPHA),{noun}),
//             Word(Token("on",ALPHA),{preposition}),
//             Word(Token("the",ALPHA),{determiner}),
//             Word(Token("tree",ALPHA),{noun})
//            {Word(Token("John",ALPHA),{verb,noun}),
//             Word(Token("kicks",ALPHA),{verb}),
//             Word(Token("ball",ALPHA),{noun}),
//             Word(Token("to",ALPHA),{preposition}),
//             Word(Token("Mark",ALPHA),{noun})
            {Word(Token("He",ALPHA),{noun}),
             Word(Token("walks",ALPHA),{verb})
             });
    Parser P(Z,W);
    cout << "Getting the Grammar" << endl;
    cout << P.getGrammar() << endl;

    cout << "Getting the Words" << endl;
    for(std::size_t i = 0; i < P.getSentence().size(); ++i){
        cout << P.getSentence()[i] << "|";
    }
    cout << endl;

    cout << "Parsing the Sentence based on Grammar" << endl;
    STvector S = P.parse();
    for(std::size_t i = 0; i < S.size(); ++i){
        cout << "#" << i+1 << ": " << S[i] << endl;
    }
    cout << endl;

    cout << "Get a Specific Syntax: SUBJECT" << endl;
    std::vector<SyntaxWord> T = P.getObj(*S.begin(),SUBJECT);
    for(std::size_t i = 0; i < T.size(); ++i){
        cout << T[i] << endl;
    }
    cout << "Get ALL Syntaxes" << endl;
    std::vector<SyntaxWord> A = P.getAll(*S.begin());
    for(std::size_t i = 0; i < A.size(); ++i){
        cout << A[i] << endl;
    }
}
<|endoftext|>


<commit_before>#include "message.h"
#include "qcolor.h"
#include "colorscheme.h"
#include "emotes.h"

LazyLoadedImage* Message::badgeStaff       = new LazyLoadedImage(new QImage(":/images/staff_bg.png"));
LazyLoadedImage* Message::badgeAdmin       = new LazyLoadedImage(new QImage(":/images/admin_bg.png"));
LazyLoadedImage* Message::badgeModerator   = new LazyLoadedImage(new QImage(":/images/moderator_bg.png"));
LazyLoadedImage* Message::badgeGlobalmod   = new LazyLoadedImage(new QImage(":/images/globalmod_bg.png"));
LazyLoadedImage* Message::badgeTurbo       = new LazyLoadedImage(new QImage(":/images/turbo_bg.png"));
LazyLoadedImage* Message::badgeBroadcaster = new LazyLoadedImage(new QImage(":/images/broadcaster_bg.png"));
LazyLoadedImage* Message::badgePremium     = new LazyLoadedImage(new QImage(":/images/twitchprime_bg.png"));

Message::Message(const QString &text)
{

}

Message::Message(const IrcPrivateMessage& ircMessage, const Channel& Channel)
{
    m_parseTime = std::chrono::system_clock::now();

    auto words = new QList<Word>();

    // timestamps
    auto iterator = ircMessage.tags().find("tmi-sent-ts");
    time_t time = std::time(NULL);

    if (iterator != ircMessage.tags().end())
    {
        time = strtoll(iterator.value().toString().toStdString().c_str(), NULL, 10);
    }

    char timeStampBuffer[69];

    strftime(timeStampBuffer, 69, "%H:%M", localtime(&time));
    QString timestamp = QString(timeStampBuffer);

    strftime(timeStampBuffer, 69, "%H:%M:%S", localtime(&time));
    QString timestampWithSeconds = QString(timeStampBuffer);

    QString copytext("");
    QString tooltip("");

//    words->append(*new Word(timestamp, Word::TimestampNoSeconds, copytext, tooltip));
//    words->append(*new Word(timestampWithSeconds, Word::TimestampWithSeconds, copytext, tooltip));

    // username
    m_userName = ircMessage.account();

    if (m_userName.isEmpty())
    {
        auto iterator = ircMessage.tags().find("login");

        if (iterator != ircMessage.tags().end())
        {
            m_userName = iterator.value().toString();
        }
    }

    // display name
    QString displayName;

    iterator = ircMessage.tags().find("display-name");
    if (iterator == ircMessage.tags().end()) {
        displayName = m_userName;
    }
    else {
        displayName = iterator.value().toString();
    }

    // highlights
#pragma message WARN("xD")

    // color
    QColor usernameColor = ColorScheme::getInstance().SystemMessageColor;

    iterator = ircMessage.tags().find("color");
    if (iterator != ircMessage.tags().end())
    {
         usernameColor = QColor(iterator.value().toString());
    }

    // bits
    QString bits = "";

    iterator = ircMessage.tags().find("bits");
    if (iterator != ircMessage.tags().end())
    {
         bits = iterator.value().toString();
    }

    // badges
    iterator = ircMessage.tags().find("badges");

    if (iterator != ircMessage.tags().end())
    {
        auto badges = iterator.value().toString().split(',');

        for (QString badge : badges)
        {
            if (badge.startsWith("bits/"))
            {

            }
            else if (badge == "staff/1")
            {
                QString a("");
                QString b("Twitch Staff");
                words->append(*new Word(badgeStaff, Word::BadgeStaff, a, b));
            }
//            else if (badge == "admin/1")
//            {
//                words->append(*new Word(badgeAdmin, Word::BadgeAdmin, "", "Twitch Admin"));
//            }
//            else if (badge == "global_mod/1")
//            {
//                words->append(*new Word(badgeGlobalmod, Word::BadgeGlobalMod, "", "Global Moderator"));
//            }
//            else if (badge == "moderator/1")
//            {
//#warning "xD"
//                words->append(*new Word(badgeTurbo, Word::BadgeModerator, "", "Channel Moderator")); // custom badge
//            }
//            else if (badge == "turbo/1")
//            {
//                words->append(*new Word(badgeStaff, Word::BadgeTurbo, "", "Turbo Subscriber"));
//            }
//            else if (badge == "broadcaster/1")
//            {
//                words->append(*new Word(badgeBroadcaster, Word::BadgeBroadcaster, "", "Channel Broadcaster"));
//            }
//            else if (badge == "premium/1")
//            {
//                words->append(*new Word(badgeTwitchPrime, Word::BadgePremium, "", "Twitch Prime"));
//            }

//            case "staff/1":
//                Badges |= MessageBadges.Staff;
//                words.Add(new Word { Type = SpanType.Image, Value = GuiEngine.Current.GetImage(ImageType.BadgeStaff), Tooltip =  });
//                break;
//            case "admin/1":
//                Badges |= MessageBadges.Admin;
//                words.Add(new Word { Type = SpanType.Image, Value = GuiEngine.Current.GetImage(ImageType.BadgeAdmin), Tooltip = "Twitch Admin" });
//                break;
//            case "global_mod/1":
//                Badges |= MessageBadges.GlobalMod;
//                words.Add(new Word { Type = SpanType.Image, Value = GuiEngine.Current.GetImage(ImageType.BadgeGlobalmod), Tooltip = "Global Moderator" });
//                break;
//            case "moderator/1":
//                Badges |= MessageBadges.Mod;
//                if (channel.ModeratorBadge == null)
//                {
//                    words.Add(new Word { Type = SpanType.Image, Value = GuiEngine.Current.GetImage(ImageType.BadgeModerator), Tooltip = "Channel Moderator" });
//                }
//                else
//                {
//                    words.Add(new Word { Type = SpanType.LazyLoadedImage, Value = channel.ModeratorBadge, Tooltip = channel.ModeratorBadge.Tooltip });
//                }
//                break;
//            case "turbo/1":
//                Badges |= MessageBadges.Turbo;
//                words.Add(new Word { Type = SpanType.Image, Value = GuiEngine.Current.GetImage(ImageType.BadgeTurbo), Tooltip = "Turbo Subscriber" });
//                break;
//            case "broadcaster/1":
//                Badges |= MessageBadges.Broadcaster;
//                words.Add(new Word { Type = SpanType.Image, Value = GuiEngine.Current.GetImage(ImageType.BadgeBroadcaster), Tooltip = "Channel Broadcaster" });
//                break;
//            case "premium/1":
//                Badges |= MessageBadges.Broadcaster;
//                words.Add(new Word { Type = SpanType.Image, Value = GuiEngine.Current.GetImage(ImageType.BadgeTwitchPrime), Tooltip = "Twitch Prime" });
//                break;

//                 long long int cheer = strtoll(badge.mid(5).toStdString().c_str(), NULL, 10);

//            auto image = Emotes::getCheerImage(cheer, false);
//            auto imageAnimated = Emotes::getCheerImage(cheer, true);

//            words->append(*new Word(image, Word::Bits));
//            words->append(*new Word(imageAnimated, Word::BitsAnimated));

        }
    }
}
<commit_msg>now compiles properly in MSVC<commit_after>#include "message.h"
#include "qcolor.h"
#include "colorscheme.h"
#include "emotes.h"

#include <ctime>

LazyLoadedImage* Message::badgeStaff       = new LazyLoadedImage(new QImage(":/images/staff_bg.png"));
LazyLoadedImage* Message::badgeAdmin       = new LazyLoadedImage(new QImage(":/images/admin_bg.png"));
LazyLoadedImage* Message::badgeModerator   = new LazyLoadedImage(new QImage(":/images/moderator_bg.png"));
LazyLoadedImage* Message::badgeGlobalmod   = new LazyLoadedImage(new QImage(":/images/globalmod_bg.png"));
LazyLoadedImage* Message::badgeTurbo       = new LazyLoadedImage(new QImage(":/images/turbo_bg.png"));
LazyLoadedImage* Message::badgeBroadcaster = new LazyLoadedImage(new QImage(":/images/broadcaster_bg.png"));
LazyLoadedImage* Message::badgePremium     = new LazyLoadedImage(new QImage(":/images/twitchprime_bg.png"));

Message::Message(const QString &text)
{

}

Message::Message(const IrcPrivateMessage& ircMessage, const Channel& Channel)
{
    m_parseTime = std::chrono::system_clock::now();

    auto words = new QList<Word>();

    // timestamps
    auto iterator = ircMessage.tags().find("tmi-sent-ts");
    std::time_t time = std::time(NULL);

    if (iterator != ircMessage.tags().end())
    {
        time = strtoll(iterator.value().toString().toStdString().c_str(), NULL, 10);
    }

    char timeStampBuffer[69];

    strftime(timeStampBuffer, 69, "%H:%M", localtime(&time));
    QString timestamp = QString(timeStampBuffer);

    strftime(timeStampBuffer, 69, "%H:%M:%S", localtime(&time));
    QString timestampWithSeconds = QString(timeStampBuffer);

    QString copytext("");
    QString tooltip("");

//    words->append(*new Word(timestamp, Word::TimestampNoSeconds, copytext, tooltip));
//    words->append(*new Word(timestampWithSeconds, Word::TimestampWithSeconds, copytext, tooltip));

    // username
    m_userName = ircMessage.account();

    if (m_userName.isEmpty())
    {
        auto iterator = ircMessage.tags().find("login");

        if (iterator != ircMessage.tags().end())
        {
            m_userName = iterator.value().toString();
        }
    }

    // display name
    QString displayName;

    iterator = ircMessage.tags().find("display-name");
    if (iterator == ircMessage.tags().end()) {
        displayName = m_userName;
    }
    else {
        displayName = iterator.value().toString();
    }

    // highlights
#pragma message WARN("xD")

    // color
    QColor usernameColor = ColorScheme::getInstance().SystemMessageColor;

    iterator = ircMessage.tags().find("color");
    if (iterator != ircMessage.tags().end())
    {
         usernameColor = QColor(iterator.value().toString());
    }

    // bits
    QString bits = "";

    iterator = ircMessage.tags().find("bits");
    if (iterator != ircMessage.tags().end())
    {
         bits = iterator.value().toString();
    }

    // badges
    iterator = ircMessage.tags().find("badges");

    if (iterator != ircMessage.tags().end())
    {
        auto badges = iterator.value().toString().split(',');

        for (QString badge : badges)
        {
            if (badge.startsWith("bits/"))
            {

            }
            else if (badge == "staff/1")
            {
                QString a("");
                QString b("Twitch Staff");
                words->append(*new Word(badgeStaff, Word::BadgeStaff, a, b));
            }
//            else if (badge == "admin/1")
//            {
//                words->append(*new Word(badgeAdmin, Word::BadgeAdmin, "", "Twitch Admin"));
//            }
//            else if (badge == "global_mod/1")
//            {
//                words->append(*new Word(badgeGlobalmod, Word::BadgeGlobalMod, "", "Global Moderator"));
//            }
//            else if (badge == "moderator/1")
//            {
//#warning "xD"
//                words->append(*new Word(badgeTurbo, Word::BadgeModerator, "", "Channel Moderator")); // custom badge
//            }
//            else if (badge == "turbo/1")
//            {
//                words->append(*new Word(badgeStaff, Word::BadgeTurbo, "", "Turbo Subscriber"));
//            }
//            else if (badge == "broadcaster/1")
//            {
//                words->append(*new Word(badgeBroadcaster, Word::BadgeBroadcaster, "", "Channel Broadcaster"));
//            }
//            else if (badge == "premium/1")
//            {
//                words->append(*new Word(badgeTwitchPrime, Word::BadgePremium, "", "Twitch Prime"));
//            }

//            case "staff/1":
//                Badges |= MessageBadges.Staff;
//                words.Add(new Word { Type = SpanType.Image, Value = GuiEngine.Current.GetImage(ImageType.BadgeStaff), Tooltip =  });
//                break;
//            case "admin/1":
//                Badges |= MessageBadges.Admin;
//                words.Add(new Word { Type = SpanType.Image, Value = GuiEngine.Current.GetImage(ImageType.BadgeAdmin), Tooltip = "Twitch Admin" });
//                break;
//            case "global_mod/1":
//                Badges |= MessageBadges.GlobalMod;
//                words.Add(new Word { Type = SpanType.Image, Value = GuiEngine.Current.GetImage(ImageType.BadgeGlobalmod), Tooltip = "Global Moderator" });
//                break;
//            case "moderator/1":
//                Badges |= MessageBadges.Mod;
//                if (channel.ModeratorBadge == null)
//                {
//                    words.Add(new Word { Type = SpanType.Image, Value = GuiEngine.Current.GetImage(ImageType.BadgeModerator), Tooltip = "Channel Moderator" });
//                }
//                else
//                {
//                    words.Add(new Word { Type = SpanType.LazyLoadedImage, Value = channel.ModeratorBadge, Tooltip = channel.ModeratorBadge.Tooltip });
//                }
//                break;
//            case "turbo/1":
//                Badges |= MessageBadges.Turbo;
//                words.Add(new Word { Type = SpanType.Image, Value = GuiEngine.Current.GetImage(ImageType.BadgeTurbo), Tooltip = "Turbo Subscriber" });
//                break;
//            case "broadcaster/1":
//                Badges |= MessageBadges.Broadcaster;
//                words.Add(new Word { Type = SpanType.Image, Value = GuiEngine.Current.GetImage(ImageType.BadgeBroadcaster), Tooltip = "Channel Broadcaster" });
//                break;
//            case "premium/1":
//                Badges |= MessageBadges.Broadcaster;
//                words.Add(new Word { Type = SpanType.Image, Value = GuiEngine.Current.GetImage(ImageType.BadgeTwitchPrime), Tooltip = "Twitch Prime" });
//                break;

//                 long long int cheer = strtoll(badge.mid(5).toStdString().c_str(), NULL, 10);

//            auto image = Emotes::getCheerImage(cheer, false);
//            auto imageAnimated = Emotes::getCheerImage(cheer, true);

//            words->append(*new Word(image, Word::Bits));
//            words->append(*new Word(imageAnimated, Word::BitsAnimated));

        }
    }
}
<|endoftext|>


<commit_before>//
// Copyright(c) 2016-2017 benikabocha.
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
//

#include <Saba/Base/UnicodeUtil.h>
#include <Saba/Base/Path.h>
#include <Saba/Model/MMD/MMDModel.h>
#include <Saba/Model/MMD/PMDModel.h>
#include <Saba/Model/MMD/PMXModel.h>
#include <Saba/Model/MMD/VMDFile.h>
#include <Saba/Model/MMD/VMDAnimation.h>
#include <Saba/Model/MMD/VPDFile.h>

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

void Usage()
{
	std::cout << "mmd2obj <pmd/pmx file> [-vmd <vmd file>] [-t <animation time (sec)>] [-vpd <vpd file>]\n";
}

bool MMD2Obj(const std::vector<std::string>& args)
{
	if (args.size() <= 1)
	{
		Usage();
		return false;
	}

	// Analyze commad line.
	const std::string& modelPath = args[1];
	std::vector<std::string> vmdPaths;
	std::string vpdPath;
	double	animTime = 0.0;

	for (size_t i = 2; i < args.size(); i++)
	{
		if (args[i] == "-vmd")
		{
			i++;
			if (i < args.size())
			{
				vmdPaths.push_back(args[i]);
			}
			else
			{
				Usage();
				return false;
			}
		}
		else if (args[i] == "-t")
		{
			i++;
			if (i < args.size())
			{
				animTime = std::stod(args[i]);
			}
			else
			{
				Usage();
				return false;
			}
		}
		else if (args[i] == "-vpd")
		{
			i++;
			if (i < args.size())
			{
				vpdPath = args[i];
			}
			else
			{
				Usage();
				return false;
			}
		}
		else
		{
			Usage();
			return false;
		}
	}

	// Load model.
	std::shared_ptr<saba::MMDModel> mmdModel;
	std::string mmdDataPath = "";	// Set MMD data path(default toon texture path).
	std::string ext = saba::PathUtil::GetExt(modelPath);
	if (ext == "pmd")
	{
		auto pmdModel = std::make_unique<saba::PMDModel>();
		if (!pmdModel->Load(modelPath, mmdDataPath))
		{
			std::cout << "Failed to load PMDModel.\n";
			return false;
		}
		mmdModel = std::move(pmdModel);
	}
	else if (ext == "pmx")
	{
		auto pmxModel = std::make_unique<saba::PMXModel>();
		if (!pmxModel->Load(modelPath, mmdDataPath))
		{
			std::cout << "Failed to load PMXModel.\n";
			return false;
		}
		mmdModel = std::move(pmxModel);
	}
	else
	{
		std::cout << "Unsupported Model Ext : " << ext << "\n";
		return false;
	}

	// Load animation.
	bool useVMDAnimation = !vmdPaths.empty();
	auto vmdAnim = std::make_unique<saba::VMDAnimation>();
	if (!vmdAnim->Create(mmdModel))
	{
		std::cout << "Failed to create VMDAnimation.\n";
		return false;
	}
	for (const auto& vmdPath : vmdPaths)
	{
		saba::VMDFile vmdFile;
		if (!saba::ReadVMDFile(&vmdFile, vmdPath.c_str()))
		{
			std::cout << "Failed to read VMD file.\n";
			return false;
		}
		if (!vmdAnim->Add(vmdFile))
		{
			std::cout << "Failed to add VMDAnimation.\n";
			return false;
		}
	}

	// Load pose.
	saba::VPDFile vpdFile;
	if (!vpdPath.empty())
	{
		if (!vmdPaths.empty())
		{
			std::cout << "Warning : Canceled to read VPD file.";
		}
		else
		{
			if (!saba::ReadVPDFile(&vpdFile, vpdPath.c_str()))
			{
				std::cout << "Failed to read VPD file.\n";
				return false;
			}

		}
	}

	// Initialize pose.
	{
		// Sync physics animation.
		mmdModel->InitializeAnimation();
		if (useVMDAnimation)
		{
			vmdAnim->SyncPhysics((float)animTime * 30.0f);
		}
		else
		{
			mmdModel->LoadPose(vpdFile);
		}
	}

	// Update animation(animation loop).
	{
		// Update bone animation.
		mmdModel->BeginAnimation();
		if (useVMDAnimation)
		{
			vmdAnim->Evaluate((float)animTime * 30.0f);
		}
		mmdModel->UpdateAnimation();
		mmdModel->EndAnimation();

		// Update physics animation.
		mmdModel->UpdatePhysics(1.0f / 60.0f);

		// Update vertex.
		mmdModel->Update();
	}

	// Output OBJ file.
	std::ofstream objFile;
	objFile.open("output.obj");
	if (!objFile.is_open())
	{
		std::cout << "Failed to open OBJ file.\n";
		return false;
	}
	objFile << "# mmmd2obj\n";
	objFile << "mtllib output.mtl\n";

	// Write positions.
	size_t vtxCount = mmdModel->GetVertexCount();
	const glm::vec3* positions = mmdModel->GetUpdatePositions();
	for (size_t i = 0; i < vtxCount; i++)
	{
		objFile << "v " << positions[i].x << " " << positions[i].y << " " << positions[i].z << "\n";
	}
	const glm::vec3* normals = mmdModel->GetUpdateNormals();
	for (size_t i = 0; i < vtxCount; i++)
	{
		objFile << "vn " << normals[i].x << " " << normals[i].y << " " << normals[i].z << "\n";
	}
	const glm::vec2* uvs = mmdModel->GetUpdateUVs();
	for (size_t i = 0; i < vtxCount; i++)
	{
		objFile << "vt " << uvs[i].x << " " << uvs[i].y << "\n";
	}

	// Copy vertex indices.
	std::vector<size_t> indices(mmdModel->GetIndexCount());
	if (mmdModel->GetIndexElementSize() == 1)
	{
		uint8_t* mmdIndices = (uint8_t*)mmdModel->GetIndices();
		for (size_t i = 0; i < indices.size(); i++)
		{
			indices[i] = mmdIndices[i];
		}
	}
	else if (mmdModel->GetIndexElementSize() == 2)
	{
		uint16_t* mmdIndices = (uint16_t*)mmdModel->GetIndices();
		for (size_t i = 0; i < indices.size(); i++)
		{
			indices[i] = mmdIndices[i];
		}
	}
	else if (mmdModel->GetIndexElementSize() == 4)
	{
		uint32_t* mmdIndices = (uint32_t*)mmdModel->GetIndices();
		for (size_t i = 0; i < indices.size(); i++)
		{
			indices[i] = mmdIndices[i];
		}
	}
	else
	{
		return false;
	}

	// Write faces.
	size_t subMeshCount = mmdModel->GetSubMeshCount();
	const saba::MMDSubMesh* subMeshes = mmdModel->GetSubMeshes();
	for (size_t i = 0; i < subMeshCount; i++)
	{
		objFile << "\n";
		objFile << "usemtl " << subMeshes[i].m_materialID << "\n";

		for (size_t j = 0; j < subMeshes[i].m_vertexCount; j += 3)
		{
			auto vtxIdx = subMeshes[i].m_beginIndex + j;
			auto vi0 = indices[vtxIdx + 0] + 1;
			auto vi1 = indices[vtxIdx + 1] + 1;
			auto vi2 = indices[vtxIdx + 2] + 1;
			objFile << "f "
				<< vi0 << "/" << vi0 << "/" << vi0 << " "
				<< vi1 << "/" << vi1 << "/" << vi1 << " "
				<< vi2 << "/" << vi2 << "/" << vi2 << "\n";
		}
	}
	objFile.close();

	// Write materials.
	std::ofstream mtlFile;
	mtlFile.open("output.mtl");
	if (!mtlFile.is_open())
	{
		std::cout << "Failed to open MTL file.\n";
		return false;
	}

	objFile << "# mmmd2obj\n";
	size_t materialCount = mmdModel->GetMaterialCount();
	const saba::MMDMaterial* materials = mmdModel->GetMaterials();
	for (size_t i = 0; i < materialCount; i++)
	{
		const auto& m = materials[i];
		mtlFile << "newmtl " << i << "\n";

		mtlFile << "Ka " << m.m_ambient.r << " " << m.m_ambient.g << " " << m.m_ambient.b << "\n";
		mtlFile << "Kd " << m.m_diffuse.r << " " << m.m_diffuse.g << " " << m.m_diffuse.b << "\n";
		mtlFile << "Ks " << m.m_specular.r << " " << m.m_specular.g << " " << m.m_specular.b << "\n";
		mtlFile << "d " << m.m_alpha << "\n";
		mtlFile << "map_Kd " << m.m_texture << "\n";
		mtlFile << "\n";
	}
	mtlFile.close();

	return true;
}

#if _WIN32
int wmain(int argc, wchar_t** argv)
{
	std::vector<std::string> args(argc);
	for (int i = 0; i < argc; i++)
	{
		args[i] = saba::ToUtf8String(argv[i]);
	}

	if (!MMD2Obj(args))
	{
		std::cout << "Failed to convert model data.\n";
		return 1;
	}

	return 0;
}
#else // _WIN32
int main(int argc, char** argv)
{
	std::vector<std::string> args(argc);
	for (int i = 0; i < argc; i++)
	{
		args[i] = argv[i];
	}

	if (!MMD2Obj(args))
	{
		std::cout << "Failed to convert model data.\n";
		return 1;
	}

	return 0;
}
#endif // _WIN32<commit_msg>update mmd2obj flip uv<commit_after>//
// Copyright(c) 2016-2017 benikabocha.
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
//

#include <Saba/Base/UnicodeUtil.h>
#include <Saba/Base/Path.h>
#include <Saba/Model/MMD/MMDModel.h>
#include <Saba/Model/MMD/PMDModel.h>
#include <Saba/Model/MMD/PMXModel.h>
#include <Saba/Model/MMD/VMDFile.h>
#include <Saba/Model/MMD/VMDAnimation.h>
#include <Saba/Model/MMD/VPDFile.h>

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

void Usage()
{
	std::cout << "mmd2obj <pmd/pmx file> [-vmd <vmd file>] [-t <animation time (sec)>] [-vpd <vpd file>]\n";
}

bool MMD2Obj(const std::vector<std::string>& args)
{
	if (args.size() <= 1)
	{
		Usage();
		return false;
	}

	// Analyze commad line.
	const std::string& modelPath = args[1];
	std::vector<std::string> vmdPaths;
	std::string vpdPath;
	double	animTime = 0.0;

	for (size_t i = 2; i < args.size(); i++)
	{
		if (args[i] == "-vmd")
		{
			i++;
			if (i < args.size())
			{
				vmdPaths.push_back(args[i]);
			}
			else
			{
				Usage();
				return false;
			}
		}
		else if (args[i] == "-t")
		{
			i++;
			if (i < args.size())
			{
				animTime = std::stod(args[i]);
			}
			else
			{
				Usage();
				return false;
			}
		}
		else if (args[i] == "-vpd")
		{
			i++;
			if (i < args.size())
			{
				vpdPath = args[i];
			}
			else
			{
				Usage();
				return false;
			}
		}
		else
		{
			Usage();
			return false;
		}
	}

	// Load model.
	std::shared_ptr<saba::MMDModel> mmdModel;
	std::string mmdDataPath = "";	// Set MMD data path(default toon texture path).
	std::string ext = saba::PathUtil::GetExt(modelPath);
	if (ext == "pmd")
	{
		auto pmdModel = std::make_unique<saba::PMDModel>();
		if (!pmdModel->Load(modelPath, mmdDataPath))
		{
			std::cout << "Failed to load PMDModel.\n";
			return false;
		}
		mmdModel = std::move(pmdModel);
	}
	else if (ext == "pmx")
	{
		auto pmxModel = std::make_unique<saba::PMXModel>();
		if (!pmxModel->Load(modelPath, mmdDataPath))
		{
			std::cout << "Failed to load PMXModel.\n";
			return false;
		}
		mmdModel = std::move(pmxModel);
	}
	else
	{
		std::cout << "Unsupported Model Ext : " << ext << "\n";
		return false;
	}

	// Load animation.
	bool useVMDAnimation = !vmdPaths.empty();
	auto vmdAnim = std::make_unique<saba::VMDAnimation>();
	if (!vmdAnim->Create(mmdModel))
	{
		std::cout << "Failed to create VMDAnimation.\n";
		return false;
	}
	for (const auto& vmdPath : vmdPaths)
	{
		saba::VMDFile vmdFile;
		if (!saba::ReadVMDFile(&vmdFile, vmdPath.c_str()))
		{
			std::cout << "Failed to read VMD file.\n";
			return false;
		}
		if (!vmdAnim->Add(vmdFile))
		{
			std::cout << "Failed to add VMDAnimation.\n";
			return false;
		}
	}

	// Load pose.
	saba::VPDFile vpdFile;
	if (!vpdPath.empty())
	{
		if (!vmdPaths.empty())
		{
			std::cout << "Warning : Canceled to read VPD file.";
		}
		else
		{
			if (!saba::ReadVPDFile(&vpdFile, vpdPath.c_str()))
			{
				std::cout << "Failed to read VPD file.\n";
				return false;
			}

		}
	}

	// Initialize pose.
	{
		// Sync physics animation.
		mmdModel->InitializeAnimation();
		if (useVMDAnimation)
		{
			vmdAnim->SyncPhysics((float)animTime * 30.0f);
		}
		else
		{
			mmdModel->LoadPose(vpdFile);
		}
	}

	// Update animation(animation loop).
	{
		// Update bone animation.
		mmdModel->BeginAnimation();
		if (useVMDAnimation)
		{
			vmdAnim->Evaluate((float)animTime * 30.0f);
		}
		mmdModel->UpdateAnimation();
		mmdModel->EndAnimation();

		// Update physics animation.
		mmdModel->UpdatePhysics(1.0f / 60.0f);

		// Update vertex.
		mmdModel->Update();
	}

	// Output OBJ file.
	std::ofstream objFile;
	objFile.open("output.obj");
	if (!objFile.is_open())
	{
		std::cout << "Failed to open OBJ file.\n";
		return false;
	}
	objFile << "# mmmd2obj\n";
	objFile << "mtllib output.mtl\n";

	// Write positions.
	size_t vtxCount = mmdModel->GetVertexCount();
	const glm::vec3* positions = mmdModel->GetUpdatePositions();
	for (size_t i = 0; i < vtxCount; i++)
	{
		objFile << "v " << positions[i].x << " " << positions[i].y << " " << positions[i].z << "\n";
	}
	const glm::vec3* normals = mmdModel->GetUpdateNormals();
	for (size_t i = 0; i < vtxCount; i++)
	{
		objFile << "vn " << normals[i].x << " " << normals[i].y << " " << normals[i].z << "\n";
	}
	const glm::vec2* uvs = mmdModel->GetUpdateUVs();
	for (size_t i = 0; i < vtxCount; i++)
	{
		objFile << "vt " << uvs[i].x << " " << 1.0 - uvs[i].y << "\n";
	}

	// Copy vertex indices.
	std::vector<size_t> indices(mmdModel->GetIndexCount());
	if (mmdModel->GetIndexElementSize() == 1)
	{
		uint8_t* mmdIndices = (uint8_t*)mmdModel->GetIndices();
		for (size_t i = 0; i < indices.size(); i++)
		{
			indices[i] = mmdIndices[i];
		}
	}
	else if (mmdModel->GetIndexElementSize() == 2)
	{
		uint16_t* mmdIndices = (uint16_t*)mmdModel->GetIndices();
		for (size_t i = 0; i < indices.size(); i++)
		{
			indices[i] = mmdIndices[i];
		}
	}
	else if (mmdModel->GetIndexElementSize() == 4)
	{
		uint32_t* mmdIndices = (uint32_t*)mmdModel->GetIndices();
		for (size_t i = 0; i < indices.size(); i++)
		{
			indices[i] = mmdIndices[i];
		}
	}
	else
	{
		return false;
	}

	// Write faces.
	size_t subMeshCount = mmdModel->GetSubMeshCount();
	const saba::MMDSubMesh* subMeshes = mmdModel->GetSubMeshes();
	for (size_t i = 0; i < subMeshCount; i++)
	{
		objFile << "\n";
		objFile << "usemtl " << subMeshes[i].m_materialID << "\n";

		for (size_t j = 0; j < subMeshes[i].m_vertexCount; j += 3)
		{
			auto vtxIdx = subMeshes[i].m_beginIndex + j;
			auto vi0 = indices[vtxIdx + 0] + 1;
			auto vi1 = indices[vtxIdx + 1] + 1;
			auto vi2 = indices[vtxIdx + 2] + 1;
			objFile << "f "
				<< vi0 << "/" << vi0 << "/" << vi0 << " "
				<< vi1 << "/" << vi1 << "/" << vi1 << " "
				<< vi2 << "/" << vi2 << "/" << vi2 << "\n";
		}
	}
	objFile.close();

	// Write materials.
	std::ofstream mtlFile;
	mtlFile.open("output.mtl");
	if (!mtlFile.is_open())
	{
		std::cout << "Failed to open MTL file.\n";
		return false;
	}

	objFile << "# mmmd2obj\n";
	size_t materialCount = mmdModel->GetMaterialCount();
	const saba::MMDMaterial* materials = mmdModel->GetMaterials();
	for (size_t i = 0; i < materialCount; i++)
	{
		const auto& m = materials[i];
		mtlFile << "newmtl " << i << "\n";

		mtlFile << "Ka " << m.m_ambient.r << " " << m.m_ambient.g << " " << m.m_ambient.b << "\n";
		mtlFile << "Kd " << m.m_diffuse.r << " " << m.m_diffuse.g << " " << m.m_diffuse.b << "\n";
		mtlFile << "Ks " << m.m_specular.r << " " << m.m_specular.g << " " << m.m_specular.b << "\n";
		mtlFile << "d " << m.m_alpha << "\n";
		mtlFile << "map_Kd " << saba::PathUtil::GetFilename(m.m_texture) << "\n";
		mtlFile << "\n";
	}
	mtlFile.close();

	return true;
}

#if _WIN32
int wmain(int argc, wchar_t** argv)
{
	std::vector<std::string> args(argc);
	for (int i = 0; i < argc; i++)
	{
		args[i] = saba::ToUtf8String(argv[i]);
	}

	if (!MMD2Obj(args))
	{
		std::cout << "Failed to convert model data.\n";
		return 1;
	}

	return 0;
}
#else // _WIN32
int main(int argc, char** argv)
{
	std::vector<std::string> args(argc);
	for (int i = 0; i < argc; i++)
	{
		args[i] = argv[i];
	}

	if (!MMD2Obj(args))
	{
		std::cout << "Failed to convert model data.\n";
		return 1;
	}

	return 0;
}
#endif // _WIN32<|endoftext|>


<commit_before>//
//  nthRoot.cpp
//  Calculator
//
//  Created by Gavin Scheele on 3/27/14.
//  Copyright (c) 2014 Gavin Scheele. All rights reserved.
//

#include "nthRoot.h"
#include "Integer.h"
#include <array>
using namespace std;
nthRoot::nthRoot(int root, int operand, int coefficient) {
    this->type = "nthRoot";
    this->operand = operand;
    this->root = root;
    this->coefficient = coefficient;
    this->simplify();

    if ((root % 2) == 0 && operand < 0) {
        throw runtime_error("unreal answer");
    }
}

nthRoot::nthRoot(int root, Expression* eoperand, int coefficient) {
    this->type = "nthRoot";
    this->eoperand = eoperand;
    this->root = root;
    this->coefficient = coefficient;

    if ((root % 2) == 0 && eoperand->type == "integer") {
        Integer *a = (Integer *)eoperand;
        if (a->getValue() < 0) {
            throw runtime_error("unreal answer");
        }
    }

    if ((root % 2) == 0 && eoperand->type == "Rational"){
        Rational *b = (Rational*)eoperand;
        if ((b->getNumerator() < 0 || b->getDenominator() < 0)
             && !(b->getNumerator() < 0 && b->getDenominator() < 0)) {
             throw runtime_error("unreal answer");
        }
    }
}

nthRoot::~nthRoot() {

}

 int* nthRoot::primeFactorization(int n, int div, int k) {
    if (n % div == 0) {
        factors[k] = div;
        if (div == n) {
            factors[k+1] = 0; //the zero works as a stopping point later on
            return factors;
        }
        else {
            primeFactorization((n / div), div, (k + 1));
        }
    }
    else if (div <= n) {
        primeFactorization(n, (div + 1), k);
    }
    return factors;
}

int nthRoot::localExponentiate(int base, int locExponent) {
    if (locExponent >= 1)
        return base * (localExponentiate(base, locExponent - 1));
    else return 1;
}

/*
int nthRoot::localExponentiate(int under, int locExponent) {
    for (int i = 1; i < locExponent; i++) {
        under *= under;
    }
//    cout << under << "\n";
    return under;
}
*/
/*int* nthRoot::primeFactorization(int n, int num, int number) {    //non-recursive version
    int k = 0;
    int* factors;
    while (n%2 == 0) {
        factors[k] = 2;
        k++;
        n = n/2;
    }
    for (int i = 3; i <= sqrt(n); i = i + 2) {
//        if (n%i == 0) {
            while (n%i == 0) {
                factors[k] = i;
                k++;
                n = n/i;
            }
//        }
    }
    if (n > 2) {
        factors[k] = n;
    }
    n = 3;
    return factors;
    // added bonus: factors should be sorted already
} */

Expression* nthRoot::simplify(){
    //if coefficient == 0 then return 0?
    //if operand < 0 throw an error
    if ((root % 2) == 0 && operand < 0) {
        throw runtime_error("unreal answer");
    }
//    int *factorsCopy = this->primeFactorization(operand, 2, 0);
      this->primeFactorization(operand, 2, 0);
//    copy(this->primeFactorization(operand, 2, 0)+50, factors);
    int i = 0;
    int factorsSize = sizeof(factors)/sizeof(factors[0]);

    while (i <= factorsSize && factors[i] != 0) {   //all this takes unnecessary factors out of the operand
        int j = i;               //and puts them into the coefficient
        int count = 1;
        while (j <= factorsSize && factors[j + 1] == factors[j] && factors[j] != 0) {
            count++;
            j++;
        }
        if (count >= root) {

            coefficient = coefficient * localExponentiate(factors[i], (count/root));
            operand = (operand / localExponentiate(factors[i], (count - (count % root))));
        }
        i = j + 1;
    }
    if (operand == 1) {
        Integer* newInt = new Integer(coefficient);
        return newInt;
    }
    else {
        Expression* newRoot = new nthRoot(root, operand, coefficient);
        delete this;  //is this necessary?
        return newRoot;
    }

}

Expression* nthRoot::add(Expression* a) {
    nthRoot *b = (nthRoot *)a;
    int asCoefficient = b->getCoefficient();
    int asOperand = b->getOperand();
    int asRoot = b->getRoot();
    if (root == asRoot && operand == asOperand) {
        int newCoefficient = asCoefficient + coefficient;
        nthRoot* newNthRoot = new nthRoot(root, operand, newCoefficient);
        nthRoot* simplifiedVersion = (nthRoot *)newNthRoot->simplify();
        return simplifiedVersion;
    }
    else {
        return this;
    }
}

Expression* nthRoot::subtract(Expression* a) {
    nthRoot *b = (nthRoot *)a;
    int asCoefficient = b->getCoefficient();
    int asOperand = b->getOperand();
    int asRoot = b->getRoot();
    if (root == asRoot && operand == asOperand) {
        int newCoefficient = coefficient - asCoefficient;
        nthRoot* newNthRoot = new nthRoot(root, operand, newCoefficient);
        nthRoot* simplifiedVersion = (nthRoot *)newNthRoot->simplify();
        return simplifiedVersion;
    }
    else {
        return this;
    }
}

Expression* nthRoot::multiply(Expression* a) {
    if (a->type == "integer") {
        Integer *b = (Integer*)a;
        int asValue = b->getValue();
        int newCoefficient = asValue * coefficient;
        nthRoot* newNthRoot = new nthRoot(root, operand, newCoefficient);
        nthRoot* simplifiedVersion = (nthRoot *)newNthRoot->simplify();
        return simplifiedVersion;
    }
    if (a->type == "nthRoot") {
        nthRoot *b = (nthRoot *)a;
        int asCoefficient = b->getCoefficient();
        int asOperand = b->getOperand();
        int asRoot = b->getRoot();
        if (root == asRoot) {
            int newCoefficient = asCoefficient * coefficient;
            int newOperand = operand * asOperand;       //asOperand doesnt exist?
            nthRoot* newNthRoot = new nthRoot(root, newOperand, newCoefficient);
            nthRoot* simplifiedVersion = (nthRoot *)newNthRoot->simplify();
            return simplifiedVersion;
        }
    }
    else {
        return this;
    }
    return this;
}

Expression* nthRoot::divide(Expression* a) {
    nthRoot *b = (nthRoot *)a;
    int asRoot = b->getRoot();
    int asOperand = b->getOperand();
    int asCoefficient = b->getCoefficient();
    if (root == asRoot && fmod( ((double)coefficient / (double)asCoefficient), 1) == 0 && fmod(((double)operand / (double)asOperand), 1) == 0) {
        int newCoefficient = coefficient / asCoefficient;
        int newOperand = operand / asOperand;
        nthRoot* newNthRoot = new nthRoot(root, newOperand, newCoefficient);
        nthRoot* simplifiedVersion = (nthRoot *)newNthRoot->simplify();
        return simplifiedVersion;
    }
   else if (fmod( ((double)coefficient / (double)asCoefficient),1) == 0) {
        int newCoefficient = coefficient / asCoefficient;
        nthRoot* newNthRoot = new nthRoot(root, operand, newCoefficient);
        nthRoot* simplifiedVersion = (nthRoot *)newNthRoot->simplify();
        return simplifiedVersion;
    }
    else {
        return this;
    }
}

int nthRoot::getRoot() {
    return root;
}

int nthRoot::getOperand() {
    return operand;
}

int nthRoot::getCoefficient() {
    return coefficient;
}

void nthRoot::setCoefficient(int n) {
    this->coefficient = n;
}

void nthRoot::setOperand(int n) {
    this->operand = n;
}

void nthRoot::setRoot(int n) {
    this->root = n;
}
ostream& nthRoot::print(std::ostream& output) const {
    if (this->operand == 1) {
        output << this->coefficient;
    }else{
        output << this->coefficient  << "*" << this->root << "rt:" << this->operand;
    }
    return output;
}

string nthRoot::toString() {
    stringstream s;
    if (this->operand == 1) {
        s << this->coefficient;
    }else{
        s << this->coefficient  << "*" << this->root << "rt:" << this->operand;
    }
    return s.str();
}

bool nthRoot::canAdd(Expression* b){     //use "this" as comparison. Solver will call someExpression.canAdd(&someOtherExpression)

    if (this->type == b->type && this->type != "logarithm") {
        if (this->type == "nthRoot") {
        }
        return true;
    }else if((this->type == "integer" && b->type == "rational") || (this->type == "rational" && b->type == "integer")){
        return true;
    }else if(this->type == "multiple" && b->type == "multiple"){
        MultipleExpressions *t = (MultipleExpressions *)this;
        MultipleExpressions *m = (MultipleExpressions *)b;
        if ((t->meType == "as" && m->meType == "as") || (t->meType == "md" && m->meType == "md")) {
            return true;
        }
    }else if(this->type == "multiple" || b->type == "multiple") return true;
    return false;
}
bool nthRoot::canSubtract(Expression* b){
    if (this->type == b->type) {
        return true;
    }else if((this->type == "integer" && b->type == "rational") || (this->type == "rational" && b->type == "integer")){
        return true;
    }else if(this->type == "multiple" && b->type == "multiple"){
        MultipleExpressions *t = (MultipleExpressions *)this;
        MultipleExpressions *m = (MultipleExpressions *)b;
        if ((t->meType == "as" && m->meType == "as") || (t->meType == "md" && m->meType == "md")) {
            return true;
        }
    }else if(this->type == "multiple" || b->type == "multiple") return true;
    return false;
}
bool nthRoot::canMultiply(Expression* b){
    if (this->type == b->type) {
        return true;
    }
    else if(this->type == "integer" && b->type == "rational") return true;
    else if(this->type == "rational" && b->type == "integer") return true;
    else if(this->type == "multiple" && b->type == "multiple"){
        MultipleExpressions *t = (MultipleExpressions *)this;
        MultipleExpressions *m = (MultipleExpressions *)b;
        if ((t->meType == "as" && m->meType == "as") || (t->meType == "md" && m->meType == "md")) {
            return true;
        }
    }else if(this->type == "multiple" || b->type == "multiple") return true;
    return false;

}
bool nthRoot::canDivide(Expression* b){
    if (this->type == b->type) {
        return true;
    }
    else if(this->type == "integer"){
        if( b->type == "rational") return true;
    }
    else if(this->type == "rational" && b->type == "integer") return true;
    else if(this->type == "multiple" && b->type == "multiple"){
        MultipleExpressions *t = (MultipleExpressions *)this;
        MultipleExpressions *m = (MultipleExpressions *)b;
        if ((t->meType == "as" && m->meType == "as") || (t->meType == "md" && m->meType == "md")) {
            return true;
        }
    }else if(this->type == "multiple" || b->type == "multiple") return true;
    return false;
}
<commit_msg>removed "delete this"<commit_after>//
//  nthRoot.cpp
//  Calculator
//
//  Created by Gavin Scheele on 3/27/14.
//  Copyright (c) 2014 Gavin Scheele. All rights reserved.
//

#include "nthRoot.h"
#include "Integer.h"
#include <array>
using namespace std;
nthRoot::nthRoot(int root, int operand, int coefficient) {
    this->type = "nthRoot";
    this->operand = operand;
    this->root = root;
    this->coefficient = coefficient;
    this->simplify();

    if ((root % 2) == 0 && operand < 0) {
        throw runtime_error("unreal answer");
    }
}

nthRoot::nthRoot(int root, Expression* eoperand, int coefficient) {
    this->type = "nthRoot";
    this->eoperand = eoperand;
    this->root = root;
    this->coefficient = coefficient;

    if ((root % 2) == 0 && eoperand->type == "integer") {
        Integer *a = (Integer *)eoperand;
        if (a->getValue() < 0) {
            throw runtime_error("unreal answer");
        }
    }

    if ((root % 2) == 0 && eoperand->type == "Rational"){
        Rational *b = (Rational*)eoperand;
        if ((b->getNumerator() < 0 || b->getDenominator() < 0)
             && !(b->getNumerator() < 0 && b->getDenominator() < 0)) {
             throw runtime_error("unreal answer");
        }
    }
}

nthRoot::~nthRoot() {

}

 int* nthRoot::primeFactorization(int n, int div, int k) {
    if (n % div == 0) {
        factors[k] = div;
        if (div == n) {
            factors[k+1] = 0; //the zero works as a stopping point later on
            return factors;
        }
        else {
            primeFactorization((n / div), div, (k + 1));
        }
    }
    else if (div <= n) {
        primeFactorization(n, (div + 1), k);
    }
    return factors;
}

int nthRoot::localExponentiate(int base, int locExponent) {
    if (locExponent >= 1)
        return base * (localExponentiate(base, locExponent - 1));
    else return 1;
}

/*
int nthRoot::localExponentiate(int under, int locExponent) {
    for (int i = 1; i < locExponent; i++) {
        under *= under;
    }
//    cout << under << "\n";
    return under;
}
*/
/*int* nthRoot::primeFactorization(int n, int num, int number) {    //non-recursive version
    int k = 0;
    int* factors;
    while (n%2 == 0) {
        factors[k] = 2;
        k++;
        n = n/2;
    }
    for (int i = 3; i <= sqrt(n); i = i + 2) {
//        if (n%i == 0) {
            while (n%i == 0) {
                factors[k] = i;
                k++;
                n = n/i;
            }
//        }
    }
    if (n > 2) {
        factors[k] = n;
    }
    n = 3;
    return factors;
    // added bonus: factors should be sorted already
} */

Expression* nthRoot::simplify(){
    //if coefficient == 0 then return 0?
    //if operand < 0 throw an error
    if ((root % 2) == 0 && operand < 0) {
        throw runtime_error("unreal answer");
    }
//    int *factorsCopy = this->primeFactorization(operand, 2, 0);
      this->primeFactorization(operand, 2, 0);
//    copy(this->primeFactorization(operand, 2, 0)+50, factors);
    int i = 0;
    int factorsSize = sizeof(factors)/sizeof(factors[0]);

    while (i <= factorsSize && factors[i] != 0) {   //all this takes unnecessary factors out of the operand
        int j = i;               //and puts them into the coefficient
        int count = 1;
        while (j <= factorsSize && factors[j + 1] == factors[j] && factors[j] != 0) {
            count++;
            j++;
        }
        if (count >= root) {

            coefficient = coefficient * localExponentiate(factors[i], (count/root));
            operand = (operand / localExponentiate(factors[i], (count - (count % root))));
        }
        i = j + 1;
    }
    if (operand == 1) {
        Integer* newInt = new Integer(coefficient);
        return newInt;
    }
    else {
        Expression* newRoot = new nthRoot(root, operand, coefficient);
        return newRoot;
    }

}

Expression* nthRoot::add(Expression* a) {
    nthRoot *b = (nthRoot *)a;
    int asCoefficient = b->getCoefficient();
    int asOperand = b->getOperand();
    int asRoot = b->getRoot();
    if (root == asRoot && operand == asOperand) {
        int newCoefficient = asCoefficient + coefficient;
        nthRoot* newNthRoot = new nthRoot(root, operand, newCoefficient);
        nthRoot* simplifiedVersion = (nthRoot *)newNthRoot->simplify();
        return simplifiedVersion;
    }
    else {
        return this;
    }
}

Expression* nthRoot::subtract(Expression* a) {
    nthRoot *b = (nthRoot *)a;
    int asCoefficient = b->getCoefficient();
    int asOperand = b->getOperand();
    int asRoot = b->getRoot();
    if (root == asRoot && operand == asOperand) {
        int newCoefficient = coefficient - asCoefficient;
        nthRoot* newNthRoot = new nthRoot(root, operand, newCoefficient);
        nthRoot* simplifiedVersion = (nthRoot *)newNthRoot->simplify();
        return simplifiedVersion;
    }
    else {
        return this;
    }
}

Expression* nthRoot::multiply(Expression* a) {
    if (a->type == "integer") {
        Integer *b = (Integer*)a;
        int asValue = b->getValue();
        int newCoefficient = asValue * coefficient;
        nthRoot* newNthRoot = new nthRoot(root, operand, newCoefficient);
        nthRoot* simplifiedVersion = (nthRoot *)newNthRoot->simplify();
        return simplifiedVersion;
    }
    if (a->type == "nthRoot") {
        nthRoot *b = (nthRoot *)a;
        int asCoefficient = b->getCoefficient();
        int asOperand = b->getOperand();
        int asRoot = b->getRoot();
        if (root == asRoot) {
            int newCoefficient = asCoefficient * coefficient;
            int newOperand = operand * asOperand;       //asOperand doesnt exist?
            nthRoot* newNthRoot = new nthRoot(root, newOperand, newCoefficient);
            nthRoot* simplifiedVersion = (nthRoot *)newNthRoot->simplify();
            return simplifiedVersion;
        }
    }
    else {
        return this;
    }
    return this;
}

Expression* nthRoot::divide(Expression* a) {
    nthRoot *b = (nthRoot *)a;
    int asRoot = b->getRoot();
    int asOperand = b->getOperand();
    int asCoefficient = b->getCoefficient();
    if (root == asRoot && fmod( ((double)coefficient / (double)asCoefficient), 1) == 0 && fmod(((double)operand / (double)asOperand), 1) == 0) {
        int newCoefficient = coefficient / asCoefficient;
        int newOperand = operand / asOperand;
        nthRoot* newNthRoot = new nthRoot(root, newOperand, newCoefficient);
        nthRoot* simplifiedVersion = (nthRoot *)newNthRoot->simplify();
        return simplifiedVersion;
    }
   else if (fmod( ((double)coefficient / (double)asCoefficient),1) == 0) {
        int newCoefficient = coefficient / asCoefficient;
        nthRoot* newNthRoot = new nthRoot(root, operand, newCoefficient);
        nthRoot* simplifiedVersion = (nthRoot *)newNthRoot->simplify();
        return simplifiedVersion;
    }
    else {
        return this;
    }
}

int nthRoot::getRoot() {
    return root;
}

int nthRoot::getOperand() {
    return operand;
}

int nthRoot::getCoefficient() {
    return coefficient;
}

void nthRoot::setCoefficient(int n) {
    this->coefficient = n;
}

void nthRoot::setOperand(int n) {
    this->operand = n;
}

void nthRoot::setRoot(int n) {
    this->root = n;
}
ostream& nthRoot::print(std::ostream& output) const {
    if (this->operand == 1) {
        output << this->coefficient;
    }else{
        output << this->coefficient  << "*" << this->root << "rt:" << this->operand;
    }
    return output;
}

string nthRoot::toString() {
    stringstream s;
    if (this->operand == 1) {
        s << this->coefficient;
    }else{
        s << this->coefficient  << "*" << this->root << "rt:" << this->operand;
    }
    return s.str();
}

bool nthRoot::canAdd(Expression* b){     //use "this" as comparison. Solver will call someExpression.canAdd(&someOtherExpression)

    if (this->type == b->type && this->type != "logarithm") {
        if (this->type == "nthRoot") {
        }
        return true;
    }else if((this->type == "integer" && b->type == "rational") || (this->type == "rational" && b->type == "integer")){
        return true;
    }else if(this->type == "multiple" && b->type == "multiple"){
        MultipleExpressions *t = (MultipleExpressions *)this;
        MultipleExpressions *m = (MultipleExpressions *)b;
        if ((t->meType == "as" && m->meType == "as") || (t->meType == "md" && m->meType == "md")) {
            return true;
        }
    }else if(this->type == "multiple" || b->type == "multiple") return true;
    return false;
}
bool nthRoot::canSubtract(Expression* b){
    if (this->type == b->type) {
        return true;
    }else if((this->type == "integer" && b->type == "rational") || (this->type == "rational" && b->type == "integer")){
        return true;
    }else if(this->type == "multiple" && b->type == "multiple"){
        MultipleExpressions *t = (MultipleExpressions *)this;
        MultipleExpressions *m = (MultipleExpressions *)b;
        if ((t->meType == "as" && m->meType == "as") || (t->meType == "md" && m->meType == "md")) {
            return true;
        }
    }else if(this->type == "multiple" || b->type == "multiple") return true;
    return false;
}
bool nthRoot::canMultiply(Expression* b){
    if (this->type == b->type) {
        return true;
    }
    else if(this->type == "integer" && b->type == "rational") return true;
    else if(this->type == "rational" && b->type == "integer") return true;
    else if(this->type == "multiple" && b->type == "multiple"){
        MultipleExpressions *t = (MultipleExpressions *)this;
        MultipleExpressions *m = (MultipleExpressions *)b;
        if ((t->meType == "as" && m->meType == "as") || (t->meType == "md" && m->meType == "md")) {
            return true;
        }
    }else if(this->type == "multiple" || b->type == "multiple") return true;
    return false;

}
bool nthRoot::canDivide(Expression* b){
    if (this->type == b->type) {
        return true;
    }
    else if(this->type == "integer"){
        if( b->type == "rational") return true;
    }
    else if(this->type == "rational" && b->type == "integer") return true;
    else if(this->type == "multiple" && b->type == "multiple"){
        MultipleExpressions *t = (MultipleExpressions *)this;
        MultipleExpressions *m = (MultipleExpressions *)b;
        if ((t->meType == "as" && m->meType == "as") || (t->meType == "md" && m->meType == "md")) {
            return true;
        }
    }else if(this->type == "multiple" || b->type == "multiple") return true;
    return false;
}
<|endoftext|>


<commit_before>/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */

/*
 *  Main authors:
 *     Guido Tack <guido.tack@monash.edu>
 */

/* 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 <iostream>
#include <fstream>

#include <minizinc/model.hh>
#include <minizinc/parser.hh>
#include <minizinc/prettyprinter.hh>
#include <minizinc/typecheck.hh>
#include <minizinc/exception.hh>

#include <minizinc/flatten.hh>
#include <minizinc/optimize.hh>
#include <minizinc/builtins.hh>

using namespace MiniZinc;
using namespace std;

int main(int argc, char** argv) {
  int i=1;
  string filename;
  vector<string> datafiles;
  vector<string> includePaths;
  bool flag_ignoreStdlib = false;
  bool flag_typecheck = true;
  bool flag_eval = true;
  bool flag_output = true;
  bool flag_outputFundecls = false;
  bool flag_verbose = false;
  bool flag_allSolutions = false;
  bool flag_newfzn = false;
  bool flag_free_search = false;
  bool flag_optimize = true;
  int nbThreads = 1;
  if (argc < 2)
    goto error;

  GC::init();

  for (;;) {
    if (string(argv[i])==string("-I")) {
      i++;
      if (i==argc) {
        goto error;
      }
      includePaths.push_back(argv[i]+string("/"));
    } else if (string(argv[i])==string("--ignore-stdlib")) {
      flag_ignoreStdlib = true;
    } else if (string(argv[i])==string("--no-output")) {
      flag_output = false;
    } else if (string(argv[i])==string("--no-fundecl-output")) {
      flag_outputFundecls = false;
    } else if (string(argv[i])==string("--no-typecheck")) {
      flag_typecheck = false; flag_eval=false;
    } else if (string(argv[i])==string("--no-eval")) {
      flag_eval = false;
    } else if (string(argv[i])==string("--verbose")) {
      flag_verbose = true;
    } else if (string(argv[i])==string("--newfzn")) {
      flag_newfzn = true;
    } else if (string(argv[i])==string("--no-optimize")) {
      flag_optimize = false;
    } else if (string(argv[i])==string("-a")) {
      flag_allSolutions = true;
    } else if (string(argv[i])==string("-f")) {
      flag_free_search = true;
    } else if (string(argv[i])==string("-p")) {
      i++;
      nbThreads = atoi(argv[i]);
    } else {
      break;
    }
    i++;
  }

  if (i==argc) {
    goto error;
  }
  filename = argv[i++];

  while (i<argc)
    datafiles.push_back(argv[i++]);

  {
    if (Model* m = parse(filename, datafiles, includePaths, flag_ignoreStdlib,
                         std::cerr)) {
      try {
        if (flag_verbose)
          std::cerr << "parsing " << filename << std::endl;
        if (flag_typecheck) {
          MiniZinc::typecheck(m);
          MiniZinc::registerBuiltins(m);
          Model* flat = flatten(m);
          if (flag_optimize)
            optimize(flat);

          if (flag_output) {
            if (!flag_newfzn)
              oldflatzinc(flat);
            Printer p;
            p.print(flat,std::cout);
          }
        }
      } catch (LocationException& e) {
        std::cerr << e.what() << ": " << e.msg() << std::endl;
        std::cerr << e.loc() << std::endl;
        exit(EXIT_FAILURE);
      } catch (Exception& e) {
        std::cerr << e.what() << ": " << e.msg() << std::endl;
        exit(EXIT_FAILURE);
      }
      delete m;
    }
  }
  return 0;

error:
  std::cerr << "Usage: "<< argv[0]
            << " [<options>] [-I <include path>] <model>.mzn [<data>.dzn ...]" << std::endl
            << std::endl
            << "Options:" << std::endl
            << "\t--ignore-stdlib\tIgnore the standard libraries stdlib.mzn and builtins.mzn" << std::endl
            << "\t--newfzn\tOutput in the new FlatZinc format" << std::endl
            << "\t--verbose\tPrint progress statements" << std::endl
            << "\t--no-typecheck\tDo not typecheck (implies --no-eval)" << std::endl
            << "\t--no-eval\tDo not evaluate" << std::endl
            << "\t--no-optimize\tDo not optimize the FlatZinc (may speed up large instances)" << std::endl
            << "\t--no-output\tDo not print the output" << std::endl;

  exit(EXIT_FAILURE);
}
<commit_msg>Remove unused option vars<commit_after>/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */

/*
 *  Main authors:
 *     Guido Tack <guido.tack@monash.edu>
 */

/* 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 <iostream>
#include <fstream>

#include <minizinc/model.hh>
#include <minizinc/parser.hh>
#include <minizinc/prettyprinter.hh>
#include <minizinc/typecheck.hh>
#include <minizinc/exception.hh>

#include <minizinc/flatten.hh>
#include <minizinc/optimize.hh>
#include <minizinc/builtins.hh>

using namespace MiniZinc;
using namespace std;

int main(int argc, char** argv) {
  int i=1;
  string filename;
  vector<string> datafiles;
  vector<string> includePaths;
  bool flag_ignoreStdlib = false;
  bool flag_typecheck = true;
  bool flag_eval = true;
  bool flag_output = true;
  bool flag_verbose = false;
  bool flag_newfzn = false;
  bool flag_optimize = true;
  if (argc < 2)
    goto error;

  GC::init();

  for (;;) {
    if (string(argv[i])==string("-I")) {
      i++;
      if (i==argc) {
        goto error;
      }
      includePaths.push_back(argv[i]+string("/"));
    } else if (string(argv[i])==string("--ignore-stdlib")) {
      flag_ignoreStdlib = true;
    } else if (string(argv[i])==string("--no-output")) {
      flag_output = false;
    } else if (string(argv[i])==string("--no-typecheck")) {
      flag_typecheck = false; flag_eval=false;
    } else if (string(argv[i])==string("--no-eval")) {
      flag_eval = false;
    } else if (string(argv[i])==string("--verbose")) {
      flag_verbose = true;
    } else if (string(argv[i])==string("--newfzn")) {
      flag_newfzn = true;
    } else if (string(argv[i])==string("--no-optimize")) {
      flag_optimize = false;
    } else {
      break;
    }
    i++;
  }

  if (i==argc) {
    goto error;
  }
  filename = argv[i++];

  while (i<argc)
    datafiles.push_back(argv[i++]);

  {
    if (Model* m = parse(filename, datafiles, includePaths, flag_ignoreStdlib,
                         std::cerr)) {
      try {
        if (flag_verbose)
          std::cerr << "parsing " << filename << std::endl;
        if (flag_typecheck) {
          MiniZinc::typecheck(m);
          MiniZinc::registerBuiltins(m);
          Model* flat = flatten(m);
          if (flag_optimize)
            optimize(flat);

          if (flag_output) {
            if (!flag_newfzn)
              oldflatzinc(flat);
            Printer p;
            p.print(flat,std::cout);
          }
        }
      } catch (LocationException& e) {
        std::cerr << e.what() << ": " << e.msg() << std::endl;
        std::cerr << e.loc() << std::endl;
        exit(EXIT_FAILURE);
      } catch (Exception& e) {
        std::cerr << e.what() << ": " << e.msg() << std::endl;
        exit(EXIT_FAILURE);
      }
      delete m;
    }
  }
  return 0;

error:
  std::cerr << "Usage: "<< argv[0]
            << " [<options>] [-I <include path>] <model>.mzn [<data>.dzn ...]" << std::endl
            << std::endl
            << "Options:" << std::endl
            << "\t--ignore-stdlib\tIgnore the standard libraries stdlib.mzn and builtins.mzn" << std::endl
            << "\t--newfzn\tOutput in the new FlatZinc format" << std::endl
            << "\t--verbose\tPrint progress statements" << std::endl
            << "\t--no-typecheck\tDo not typecheck (implies --no-eval)" << std::endl
            << "\t--no-eval\tDo not evaluate" << std::endl
            << "\t--no-optimize\tDo not optimize the FlatZinc (may speed up large instances)" << std::endl
            << "\t--no-output\tDo not print the output" << std::endl;

  exit(EXIT_FAILURE);
}
<|endoftext|>