<commit_before>#include "product_term_analyzer.h"
#include <la-manager/LAPool.h>
using namespace sf1r;

// #define PM_CLUST_TEXT_DEBUG

ProductTermAnalyzer::ProductTermAnalyzer()
{
    std::string kma_path;
    LAPool::getInstance()->get_kma_path(kma_path );
    std::string cma_path;
    LAPool::getInstance()->get_cma_path(cma_path );
    std::string jma_path;
    LAPool::getInstance()->get_jma_path(jma_path );
//     idmlib::util::IDMAnalyzerConfig aconfig = idmlib::util::IDMAnalyzerConfig::GetCommonConfig(kma_path,cma_path,jma_path);
    //use cma only
    idmlib::util::IDMAnalyzerConfig aconfig = idmlib::util::IDMAnalyzerConfig::GetCommonConfig("",cma_path,"");
    aconfig.symbol = true;
    aconfig.cma_config.merge_alpha_digit = true;
    analyzer_ = new idmlib::util::IDMAnalyzer(aconfig);

    //make stop words manually here
    stop_set_.insert("的");
    stop_set_.insert("在");
    stop_set_.insert("是");
    stop_set_.insert("和");
}

ProductTermAnalyzer::~ProductTermAnalyzer()
{
    delete analyzer_;
}

void ProductTermAnalyzer::Analyze(const izenelib::util::UString& title, std::vector<std::string>& terms, std::vector<double>& weights)
{
    std::vector<idmlib::util::IDMTerm> term_list;
    analyzer_->GetTermList(title, term_list);

    terms.reserve(term_list.size());
    weights.reserve(term_list.size());

#ifdef PM_CLUST_TEXT_DEBUG
    std::string stitle;
    title.convertString(stitle, izenelib::util::UString::UTF_8);
    std::cout<<"[Title] "<<stitle<<std::endl<<"[OTokens] ";
    for (uint32_t i=0;i<term_list.size();i++)
    {
        std::cout<<"["<<term_list[i].TextString()<<","<<term_list[i].tag<<"],";
    }
    std::cout<<std::endl;
#endif
    if(term_list.empty()) return;
//     TERM_STATUS status = NORMAL;

    boost::unordered_set<std::string> app;

    for (uint32_t i=0;i<term_list.size();i++)
    {
        const std::string& str = term_list[i].TextString();
        if( stop_set_.find(str)!=stop_set_.end()) continue;
        if( app.find(str)!=app.end()) continue;
        app.insert(str);
        char tag = term_list[i].tag;
        double weight = GetWeight_(term_list.size(), term_list[i].text, tag);
        if( weight<=0.0 ) continue;
        terms.push_back(str);
        weights.push_back(weight);
    }

#ifdef PM_CLUST_TEXT_DEBUG
    std::cout<<"[ATokens] ";
    for (uint32_t i=0;i<terms.size();i++)
    {
        std::cout<<"["<<terms[i]<<","<<weights[i]<<"],";
    }
    std::cout<<std::endl;
#endif

}

double ProductTermAnalyzer::GetWeight_(uint32_t title_length, const izenelib::util::UString& term, char tag)
{
    if(tag=='.') return 0.0;
    double weight = 1.0;
    uint32_t term_length = term.length();
    bool is_model = false;
    if(tag=='X')
    {
        is_model = true;
    }
    else
    {
        if(tag=='M' && term_length>=4)
        {
            is_model = true;
        }
    }

    if(is_model)
    {
        double length_factor = std::log( (double)title_length*3);
        weight = 0.5*length_factor;
        if( weight<1.0) weight = 1.0;
//         else if(weight>2.0) weight = 2.0;
    }

    else if(tag=='F')
    {
        if(term.length()<2)
        {
            weight = 0.0;
        }
        else
        {
            weight = 1;
        }
    }
    else if(tag=='M')
    {
        weight = 0.3*term.length();
    }
    return weight;
}

<commit_msg>do not extract symbols in product analyzer<commit_after>#include "product_term_analyzer.h"
#include <la-manager/LAPool.h>
using namespace sf1r;

// #define PM_CLUST_TEXT_DEBUG

ProductTermAnalyzer::ProductTermAnalyzer()
{
    std::string kma_path;
    LAPool::getInstance()->get_kma_path(kma_path );
    std::string cma_path;
    LAPool::getInstance()->get_cma_path(cma_path );
    std::string jma_path;
    LAPool::getInstance()->get_jma_path(jma_path );
//     idmlib::util::IDMAnalyzerConfig aconfig = idmlib::util::IDMAnalyzerConfig::GetCommonConfig(kma_path,cma_path,jma_path);
    //use cma only
    idmlib::util::IDMAnalyzerConfig aconfig = idmlib::util::IDMAnalyzerConfig::GetCommonConfig("",cma_path,"");
//     aconfig.symbol = true;
    aconfig.cma_config.merge_alpha_digit = true;
    analyzer_ = new idmlib::util::IDMAnalyzer(aconfig);

    //make stop words manually here
    stop_set_.insert("的");
    stop_set_.insert("在");
    stop_set_.insert("是");
    stop_set_.insert("和");
}

ProductTermAnalyzer::~ProductTermAnalyzer()
{
    delete analyzer_;
}

void ProductTermAnalyzer::Analyze(const izenelib::util::UString& title, std::vector<std::string>& terms, std::vector<double>& weights)
{
    std::vector<idmlib::util::IDMTerm> term_list;
    analyzer_->GetTermList(title, term_list);

    terms.reserve(term_list.size());
    weights.reserve(term_list.size());

#ifdef PM_CLUST_TEXT_DEBUG
    std::string stitle;
    title.convertString(stitle, izenelib::util::UString::UTF_8);
    std::cout<<"[Title] "<<stitle<<std::endl<<"[OTokens] ";
    for (uint32_t i=0;i<term_list.size();i++)
    {
        std::cout<<"["<<term_list[i].TextString()<<","<<term_list[i].tag<<"],";
    }
    std::cout<<std::endl;
#endif
    if(term_list.empty()) return;
//     TERM_STATUS status = NORMAL;

    boost::unordered_set<std::string> app;

    for (uint32_t i=0;i<term_list.size();i++)
    {
        const std::string& str = term_list[i].TextString();
        if( stop_set_.find(str)!=stop_set_.end()) continue;
        if( app.find(str)!=app.end()) continue;
        app.insert(str);
        char tag = term_list[i].tag;
        double weight = GetWeight_(term_list.size(), term_list[i].text, tag);
        if( weight<=0.0 ) continue;
        terms.push_back(str);
        weights.push_back(weight);
    }

#ifdef PM_CLUST_TEXT_DEBUG
    std::cout<<"[ATokens] ";
    for (uint32_t i=0;i<terms.size();i++)
    {
        std::cout<<"["<<terms[i]<<","<<weights[i]<<"],";
    }
    std::cout<<std::endl;
#endif

}

double ProductTermAnalyzer::GetWeight_(uint32_t title_length, const izenelib::util::UString& term, char tag)
{
    if(tag=='.') return 0.0;
    double weight = 1.0;
    uint32_t term_length = term.length();
    bool is_model = false;
    if(tag=='X')
    {
        is_model = true;
    }
    else
    {
        if(tag=='M' && term_length>=4)
        {
            is_model = true;
        }
    }

    if(is_model)
    {
        double length_factor = std::log( (double)title_length*3);
        weight = 0.5*length_factor;
        if( weight<1.0) weight = 1.0;
//         else if(weight>2.0) weight = 2.0;
    }

    else if(tag=='F')
    {
        if(term.length()<2)
        {
            weight = 0.0;
        }
        else
        {
            weight = 1;
        }
    }
    else if(tag=='M')
    {
        weight = 0.3*term.length();
    }
    return weight;
}

<|endoftext|>


<commit_before>//
// Aspia Project
// Copyright (C) 2020 Dmitry Chapyshev <dmitry@aspia.ru>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
//

#include "crypto/key_pair.h"

#include "base/logging.h"

#include <openssl/evp.h>

namespace crypto {

KeyPair::KeyPair() = default;

KeyPair::KeyPair(EVP_PKEY_ptr&& pkey) noexcept
    : pkey_(std::move(pkey))
{
    // Nothing
}

KeyPair::KeyPair(KeyPair&& other) noexcept
    : pkey_(std::move(other.pkey_))
{
    // Nothing
}

KeyPair& KeyPair::operator=(KeyPair&& other) noexcept
{
    if (&other != this)
        pkey_ = std::move(other.pkey_);

    return *this;
}

KeyPair::~KeyPair() = default;

// static
KeyPair KeyPair::create(Type type)
{
    DCHECK_EQ(type, Type::X25519);

    EVP_PKEY_CTX_ptr ctx(EVP_PKEY_CTX_new_id(EVP_PKEY_X25519, nullptr));
    if (!ctx)
    {
        LOG(LS_WARNING) << "EVP_PKEY_CTX_new_id failed";
        return KeyPair();
    }

    if (EVP_PKEY_keygen_init(ctx.get()) != 1)
    {
        LOG(LS_WARNING) << "EVP_PKEY_keygen_init failed";
        return KeyPair();
    }

    EVP_PKEY* private_key = nullptr;
    if (EVP_PKEY_keygen(ctx.get(), &private_key) != 1)
    {
        LOG(LS_WARNING) << "EVP_PKEY_keygen failed";
        return KeyPair();
    }

    return KeyPair(EVP_PKEY_ptr(private_key));
}

// static
KeyPair KeyPair::fromPrivateKey(const base::ByteArray& private_key)
{
    return KeyPair(EVP_PKEY_ptr(EVP_PKEY_new_raw_private_key(
        EVP_PKEY_X25519, nullptr, private_key.data(), private_key.size())));
}

bool KeyPair::isValid() const
{
    return pkey_ != nullptr;
}

base::ByteArray KeyPair::privateKey() const
{
    size_t private_key_length = 0;

    if (EVP_PKEY_get_raw_private_key(pkey_.get(), nullptr, &private_key_length) != 1)
    {
        LOG(LS_WARNING) << "EVP_PKEY_get_raw_private_key failed";
        return base::ByteArray();
    }

    if (!private_key_length)
    {
        LOG(LS_WARNING) << "Invalid private key size";
        return base::ByteArray();
    }

    base::ByteArray private_key;
    private_key.resize(private_key_length);

    if (EVP_PKEY_get_raw_private_key(pkey_.get(), private_key.data(), &private_key_length) != 1)
    {
        LOG(LS_WARNING) << "EVP_PKEY_get_raw_private_key failed";
        return base::ByteArray();
    }

    if (private_key.size() != private_key_length)
    {
        LOG(LS_WARNING) << "Invalid private key size";
        return base::ByteArray();
    }

    return private_key;
}

base::ByteArray KeyPair::publicKey() const
{
    size_t public_key_length = 0;

    if (EVP_PKEY_get_raw_public_key(pkey_.get(), nullptr, &public_key_length) != 1)
    {
        LOG(LS_WARNING) << "EVP_PKEY_get_raw_public_key failed";
        return base::ByteArray();
    }

    if (!public_key_length)
    {
        LOG(LS_WARNING) << "Invalid public key size";
        return base::ByteArray();
    }

    base::ByteArray public_key;
    public_key.resize(public_key_length);

    if (EVP_PKEY_get_raw_public_key(pkey_.get(), public_key.data(), &public_key_length) != 1)
    {
        LOG(LS_WARNING) << "EVP_PKEY_get_raw_public_key failed";
        return base::ByteArray();
    }

    if (public_key.size() != public_key_length)
    {
        LOG(LS_WARNING) << "Invalid public key size";
        return base::ByteArray();
    }

    return public_key;
}

base::ByteArray KeyPair::sessionKey(const base::ByteArray& peer_public_key) const
{
    EVP_PKEY_ptr public_key(EVP_PKEY_new_raw_public_key(
        EVP_PKEY_X25519, nullptr, peer_public_key.data(), peer_public_key.size()));
    if (!public_key)
    {
        LOG(LS_WARNING) << "EVP_PKEY_new_raw_public_key failed";
        return base::ByteArray();
    }

    EVP_PKEY_CTX_ptr ctx(EVP_PKEY_CTX_new(pkey_.get(), nullptr));
    if (!ctx)
    {
        LOG(LS_WARNING) << "EVP_PKEY_CTX_new failed";
        return base::ByteArray();
    }

    if (EVP_PKEY_derive_init(ctx.get()) != 1)
    {
        LOG(LS_WARNING) << "EVP_PKEY_derive_init failed";
        return base::ByteArray();
    }

    if (EVP_PKEY_derive_set_peer(ctx.get(), public_key.get()) != 1)
    {
        LOG(LS_WARNING) << "EVP_PKEY_derive_set_pee failed";
        return base::ByteArray();
    }

    size_t session_key_length = 0;

    if (EVP_PKEY_derive(ctx.get(), nullptr, &session_key_length) != 1)
    {
        LOG(LS_WARNING) << "EVP_PKEY_derive failed";
        return base::ByteArray();
    }

    if (!session_key_length)
    {
        LOG(LS_WARNING) << "Invalid session key size";
        return base::ByteArray();
    }

    base::ByteArray session_key;
    session_key.resize(session_key_length);

    if (EVP_PKEY_derive(ctx.get(), session_key.data(), &session_key_length) != 1)
    {
        LOG(LS_WARNING) << "EVP_PKEY_derive failed";
        return base::ByteArray();
    }

    if (session_key.size() != session_key_length)
    {
        LOG(LS_WARNING) << "Invalid session key size";
        return base::ByteArray();
    }

    return session_key;
}

} // namespace crypto
<commit_msg>Added checks.<commit_after>//
// Aspia Project
// Copyright (C) 2020 Dmitry Chapyshev <dmitry@aspia.ru>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
//

#include "crypto/key_pair.h"

#include "base/logging.h"

#include <openssl/evp.h>

namespace crypto {

KeyPair::KeyPair() = default;

KeyPair::KeyPair(EVP_PKEY_ptr&& pkey) noexcept
    : pkey_(std::move(pkey))
{
    // Nothing
}

KeyPair::KeyPair(KeyPair&& other) noexcept
    : pkey_(std::move(other.pkey_))
{
    // Nothing
}

KeyPair& KeyPair::operator=(KeyPair&& other) noexcept
{
    if (&other != this)
        pkey_ = std::move(other.pkey_);

    return *this;
}

KeyPair::~KeyPair() = default;

// static
KeyPair KeyPair::create(Type type)
{
    DCHECK_EQ(type, Type::X25519);

    EVP_PKEY_CTX_ptr ctx(EVP_PKEY_CTX_new_id(EVP_PKEY_X25519, nullptr));
    if (!ctx)
    {
        LOG(LS_WARNING) << "EVP_PKEY_CTX_new_id failed";
        return KeyPair();
    }

    if (EVP_PKEY_keygen_init(ctx.get()) != 1)
    {
        LOG(LS_WARNING) << "EVP_PKEY_keygen_init failed";
        return KeyPair();
    }

    EVP_PKEY* private_key = nullptr;
    if (EVP_PKEY_keygen(ctx.get(), &private_key) != 1)
    {
        LOG(LS_WARNING) << "EVP_PKEY_keygen failed";
        return KeyPair();
    }

    return KeyPair(EVP_PKEY_ptr(private_key));
}

// static
KeyPair KeyPair::fromPrivateKey(const base::ByteArray& private_key)
{
    if (private_key.empty())
        return KeyPair();

    return KeyPair(EVP_PKEY_ptr(EVP_PKEY_new_raw_private_key(
        EVP_PKEY_X25519, nullptr, private_key.data(), private_key.size())));
}

bool KeyPair::isValid() const
{
    return pkey_ != nullptr;
}

base::ByteArray KeyPair::privateKey() const
{
    size_t private_key_length = 0;

    if (EVP_PKEY_get_raw_private_key(pkey_.get(), nullptr, &private_key_length) != 1)
    {
        LOG(LS_WARNING) << "EVP_PKEY_get_raw_private_key failed";
        return base::ByteArray();
    }

    if (!private_key_length)
    {
        LOG(LS_WARNING) << "Invalid private key size";
        return base::ByteArray();
    }

    base::ByteArray private_key;
    private_key.resize(private_key_length);

    if (EVP_PKEY_get_raw_private_key(pkey_.get(), private_key.data(), &private_key_length) != 1)
    {
        LOG(LS_WARNING) << "EVP_PKEY_get_raw_private_key failed";
        return base::ByteArray();
    }

    if (private_key.size() != private_key_length)
    {
        LOG(LS_WARNING) << "Invalid private key size";
        return base::ByteArray();
    }

    return private_key;
}

base::ByteArray KeyPair::publicKey() const
{
    size_t public_key_length = 0;

    if (EVP_PKEY_get_raw_public_key(pkey_.get(), nullptr, &public_key_length) != 1)
    {
        LOG(LS_WARNING) << "EVP_PKEY_get_raw_public_key failed";
        return base::ByteArray();
    }

    if (!public_key_length)
    {
        LOG(LS_WARNING) << "Invalid public key size";
        return base::ByteArray();
    }

    base::ByteArray public_key;
    public_key.resize(public_key_length);

    if (EVP_PKEY_get_raw_public_key(pkey_.get(), public_key.data(), &public_key_length) != 1)
    {
        LOG(LS_WARNING) << "EVP_PKEY_get_raw_public_key failed";
        return base::ByteArray();
    }

    if (public_key.size() != public_key_length)
    {
        LOG(LS_WARNING) << "Invalid public key size";
        return base::ByteArray();
    }

    return public_key;
}

base::ByteArray KeyPair::sessionKey(const base::ByteArray& peer_public_key) const
{
    if (peer_public_key.empty())
        return base::ByteArray();

    EVP_PKEY_ptr public_key(EVP_PKEY_new_raw_public_key(
        EVP_PKEY_X25519, nullptr, peer_public_key.data(), peer_public_key.size()));
    if (!public_key)
    {
        LOG(LS_WARNING) << "EVP_PKEY_new_raw_public_key failed";
        return base::ByteArray();
    }

    EVP_PKEY_CTX_ptr ctx(EVP_PKEY_CTX_new(pkey_.get(), nullptr));
    if (!ctx)
    {
        LOG(LS_WARNING) << "EVP_PKEY_CTX_new failed";
        return base::ByteArray();
    }

    if (EVP_PKEY_derive_init(ctx.get()) != 1)
    {
        LOG(LS_WARNING) << "EVP_PKEY_derive_init failed";
        return base::ByteArray();
    }

    if (EVP_PKEY_derive_set_peer(ctx.get(), public_key.get()) != 1)
    {
        LOG(LS_WARNING) << "EVP_PKEY_derive_set_pee failed";
        return base::ByteArray();
    }

    size_t session_key_length = 0;

    if (EVP_PKEY_derive(ctx.get(), nullptr, &session_key_length) != 1)
    {
        LOG(LS_WARNING) << "EVP_PKEY_derive failed";
        return base::ByteArray();
    }

    if (!session_key_length)
    {
        LOG(LS_WARNING) << "Invalid session key size";
        return base::ByteArray();
    }

    base::ByteArray session_key;
    session_key.resize(session_key_length);

    if (EVP_PKEY_derive(ctx.get(), session_key.data(), &session_key_length) != 1)
    {
        LOG(LS_WARNING) << "EVP_PKEY_derive failed";
        return base::ByteArray();
    }

    if (session_key.size() != session_key_length)
    {
        LOG(LS_WARNING) << "Invalid session key size";
        return base::ByteArray();
    }

    return session_key;
}

} // namespace crypto
<|endoftext|>


<commit_before>#include <iostream>
#include <fstream>
#include <functional>
#include <typeinfo>
#include <time.h>
#include <cstdio>
#include <vector>
#include <time.h>

#define SEQAN_DEBUG
#define SEQAN_TEST

#include <seqan/file.h>
#include <seqan/modifier.h>

using namespace std;
using namespace seqan;

//////////////////////////////////////////////////////////////////////////////

	// custom functor (Caesar chiffre)
    template <typename InType, typename Result = InType>
    struct CaesarChiffre : public unary_function<InType,Result>
	{
		InType delta;

		CaesarChiffre() {}
		CaesarChiffre(InType _delta) {
			if (_delta < 0)
				delta = ('z' - 'a' + 1) - (-_delta) % ('z' - 'a' + 1);
			else
				delta = _delta;
		}

        inline Result operator()(InType x) const {
			if (('a' <= x) && (x <= 'z')) return (x - 'a' + delta) % ('z' - 'a' + 1) + 'a';
			if (('A' <= x) && (x <= 'Z')) return (x - 'A' + delta) % ('Z' - 'A' + 1) + 'A';
			return x;
		}
    };

void testViewIterator()
{
		String<char> origin = "Vjku ku qwt qtkikpcn uvtkpi";

	//____________________________________________________________________________
	// Test1 - no modification (default)
	{

		typedef ModifiedIterator< Iterator<String<char> >::Type > TModIterDefault;

		TModIterDefault it, itEnd(end(origin));

		cout << "*** Iterator Test: Caesar chiffre ***" << endl;
		cout << "chiffre:  ";

		it = begin(origin);
		while (it != itEnd) {
			cout << *it;
			++it;
		}
		cout << endl;

	}
	//____________________________________________________________________________
	// Test2 - Caesar chiffre
	{

		typedef CaesarChiffre<char> TEncode;
		typedef ModifiedIterator< Iterator<String<char> >::Type, ModView<TEncode> > TModIterCaesar;

		TEncode encode(-2);
		TModIterCaesar it(encode), itEnd(end(origin));

		cout << "original: ";

		it = begin(origin);
		while (it != itEnd) {
			cout << *it;
			it = it + 1;
		}
		cout << endl << endl;

	}
}

void testViewString()
{
		String<char> origin = "This is our original string";

	//____________________________________________________________________________
	// Test1 - no modification (default)

		typedef ModifiedString< String<char> > TModStringDefault;

		TModStringDefault nomod(origin);

		cout << "*** Test1/2: Caesar chiffre ***" << endl;
		cout << "origin:  " << nomod << endl;

	//____________________________________________________________________________
	// Test2 - Caesar chiffre

		typedef CaesarChiffre<char> TEncode;
		typedef ModifiedString< String<char>, ModView<TEncode> > TModStringCaesar;

		TEncode encode(2);
		TModStringCaesar chiffre(origin);
		assignModViewFunctor(chiffre, encode);

		cout << "chiffre: " << chiffre << endl << endl;

	//____________________________________________________________________________
	// Test3 - upcase/downcase

		typedef ModifiedString< String<char>, ModView< FunctorUpcase<char> > > TModStringUp;
		typedef ModifiedString< String<char>, ModView< FunctorDowncase<char> > > TModStringDown;

		TModStringUp	up(origin);
		TModStringDown	down(origin);

		cout << "*** Test3: upcase/downcase ***" << endl;
		cout << "upcase:   " << up << endl;
		cout << "downcase: " << down << endl << endl;

	//____________________________________________________________________________
	// Test4 - alphabet conversion

		String<char> originDNA = "acgtnACGTN";
		typedef ModifiedString< String<char>, ModView< FunctorConvert<char, Dna5> > > TModStringDNA;

		TModStringDNA	dna(originDNA);

		cout << "*** Test4: alphabet conversion ***" << endl;
		cout << "origin: " << originDNA << endl;
		cout << "Dna5:   " << dna << endl << endl;

	//____________________________________________________________________________
	// Test5 - nested modifiers

		typedef CaesarChiffre<char> TEncode;
		typedef ModifiedString<
					ModifiedString<
						ModifiedString<
							String<char>,
							ModView<TEncode>
						>,
						ModView<TEncode>
					>,
					ModView<TEncode>
				> TModStringNested;

		TModStringNested nested(origin);

		TEncode enc2(2), enc3(3), enc_5(-5);

		assignModViewFunctor(nested, enc2);
		assignModViewFunctor(host(nested), enc3);
		assignModViewFunctor(host(host(nested)), enc_5);

		cout << "*** Test5: nested modifiers ***" << endl;
		cout << "nested: " << nested << endl << endl;

}

void testReverseString()
{
		String<char> origin = "A man, a plan, a canal-Panama";

	//____________________________________________________________________________
	// Test1 - reverse string

		typedef ModifiedString< String<char>, ModReverse> TModString;

		TModString reverse(origin);

		cout << "*** Test1: Reverse String ***" << endl;
		cout << "origin:  " << origin << endl;
		cout << "reverse: " << reverse << endl << endl;

	//____________________________________________________________________________
	// Test2 - complement string

		DnaString dna = "attacgg";

		cout << "*** Test2: DNA symmetry ***" << endl;
		cout << "origin:             " << dna << endl;
		cout << "reverse:            " << DnaStringReverse(dna) << endl;
		cout << "complement:         " << DnaStringComplement(dna) << endl;
		cout << "reverse complement: " << DnaStringReverseComplement(dna) << endl << endl;

	//____________________________________________________________________________
	// Test3 - in-place conversions

		DnaString dna2 = dna;
		cout << "*** Test3: in-place conversions ***" << endl;
		cout << "origin:             " << dna2 << endl;

		reverseInPlace(dna2);
		cout << "reverse:            " << dna2 << endl;

		dna2 = dna;
		complementInPlace(dna2);
		cout << "complement:         " << dna2 << endl;

		dna2 = dna;
		reverseComplementInPlace(dna2);
		cout << "reverse complement: " << dna2 << endl << endl;

}

int main()
{
	SEQAN_TREPORT("TEST BEGIN")

		testViewString();
		testViewIterator();
		testReverseString();

	SEQAN_TREPORT("TEST END")
		return 0;
}
<commit_msg><commit_after>#include <iostream>
#include <fstream>
#include <functional>
#include <typeinfo>
#include <time.h>
#include <cstdio>
#include <vector>
#include <time.h>

#define SEQAN_DEBUG
#define SEQAN_TEST

#include <seqan/file.h>
#include <seqan/modifier.h>

using namespace std;
using namespace seqan;

//////////////////////////////////////////////////////////////////////////////

	// custom functor (Caesar chiffre)
    template <typename InType, typename Result = InType>
    struct CaesarChiffre : public unary_function<InType,Result>
	{
		InType delta;

		CaesarChiffre():delta(1) {}
		CaesarChiffre(InType _delta) {
			if (_delta < 0)
				delta = ('z' - 'a' + 1) - (-_delta) % ('z' - 'a' + 1);
			else
				delta = _delta;
		}

        inline Result operator()(InType x) const {
			if (('a' <= x) && (x <= 'z')) return (x - 'a' + delta) % ('z' - 'a' + 1) + 'a';
			if (('A' <= x) && (x <= 'Z')) return (x - 'A' + delta) % ('Z' - 'A' + 1) + 'A';
			return x;
		}
    };

void testViewIterator()
{
		String<char> origin = "Vjku ku qwt qtkikpcn uvtkpi";

	//____________________________________________________________________________
	// Test1 - no modification (default)
	{

		typedef ModifiedIterator< Iterator<String<char> >::Type > TModIterDefault;

		TModIterDefault it, itEnd(end(origin));

		cout << "*** Iterator Test: Caesar chiffre ***" << endl;
		cout << "chiffre:  ";

		it = begin(origin);
		while (it != itEnd) {
			cout << *it;
			++it;
		}
		cout << endl;

	}
	//____________________________________________________________________________
	// Test2 - Caesar chiffre
	{

		typedef CaesarChiffre<char> TEncode;
		typedef ModifiedIterator< Iterator<String<char> >::Type, ModView<TEncode> > TModIterCaesar;

		TEncode encode(-2);
		TModIterCaesar it(encode), itEnd(end(origin));

		cout << "original: ";

		it = begin(origin);
		while (it != itEnd) {
			cout << *it;
			it = it + 1;
		}
		cout << endl << endl;

	}
}

void testViewString()
{
		String<char> origin = "This is our original string";

	//____________________________________________________________________________
	// Test1 - no modification (default)

		typedef ModifiedString< String<char> > TModStringDefault;

		TModStringDefault nomod(origin);

		cout << "*** Test1/2: Caesar chiffre ***" << endl;
		cout << "origin:  " << nomod << endl;

	//____________________________________________________________________________
	// Test2 - Caesar chiffre

		typedef CaesarChiffre<char> TEncode;
		typedef ModifiedString< String<char>, ModView<TEncode> > TModStringCaesar;

		TEncode encode(2);
		TModStringCaesar chiffre(origin);
		assignModViewFunctor(chiffre, encode);

		cout << "chiffre: " << chiffre << endl << endl;

	//____________________________________________________________________________
	// Test3 - upcase/lowcase

		typedef ModifiedString< String<char>, ModView< FunctorUpcase<char> > > TModStringUp;
		typedef ModifiedString< String<char>, ModView< FunctorLowcase<char> > > TModStringLow;

		TModStringUp	up(origin);
		TModStringLow	low(origin);

		cout << "*** Test3: upcase/lowcase ***" << endl;
		cout << "upcase:   " << up << endl;
		cout << "lowcase: " << low << endl << endl;

	//____________________________________________________________________________
	// Test4 - alphabet conversion

		String<char> originDNA = "acgtnACGTN";
		typedef ModifiedString< String<char>, ModView< FunctorConvert<char, Dna5> > > TModStringDNA;

		TModStringDNA	dna(originDNA);

		cout << "*** Test4: alphabet conversion ***" << endl;
		cout << "origin: " << originDNA << endl;
		cout << "Dna5:   " << dna << endl << endl;

	//____________________________________________________________________________
	// Test5 - nested modifiers

		typedef CaesarChiffre<char> TEncode;
		typedef ModifiedString<
		//			ModifiedString<
						ModifiedString<
							String<char>,
							ModView<TEncode>
						>,
						ModView<TEncode>
		//			>,
		//			ModView<TEncode>
				> TModStringNested;

		TModStringNested nested(origin);

		TEncode enc2(2), enc3(-2), enc_5(-5);

		assignModViewFunctor(nested, enc2);
		assignModViewFunctor(host(nested), enc3);
//		assignModViewFunctor(host(host(nested)), enc_5);

		cout << (int) (begin(nested)).data_cargo.func.delta << "  ";
		cout << (int) host((begin(nested))).data_cargo.func.delta << "  ";
//		cout << (int) host(host(nested)).data_cargo.func.delta << "  ";

		cout << "*** Test5: nested modifiers ***" << endl;
		cout << "nested: " << nested << endl << endl;

}

void testReverseString()
{
		String<char> origin = "A man, a plan, a canal-Panama";

	//____________________________________________________________________________
	// Test1 - reverse string

		typedef ModifiedString< String<char>, ModReverse> TModString;

		TModString reverse(origin);

		cout << "*** Test1: Reverse String ***" << endl;
		cout << "origin:  " << origin << endl;
		cout << "reverse: " << reverse << endl << endl;

	//____________________________________________________________________________
	// Test2 - complement string

		DnaString dna = "attacgg";

		cout << "*** Test2: DNA symmetry ***" << endl;
		cout << "origin:             " << dna << endl;
		cout << "reverse:            " << DnaStringReverse(dna) << endl;
		cout << "complement:         " << DnaStringComplement(dna) << endl;
		cout << "reverse complement: " << DnaStringReverseComplement(dna) << endl << endl;

	//____________________________________________________________________________
	// Test3 - in-place conversions

		DnaString dna2 = dna;
		cout << "*** Test3: in-place conversions ***" << endl;
		cout << "origin:             " << dna2 << endl;

		reverseInPlace(dna2);
		cout << "reverse:            " << dna2 << endl;

		dna2 = dna;
		complementInPlace(dna2);
		cout << "complement:         " << dna2 << endl;

		dna2 = dna;
		reverseComplementInPlace(dna2);
		cout << "reverse complement: " << dna2 << endl << endl;

}

int main()
{
	SEQAN_TREPORT("TEST BEGIN")

		testViewString();
		testViewIterator();
		testReverseString();

	SEQAN_TREPORT("TEST END")
		return 0;
}
<|endoftext|>


<commit_before>#include "functions.h"
#include "filenamewindow.h"
#include "ui_filenamewindow.h"
#include "image.h"

FilenameWindow::FilenameWindow(QString value, QWidget *parent) : QDialog(parent), ui(new Ui::FilenameWindow)
{
	ui->setupUi(this);

	#if USE_QSCINTILLA
		m_scintilla = new QsciScintilla(this);
		QsciLexerJavaScript *lexer = new QsciLexerJavaScript(this);
		m_scintilla->setLexer(lexer);
	#else
		m_scintilla = new QTextEdit(this);
	#endif

	connect(ui->radioJavascript, SIGNAL(toggled(bool)), m_scintilla, SLOT(setEnabled(bool)));
	ui->verticalLayout->insertWidget(ui->verticalLayout->count() - 1, m_scintilla);

	if (value.startsWith("javascript:"))
	{
		value = value.right(value.length() - 11);
		m_scintilla->setText(value);
		ui->lineClassic->setEnabled(false);
		ui->radioJavascript->toggle();
	}
	else
	{
		ui->lineClassic->setText(value);
		m_scintilla->setEnabled(false);
		ui->radioClassic->toggle();
	}

	connect(this, &QDialog::accepted, this, &FilenameWindow::send);
}

FilenameWindow::~FilenameWindow()
{
	delete ui;
}

void FilenameWindow::on_lineClassic_textChanged(QString text)
{
	ui->labelValidator->setText(validateFilename(text));

	QRegExp date("%date:([^%]+)%");
	int pos = 0;
	text = text.replace("\\", "\\\\").replace("'", "\\'");

	while ((pos = date.indexIn(text, pos)) != -1)
	{
		QString cap = date.cap(1);
		QString format = "";
		for (int i = 0; i < cap.length(); ++i)
		{
			QChar c = cap.at(i);
			if (c == 'Y')
			{ format += "' + date.getFullYear() + '"; }
			else if (c == 'M')
			{ format += "' + date.getMonth() + '"; }
			else if (c == 'd')
			{ format += "' + date.getDate() + '"; }
			else if (c == 'h')
			{ format += "' + date.getHours() + '"; }
			else if (c == 'm')
			{ format += "' + date.getMinutes() + '"; }
			else if (c == 's')
			{ format += "' + date.getSeconds() + '"; }
			else
			{ format += c; }
		}

		text = text.left(pos) + format + text.mid(pos + date.matchedLength());
		pos += date.matchedLength();
	}

	QString value = "'"+text.replace(QRegExp("%([^%]+)%"), "' + \\1 + '").remove(" + '' + ").trimmed()+"'";
	if (value.startsWith("' + "))
	{ value = value.right(value.length() - 4); }
	if (value.startsWith("'' + "))
	{ value = value.right(value.length() - 5); }
	if (value.endsWith(" + '"))
	{ value = value.left(value.length() - 4); }
	if (value.endsWith(" + ''"))
	{ value = value.left(value.length() - 5); }

	m_scintilla->setText(value);
}

void FilenameWindow::on_buttonHelpClassic_clicked()
{
	QMessageBox::information(this, tr("Aide"), tr(
		"Symboles disponibles : %artist%, %general%, %copyright%, %character%, %all%, %filename%, %ext%, %rating%, %website%, %md5%.

"
		"%artist% : tags de nom d'artiste
"
		"%general% : tags d'image génériques
"
		"%copyright% : tags de copyright, en général le nom de l'anime/manga
"
		"%character% : tags indiquant quels personnages sont présents sur l'image
"
		"%all% : tous les tags
"
		"%filename% : nom du fichier sur le serveur, en général une chaîne alphanumérique
"
		"%ext% : extension de l'image
"
		"%rating% : Questionable, Safe ou Explicit
"
		"%score% : le score de l'image
"
		"%website% : url du site de l'image
"
		"%websitename% : nom du site de l'image
"
		"%md5% : code unique de l'image, composé de 32 caractères alphanumériques
"
		"%id% : identifiant de l'image sur un site donné
"
		"%search% : tags de la recherche
"
		"%search_n% : n-ième tag de la recherche
"
		"%date% : date d'ajout de l'image au format dd-MM-yyyy HH.mm
"
		"%date:format% : date d'ajout de l'image au format donné

"
		"Vous pouvez aussi utiliser les structures conditionnelles. Pour plus d'informations, cliquez ici.")
	);
}

void FilenameWindow::on_buttonHelpJavascript_clicked()
{
	QMessageBox::information(this, tr("Aide"), tr(
		"Variables disponibles : artist, general, copyright, character, all, filename, ext, rating, website, md5.

"
		"artist : tags de nom d'artiste
"
		"general : tags d'image génériques
"
		"copyright : tags de copyright, en général le nom de l'anime/manga
"
		"character : tags indiquant quels personnages sont présents sur l'image
"
		"all : tous les tags
"
		"filename : nom du fichier sur le serveur, en général une chaîne alphanumérique
"
		"ext : extension de l'image
"
		"rating : Questionable, Safe ou Explicit
"
		"score : le score de l'image
"
		"website : url du site de l'image
"
		"websitename : nom du site de l'image
"
		"md5 : code unique de l'image, composé de 32 caractères alphanumériques
"
		"id : identifiant de l'image sur un site donné
"
		"search : tags de la recherche
"
		"search_n : n-ième tag de la recherche
"
		"date : date d'ajout de l'image au format dd-MM-yyyy HH.mm

"
		"Pour plus d'informations sur le nommage Javascript, cliquez ici.")
	);
}

void FilenameWindow::done(int r)
{
	QMap<QString, Site*> *sites = Site::getAllSites();

	if (QDialog::Accepted == r && ui->radioJavascript->isChecked() && !sites->isEmpty())
	{
		QMap<QString, QString> info;
		info.insert("site", QString::number((qintptr)sites->first()));

		#if USE_QSCINTILLA
			QString text = m_scintilla->text();
		#else
			QString text = m_scintilla->toPlainText();
		#endif

		Image image(info);
		QStringList det = image.path("javascript:" + text, "");

		if (det.isEmpty())
		{
			QMessageBox::StandardButton reply = QMessageBox::question(this, tr("Attention"), tr("Votre script contient des erreurs, êtes-vous sûr de vouloir l'enregistrer ?"), QMessageBox::Yes | QMessageBox::Cancel);
			if (reply == QMessageBox::Cancel)
			{
				return;
			}
		}
	}

	QDialog::done(r);
	return;
}

void FilenameWindow::send()
{
	if (ui->radioJavascript->isChecked())
	{
		#if USE_QSCINTILLA
			QString text = m_scintilla->text();
		#else
			QString text = m_scintilla->toPlainText();
		#endif
		emit validated("javascript:"+text);
	}
	else
	{ emit validated(ui->lineClassic->text()); }
}
<commit_msg>Fix usage of 5.5 qmap api on older Qt<commit_after>#include "functions.h"
#include "filenamewindow.h"
#include "ui_filenamewindow.h"
#include "image.h"

FilenameWindow::FilenameWindow(QString value, QWidget *parent) : QDialog(parent), ui(new Ui::FilenameWindow)
{
	ui->setupUi(this);

	#if USE_QSCINTILLA
		m_scintilla = new QsciScintilla(this);
		QsciLexerJavaScript *lexer = new QsciLexerJavaScript(this);
		m_scintilla->setLexer(lexer);
	#else
		m_scintilla = new QTextEdit(this);
	#endif

	connect(ui->radioJavascript, SIGNAL(toggled(bool)), m_scintilla, SLOT(setEnabled(bool)));
	ui->verticalLayout->insertWidget(ui->verticalLayout->count() - 1, m_scintilla);

	if (value.startsWith("javascript:"))
	{
		value = value.right(value.length() - 11);
		m_scintilla->setText(value);
		ui->lineClassic->setEnabled(false);
		ui->radioJavascript->toggle();
	}
	else
	{
		ui->lineClassic->setText(value);
		m_scintilla->setEnabled(false);
		ui->radioClassic->toggle();
	}

	connect(this, &QDialog::accepted, this, &FilenameWindow::send);
}

FilenameWindow::~FilenameWindow()
{
	delete ui;
}

void FilenameWindow::on_lineClassic_textChanged(QString text)
{
	ui->labelValidator->setText(validateFilename(text));

	QRegExp date("%date:([^%]+)%");
	int pos = 0;
	text = text.replace("\\", "\\\\").replace("'", "\\'");

	while ((pos = date.indexIn(text, pos)) != -1)
	{
		QString cap = date.cap(1);
		QString format = "";
		for (int i = 0; i < cap.length(); ++i)
		{
			QChar c = cap.at(i);
			if (c == 'Y')
			{ format += "' + date.getFullYear() + '"; }
			else if (c == 'M')
			{ format += "' + date.getMonth() + '"; }
			else if (c == 'd')
			{ format += "' + date.getDate() + '"; }
			else if (c == 'h')
			{ format += "' + date.getHours() + '"; }
			else if (c == 'm')
			{ format += "' + date.getMinutes() + '"; }
			else if (c == 's')
			{ format += "' + date.getSeconds() + '"; }
			else
			{ format += c; }
		}

		text = text.left(pos) + format + text.mid(pos + date.matchedLength());
		pos += date.matchedLength();
	}

	QString value = "'"+text.replace(QRegExp("%([^%]+)%"), "' + \\1 + '").remove(" + '' + ").trimmed()+"'";
	if (value.startsWith("' + "))
	{ value = value.right(value.length() - 4); }
	if (value.startsWith("'' + "))
	{ value = value.right(value.length() - 5); }
	if (value.endsWith(" + '"))
	{ value = value.left(value.length() - 4); }
	if (value.endsWith(" + ''"))
	{ value = value.left(value.length() - 5); }

	m_scintilla->setText(value);
}

void FilenameWindow::on_buttonHelpClassic_clicked()
{
	QMessageBox::information(this, tr("Aide"), tr(
		"Symboles disponibles : %artist%, %general%, %copyright%, %character%, %all%, %filename%, %ext%, %rating%, %website%, %md5%.

"
		"%artist% : tags de nom d'artiste
"
		"%general% : tags d'image génériques
"
		"%copyright% : tags de copyright, en général le nom de l'anime/manga
"
		"%character% : tags indiquant quels personnages sont présents sur l'image
"
		"%all% : tous les tags
"
		"%filename% : nom du fichier sur le serveur, en général une chaîne alphanumérique
"
		"%ext% : extension de l'image
"
		"%rating% : Questionable, Safe ou Explicit
"
		"%score% : le score de l'image
"
		"%website% : url du site de l'image
"
		"%websitename% : nom du site de l'image
"
		"%md5% : code unique de l'image, composé de 32 caractères alphanumériques
"
		"%id% : identifiant de l'image sur un site donné
"
		"%search% : tags de la recherche
"
		"%search_n% : n-ième tag de la recherche
"
		"%date% : date d'ajout de l'image au format dd-MM-yyyy HH.mm
"
		"%date:format% : date d'ajout de l'image au format donné

"
		"Vous pouvez aussi utiliser les structures conditionnelles. Pour plus d'informations, cliquez ici.")
	);
}

void FilenameWindow::on_buttonHelpJavascript_clicked()
{
	QMessageBox::information(this, tr("Aide"), tr(
		"Variables disponibles : artist, general, copyright, character, all, filename, ext, rating, website, md5.

"
		"artist : tags de nom d'artiste
"
		"general : tags d'image génériques
"
		"copyright : tags de copyright, en général le nom de l'anime/manga
"
		"character : tags indiquant quels personnages sont présents sur l'image
"
		"all : tous les tags
"
		"filename : nom du fichier sur le serveur, en général une chaîne alphanumérique
"
		"ext : extension de l'image
"
		"rating : Questionable, Safe ou Explicit
"
		"score : le score de l'image
"
		"website : url du site de l'image
"
		"websitename : nom du site de l'image
"
		"md5 : code unique de l'image, composé de 32 caractères alphanumériques
"
		"id : identifiant de l'image sur un site donné
"
		"search : tags de la recherche
"
		"search_n : n-ième tag de la recherche
"
		"date : date d'ajout de l'image au format dd-MM-yyyy HH.mm

"
		"Pour plus d'informations sur le nommage Javascript, cliquez ici.")
	);
}

void FilenameWindow::done(int r)
{
	QMap<QString, Site*> *sites = Site::getAllSites();

	if (QDialog::Accepted == r && ui->radioJavascript->isChecked() && !sites->isEmpty())
	{
		QMap<QString, QString> info;
		info.insert("site", QString::number((qintptr)sites->value(sites->keys().first())));

		#if USE_QSCINTILLA
			QString text = m_scintilla->text();
		#else
			QString text = m_scintilla->toPlainText();
		#endif

		Image image(info);
		QStringList det = image.path("javascript:" + text, "");

		if (det.isEmpty())
		{
			QMessageBox::StandardButton reply = QMessageBox::question(this, tr("Attention"), tr("Votre script contient des erreurs, êtes-vous sûr de vouloir l'enregistrer ?"), QMessageBox::Yes | QMessageBox::Cancel);
			if (reply == QMessageBox::Cancel)
			{
				return;
			}
		}
	}

	QDialog::done(r);
	return;
}

void FilenameWindow::send()
{
	if (ui->radioJavascript->isChecked())
	{
		#if USE_QSCINTILLA
			QString text = m_scintilla->text();
		#else
			QString text = m_scintilla->toPlainText();
		#endif
		emit validated("javascript:"+text);
	}
	else
	{ emit validated(ui->lineClassic->text()); }
}
<|endoftext|>


<commit_before>/**********************************************************************
 * $Id$
 *
 * GEOS - Geometry Engine Open Source
 * http://geos.refractions.net
 *
 * Copyright (C) 2001-2002 Vivid Solutions Inc.
 *
 * This is free software; you can redistribute and/or modify it under
 * the terms of the GNU Lesser General Public Licence as published
 * by the Free Software Foundation.
 * See the COPYING file for more information.
 *
 **********************************************************************/

#include <geos/geomgraph.h>
//#include "../headers/util.h"

#ifndef DEBUG
#define DEBUG 0
#endif
#ifndef COMPUTE_Z
#define COMPUTE_Z 0
#endif

namespace geos {

Node::Node(Coordinate& newCoord, EdgeEndStar* newEdges): GraphComponent(new Label(0,Location::UNDEF)) {
	coord=newCoord;
#if DEBUG
	cerr<<"Node::Node("<<newCoord.toString()<<")"<<endl;
#endif
#if COMPUTE_Z
	z=0;
	validz=0;
#endif
	edges=newEdges;
}

Node::~Node(){
	delete edges;
}

const Coordinate& Node::getCoordinate() const {
	return coord;
}

EdgeEndStar* Node::getEdges() {
	return edges;
}

bool Node::isIsolated() {
	return (label->getGeometryCount()==1);
}

void Node::add(EdgeEnd *e) {
#if DEBUG
	cerr<<"Node::add("<<e->print()<<")"<<endl;
#endif
	// Assert: start pt of e is equal to node point
	if (edges==NULL)
		edges=new EdgeEndStar();
	edges->insert(e);
	e->setNode(this);
#if COMPUTE_Z
	Coordinate &ec = e->getCoordinate();
	if ( ec.z != DoubleNotANumber )
	{
		z+=ec.z;
		validz++;
	}
	coord.z=z/validz;
#if DEBUG
	cerr<<" z=="<<z<<endl;
	cerr<<" validz=="<<validz<<endl;
	cerr<<" coord.z=="<<coord.z<<endl;
#endif // DEBUG
#endif
}

void Node::mergeLabel(const Node* n) {
	mergeLabel(n->label);
}

void Node::mergeLabel(const Label* label2) {
	for (int i=0; i<2; i++) {
		int loc=computeMergedLocation(label2, i);
		int thisLoc=label->getLocation(i);
		if (thisLoc==Location::UNDEF) label->setLocation(i,loc);
	}
}

void Node::setLabel(int argIndex, int onLocation) {
	if (label==NULL) {
		label=new Label(argIndex, onLocation);
	} else
		label->setLocation(argIndex, onLocation);
}

void Node::setLabelBoundary(int argIndex) {
	int loc=Location::UNDEF;
	if (label!=NULL)
		loc=label->getLocation(argIndex);
	// flip the loc
	int newLoc;
	switch (loc){
		case Location::BOUNDARY: newLoc=Location::INTERIOR; break;
		case Location::INTERIOR: newLoc=Location::BOUNDARY; break;
		default: newLoc=Location::BOUNDARY;  break;
	}
	label->setLocation(argIndex, newLoc);
}

int Node::computeMergedLocation(const Label* label2, int eltIndex){
	int loc=Location::UNDEF;
	loc=label->getLocation(eltIndex);
	if (!label2->isNull(eltIndex)) {
		int nLoc=label2->getLocation(eltIndex);
		if (loc!=Location::BOUNDARY) loc=nLoc;
	}
	return loc;
}

string Node::print(){
	string out="node "+coord.toString()+" lbl: "+label->toString();
	return out;
}

}

/**********************************************************************
 * $Log$
 * Revision 1.5  2004/11/17 15:09:08  strk
 * Changed COMPUTE_Z defaults to be more conservative
 *
 * Revision 1.4  2004/11/17 08:13:16  strk
 * Indentation changes.
 * Some Z_COMPUTATION activated by default.
 *
 * Revision 1.3  2004/10/21 22:29:54  strk
 * Indentation changes and some more COMPUTE_Z rules
 *
 * Revision 1.2  2004/07/02 13:28:26  strk
 * Fixed all #include lines to reflect headers layout change.
 * Added client application build tips in README.
 *
 * Revision 1.1  2004/03/19 09:48:45  ybychkov
 * "geomgraph" and "geomgraph/indexl" upgraded to JTS 1.4
 *
 * Revision 1.12  2003/11/07 01:23:42  pramsey
 * Add standard CVS headers licence notices and copyrights to all cpp and h
 * files.
 *
 *
 **********************************************************************/

<commit_msg>COMPUTE_Z re-enabled by default<commit_after>/**********************************************************************
 * $Id$
 *
 * GEOS - Geometry Engine Open Source
 * http://geos.refractions.net
 *
 * Copyright (C) 2001-2002 Vivid Solutions Inc.
 *
 * This is free software; you can redistribute and/or modify it under
 * the terms of the GNU Lesser General Public Licence as published
 * by the Free Software Foundation.
 * See the COPYING file for more information.
 *
 **********************************************************************/

#include <geos/geomgraph.h>
//#include "../headers/util.h"

#ifndef DEBUG
#define DEBUG 0
#endif
#ifndef COMPUTE_Z
#define COMPUTE_Z 1
#endif

namespace geos {

Node::Node(Coordinate& newCoord, EdgeEndStar* newEdges): GraphComponent(new Label(0,Location::UNDEF)) {
	coord=newCoord;
#if DEBUG
	cerr<<"Node::Node("<<newCoord.toString()<<")"<<endl;
#endif
#if COMPUTE_Z
	z=0;
	validz=0;
#endif
	edges=newEdges;
}

Node::~Node(){
	delete edges;
}

const Coordinate& Node::getCoordinate() const {
	return coord;
}

EdgeEndStar* Node::getEdges() {
	return edges;
}

bool Node::isIsolated() {
	return (label->getGeometryCount()==1);
}

void Node::add(EdgeEnd *e) {
#if DEBUG
	cerr<<"Node::add("<<e->print()<<")"<<endl;
#endif
	// Assert: start pt of e is equal to node point
	if (edges==NULL)
		edges=new EdgeEndStar();
	edges->insert(e);
	e->setNode(this);
#if COMPUTE_Z
	Coordinate &ec = e->getCoordinate();
	if ( ec.z != DoubleNotANumber )
	{
		z+=ec.z;
		validz++;
	}
	coord.z=z/validz;
#if DEBUG
	cerr<<" z=="<<z<<endl;
	cerr<<" validz=="<<validz<<endl;
	cerr<<" coord.z=="<<coord.z<<endl;
#endif // DEBUG
#endif
}

void Node::mergeLabel(const Node* n) {
	mergeLabel(n->label);
}

void Node::mergeLabel(const Label* label2) {
	for (int i=0; i<2; i++) {
		int loc=computeMergedLocation(label2, i);
		int thisLoc=label->getLocation(i);
		if (thisLoc==Location::UNDEF) label->setLocation(i,loc);
	}
}

void Node::setLabel(int argIndex, int onLocation) {
	if (label==NULL) {
		label=new Label(argIndex, onLocation);
	} else
		label->setLocation(argIndex, onLocation);
}

void Node::setLabelBoundary(int argIndex) {
	int loc=Location::UNDEF;
	if (label!=NULL)
		loc=label->getLocation(argIndex);
	// flip the loc
	int newLoc;
	switch (loc){
		case Location::BOUNDARY: newLoc=Location::INTERIOR; break;
		case Location::INTERIOR: newLoc=Location::BOUNDARY; break;
		default: newLoc=Location::BOUNDARY;  break;
	}
	label->setLocation(argIndex, newLoc);
}

int Node::computeMergedLocation(const Label* label2, int eltIndex){
	int loc=Location::UNDEF;
	loc=label->getLocation(eltIndex);
	if (!label2->isNull(eltIndex)) {
		int nLoc=label2->getLocation(eltIndex);
		if (loc!=Location::BOUNDARY) loc=nLoc;
	}
	return loc;
}

string Node::print(){
	string out="node "+coord.toString()+" lbl: "+label->toString();
	return out;
}

}

/**********************************************************************
 * $Log$
 * Revision 1.6  2004/11/19 10:10:23  strk
 * COMPUTE_Z re-enabled by default
 *
 * Revision 1.5  2004/11/17 15:09:08  strk
 * Changed COMPUTE_Z defaults to be more conservative
 *
 * Revision 1.4  2004/11/17 08:13:16  strk
 * Indentation changes.
 * Some Z_COMPUTATION activated by default.
 *
 * Revision 1.3  2004/10/21 22:29:54  strk
 * Indentation changes and some more COMPUTE_Z rules
 *
 * Revision 1.2  2004/07/02 13:28:26  strk
 * Fixed all #include lines to reflect headers layout change.
 * Added client application build tips in README.
 *
 * Revision 1.1  2004/03/19 09:48:45  ybychkov
 * "geomgraph" and "geomgraph/indexl" upgraded to JTS 1.4
 *
 * Revision 1.12  2003/11/07 01:23:42  pramsey
 * Add standard CVS headers licence notices and copyrights to all cpp and h
 * files.
 *
 *
 **********************************************************************/

<|endoftext|>


<commit_before>/** @file assembler.cpp
 * Implementation of Assembler class methods
 * @author Alexander Potashev
 * Copyright 2009 MDSP team
 */

#include "assembler.h"
#include "operation.h"

Assembler::Assembler( std::vector<SemanticUnit *> units)
{
    this->units = units;
}

Assembler::~Assembler()
{
}

std::map<unsigned int, hostUInt8> Assembler::run()
{
    /* This variable is used to keep track of the current address in
     * program memory while following the sequence of semantic units */
    unsigned int pc = 0; // which type is better to use here?

    /* map from semantic units in the source code to the current
     * addresses in program memory */
    std::map<SemanticUnit *, unsigned int> unit_addr;

    label_addr.clear();

    for ( int i = 0; i < (int)units.size(); i ++)
    {
        unit_addr[units[i]] = pc;

        if ( units[i]->type() == UNIT_LABEL)
        {
            label_addr[units[i]->str()] = pc;
        }
        else if ( units[i]->type() == UNIT_OPERATION)
        {
            pc += 4; // add operation length in bytes
        }
    }

    /* map from program memory byte addresses to encoded instructions
     * starting at those addresses */
    std::map<unsigned int, ByteLine *> op_list;
    for ( int i = 0; i < (int)units.size(); i ++)
    {
        if ( units[i]->type() == UNIT_OPERATION)
        {
            pc = unit_addr[units[i]];
            if ( op_list.find( pc) != op_list.end())
            {
                assert(0);
                throw; // 2 operations at the same address
            }

            op_list[pc] = encodeOperation( units[i], pc);
        }
    }

    /* TODO: use class MemoryModel (when it will come usable) */
    /* map from byte addresses in program memory to the values
     * of those bytes */
    std::map<unsigned int, hostUInt8> addr_byte;

    for ( std::map<unsigned int, ByteLine *>::iterator op = op_list.begin();
          op != op_list.end(); op ++)
    {
        unsigned int start_addr = op->first; // in bytes
        ByteLine *bytes = op->second;

        for ( int i = 0; i < (int)bytes->getSizeOfLine(); i ++)
        {
            if ( addr_byte.find( start_addr + i) != addr_byte.end())
            {
                assert(0);
                throw; // there already is a byte at this address
            }

            addr_byte[start_addr + i] = bytes->getByteVal( i);
        }
    }

    return addr_byte;
}

ByteLine *Assembler::encodeOperation(
    SemanticUnit *operation, unsigned int pc)
{
    /* This method is only applicable to assembler commands */
    assert( operation->type() == UNIT_OPERATION);

    Operation op;

    if ( *operation == "brm")
    {
        assert( operation->nOperands() == 2);

        hostUInt8 sd = 0;
        if ( (*operation)[0]->isIndirectGpr() &&
             (*operation)[1]->isDirectGpr())
        {
            sd = 1; // m(reg) -> reg
        }
        else if ( (*operation)[0]->isDirectGpr() &&
                  (*operation)[1]->isIndirectGpr())
        {
            sd = 0; // reg -> m(reg)
        }
        else
        {
            assert(0);
            throw; // invalid combination of opcode and operands
        }

        op.setMOVE( BRM, sd, 0,
                getGprNum( (*operation)[0]->str()),
                getGprNum( (*operation)[1]->str()));
    }
    else if ( *operation == "brr")
    {
        assert( operation->nOperands() == 2);
        assert( (*operation)[0]->isDirectGpr() &&
                (*operation)[1]->isDirectGpr());

        op.setMOVE( BRR, 0, 0,
                getGprNum( (*operation)[0]->str()),
                getGprNum( (*operation)[1]->str()));
    }
    else if ( *operation == "ld")
    {
        assert( operation->nOperands() == 2);
        assert( (*operation)[0]->isConstInt());

        hostUInt8 sd = 0;
        if ( (*operation)[1]->isDirectGpr())
        {
            sd = 0; // <const> -> reg
        }
        else if ( (*operation)[1]->isIndirectGpr())
        {
            sd = 1; // <const> -> m(reg)
        }
        else
        {
            assert(0);
            throw; // invalid combination of opcode and operands
        }

        /* LD command always has an imm16 operand */
        int imm = (*operation)[0]->integer();
        assert( imm >= 0 && imm <= 0xffff);

        hostUInt16 imm16 = (hostUInt16)imm;

        op.setMOVE( LD, sd, imm16, 0,
                getGprNum( (*operation)[1]->str()));
    }
    else if ( *operation == "add" || *operation == "sub")
    {
        hostUInt8 am = 0;
        hostUInt8 rs1 = 0;
        hostUInt8 rs2 = 0;
        hostUInt8 rd = 0;
        hostUInt16 imm10 = 0;

        if ( operation->nOperands() == 3)
        {
            assert( (*operation)[0]->isDirectOrIndirectGpr());
            assert( (*operation)[1]->isDirectOrIndirectGpr());
            assert( (*operation)[2]->isDirectOrIndirectGpr());

            rs1 = getGprNum( (*operation)[0]->str());
            rs2 = getGprNum( (*operation)[1]->str());
            rd = getGprNum( (*operation)[2]->str());

            if ( (*operation)[0]->isDirectGpr() &&
                 (*operation)[1]->isDirectGpr() &&
                 (*operation)[2]->isDirectGpr())
            {
                am = 0; // register direct (all operands are registers)
            }
            else if ( (*operation)[0]->isIndirectGpr() &&
                      (*operation)[1]->isIndirectGpr() &&
                      (*operation)[2]->isIndirectGpr())
            {
                am = 2; // register indirect (all operands are in memory)
            }
            else
            {
                assert(0);
                throw; // wrong operand types for 'add'
            }
        }
        else if ( operation->nOperands() == 2)
        {
            if ( (*operation)[0]->isConstInt() &&
                 (*operation)[1]->isDirectOrIndirectGpr())
            {
                imm10 = (*operation)[0]->integer();
                rd = getGprNum( (*operation)[1]->str());

                if ( (*operation)[1]->isDirectGpr())
                {
                    am = 1; // register direct with immediate data
                            // (implied addressing: sources are imm10
                            // and rD, destination is rD)
                }
                else // isIndirectGpr
                {
                    am = 3; // register indirect with immediate data
                            // (implied addressing: sources are imm10
                            // and memory, destination is memory
                            // (rD keeps memory address))
                }
            }
            else
            {
                throw;
            }
        }
        else
        {
            cout << "Wrong number of operand for 'add': " <<
                operation->nOperands() << endl;
            throw; // wrong numbers of operands for 'add'
        }

        op.setALU( NOP, *operation == "add" ? ADD : SUB, NOP,
                   am, imm10, rs1, rs2, rd);
    }
    else if ( *operation == "nop")
    {
        if ( operation->nOperands() != 0)
        {
            assert(0);
            throw;
        }

        op.setALU( NOP, NOP, NOP, 0, 0, 0, 0, 0);
    }
    else if ( *operation == "jmp")
    {
        hostUInt8 sd = 0;
        hostUInt8 rd = 0;
        hostUInt16 imm16 = 0;

        if ( operation->nOperands() != 1)
        {
            assert( 0);
        }

        if ( (*operation)[0]->isDirectGpr())
        {
            sd = 0;
            rd = getGprNum( (*operation)[0]->str());
        }
        else if ( (*operation)[0]->isDirectCustomId())
        {
            sd = 1;
            imm16 = label_addr[(*operation)[0]->str()];
        }
        else
        {
            assert( 0);
        }

        op.setPFLOW( JMP, sd, rd, imm16);
    }
    else
    {
        cout << "Unknown operation: " << operation->str() << endl;
        throw;
    }

    return op.encode();
}

int Assembler::getGprNum( std::string id)
{
    assert( id[0] == '%' && id[1] == 'r');
    assert( isdigit( id[2]));

    if ( id.size() == 3)
    {
        return (int)(id[2] - '0');
    }
    else if ( id.size() == 4)
    {
        assert( isdigit( id[3]));

        int x = 10 * (int)(id[2] - '0') + (int)(id[3] - '0');
        assert( x <= 31);

        return x;
    }
    else
    {
        throw;
    }
}

<commit_msg>asm: implement command `jgt'<commit_after>/** @file assembler.cpp
 * Implementation of Assembler class methods
 * @author Alexander Potashev
 * Copyright 2009 MDSP team
 */

#include "assembler.h"
#include "operation.h"

Assembler::Assembler( std::vector<SemanticUnit *> units)
{
    this->units = units;
}

Assembler::~Assembler()
{
}

std::map<unsigned int, hostUInt8> Assembler::run()
{
    /* This variable is used to keep track of the current address in
     * program memory while following the sequence of semantic units */
    unsigned int pc = 0; // which type is better to use here?

    /* map from semantic units in the source code to the current
     * addresses in program memory */
    std::map<SemanticUnit *, unsigned int> unit_addr;

    label_addr.clear();

    for ( int i = 0; i < (int)units.size(); i ++)
    {
        unit_addr[units[i]] = pc;

        if ( units[i]->type() == UNIT_LABEL)
        {
            label_addr[units[i]->str()] = pc;
        }
        else if ( units[i]->type() == UNIT_OPERATION)
        {
            pc += 4; // add operation length in bytes
        }
    }

    /* map from program memory byte addresses to encoded instructions
     * starting at those addresses */
    std::map<unsigned int, ByteLine *> op_list;
    for ( int i = 0; i < (int)units.size(); i ++)
    {
        if ( units[i]->type() == UNIT_OPERATION)
        {
            pc = unit_addr[units[i]];
            if ( op_list.find( pc) != op_list.end())
            {
                assert(0);
                throw; // 2 operations at the same address
            }

            op_list[pc] = encodeOperation( units[i], pc);
        }
    }

    /* TODO: use class MemoryModel (when it will come usable) */
    /* map from byte addresses in program memory to the values
     * of those bytes */
    std::map<unsigned int, hostUInt8> addr_byte;

    for ( std::map<unsigned int, ByteLine *>::iterator op = op_list.begin();
          op != op_list.end(); op ++)
    {
        unsigned int start_addr = op->first; // in bytes
        ByteLine *bytes = op->second;

        for ( int i = 0; i < (int)bytes->getSizeOfLine(); i ++)
        {
            if ( addr_byte.find( start_addr + i) != addr_byte.end())
            {
                assert(0);
                throw; // there already is a byte at this address
            }

            addr_byte[start_addr + i] = bytes->getByteVal( i);
        }
    }

    return addr_byte;
}

ByteLine *Assembler::encodeOperation(
    SemanticUnit *operation, unsigned int pc)
{
    /* This method is only applicable to assembler commands */
    assert( operation->type() == UNIT_OPERATION);

    Operation op;

    if ( *operation == "brm")
    {
        assert( operation->nOperands() == 2);

        hostUInt8 sd = 0;
        if ( (*operation)[0]->isIndirectGpr() &&
             (*operation)[1]->isDirectGpr())
        {
            sd = 1; // m(reg) -> reg
        }
        else if ( (*operation)[0]->isDirectGpr() &&
                  (*operation)[1]->isIndirectGpr())
        {
            sd = 0; // reg -> m(reg)
        }
        else
        {
            assert(0);
            throw; // invalid combination of opcode and operands
        }

        op.setMOVE( BRM, sd, 0,
                getGprNum( (*operation)[0]->str()),
                getGprNum( (*operation)[1]->str()));
    }
    else if ( *operation == "brr")
    {
        assert( operation->nOperands() == 2);
        assert( (*operation)[0]->isDirectGpr() &&
                (*operation)[1]->isDirectGpr());

        op.setMOVE( BRR, 0, 0,
                getGprNum( (*operation)[0]->str()),
                getGprNum( (*operation)[1]->str()));
    }
    else if ( *operation == "ld")
    {
        assert( operation->nOperands() == 2);
        assert( (*operation)[0]->isConstInt());

        hostUInt8 sd = 0;
        if ( (*operation)[1]->isDirectGpr())
        {
            sd = 0; // <const> -> reg
        }
        else if ( (*operation)[1]->isIndirectGpr())
        {
            sd = 1; // <const> -> m(reg)
        }
        else
        {
            assert(0);
            throw; // invalid combination of opcode and operands
        }

        /* LD command always has an imm16 operand */
        int imm = (*operation)[0]->integer();
        assert( imm >= 0 && imm <= 0xffff);

        hostUInt16 imm16 = (hostUInt16)imm;

        op.setMOVE( LD, sd, imm16, 0,
                getGprNum( (*operation)[1]->str()));
    }
    else if ( *operation == "add" || *operation == "sub")
    {
        hostUInt8 am = 0;
        hostUInt8 rs1 = 0;
        hostUInt8 rs2 = 0;
        hostUInt8 rd = 0;
        hostUInt16 imm10 = 0;

        if ( operation->nOperands() == 3)
        {
            assert( (*operation)[0]->isDirectOrIndirectGpr());
            assert( (*operation)[1]->isDirectOrIndirectGpr());
            assert( (*operation)[2]->isDirectOrIndirectGpr());

            rs1 = getGprNum( (*operation)[0]->str());
            rs2 = getGprNum( (*operation)[1]->str());
            rd = getGprNum( (*operation)[2]->str());

            if ( (*operation)[0]->isDirectGpr() &&
                 (*operation)[1]->isDirectGpr() &&
                 (*operation)[2]->isDirectGpr())
            {
                am = 0; // register direct (all operands are registers)
            }
            else if ( (*operation)[0]->isIndirectGpr() &&
                      (*operation)[1]->isIndirectGpr() &&
                      (*operation)[2]->isIndirectGpr())
            {
                am = 2; // register indirect (all operands are in memory)
            }
            else
            {
                assert(0);
                throw; // wrong operand types for 'add'
            }
        }
        else if ( operation->nOperands() == 2)
        {
            if ( (*operation)[0]->isConstInt() &&
                 (*operation)[1]->isDirectOrIndirectGpr())
            {
                imm10 = (*operation)[0]->integer();
                rd = getGprNum( (*operation)[1]->str());

                if ( (*operation)[1]->isDirectGpr())
                {
                    am = 1; // register direct with immediate data
                            // (implied addressing: sources are imm10
                            // and rD, destination is rD)
                }
                else // isIndirectGpr
                {
                    am = 3; // register indirect with immediate data
                            // (implied addressing: sources are imm10
                            // and memory, destination is memory
                            // (rD keeps memory address))
                }
            }
            else
            {
                throw;
            }
        }
        else
        {
            cout << "Wrong number of operand for 'add': " <<
                operation->nOperands() << endl;
            throw; // wrong numbers of operands for 'add'
        }

        op.setALU( NOP, *operation == "add" ? ADD : SUB, NOP,
                   am, imm10, rs1, rs2, rd);
    }
    else if ( *operation == "nop")
    {
        if ( operation->nOperands() != 0)
        {
            assert(0);
            throw;
        }

        op.setALU( NOP, NOP, NOP, 0, 0, 0, 0, 0);
    }
    else if ( *operation == "jmp" || *operation == "jgt")
    {
        hostUInt8 sd = 0;
        hostUInt8 rd = 0;
        hostUInt16 imm16 = 0;

        if ( operation->nOperands() != 1)
        {
            assert( 0);
        }

        if ( (*operation)[0]->isDirectGpr())
        {
            sd = 0;
            rd = getGprNum( (*operation)[0]->str());
        }
        else if ( (*operation)[0]->isDirectCustomId())
        {
            sd = 1;
            imm16 = label_addr[(*operation)[0]->str()];
        }
        else
        {
            assert( 0);
        }

        op.setPFLOW( *operation == "jmp" ? JMP : JGT, sd, rd, imm16);
    }
    else
    {
        cout << "Unknown operation: " << operation->str() << endl;
        throw;
    }

    return op.encode();
}

int Assembler::getGprNum( std::string id)
{
    assert( id[0] == '%' && id[1] == 'r');
    assert( isdigit( id[2]));

    if ( id.size() == 3)
    {
        return (int)(id[2] - '0');
    }
    else if ( id.size() == 4)
    {
        assert( isdigit( id[3]));

        int x = 10 * (int)(id[2] - '0') + (int)(id[3] - '0');
        assert( x <= 31);

        return x;
    }
    else
    {
        throw;
    }
}

<|endoftext|>


<commit_before>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2013.  All rights reserved
 */
#include    "Stroika/Frameworks/StroikaPreComp.h"

#include    <iostream>

#include    "Stroika/Foundation/Execution/CommandLine.h"
#include    "Stroika/Foundation/Execution/Event.h"
#include    "Stroika/Foundation/Execution/Sleep.h"
#include    "Stroika/Foundation/Memory/Optional.h"
#include    "Stroika/Frameworks/Service/Main.h"

using   namespace std;

using   namespace Stroika::Foundation;
using   namespace Stroika::Frameworks::Service;

using   Containers::Sequence;

/*
 *  Almost always would want to use logger with a service. But demarcate so clear what is 'service' demo
 *  and what is logger demo.
 */
#ifndef     qUseLogger
#define     qUseLogger 1
#endif

#if qUseLogger
#include    "Stroika/Foundation/Execution/Logger.h"
#endif

#if qUseLogger
using   Execution::Logger;
#endif

/// *** TODO ****
/// add option to log to LOGGER instead of stderr!!!
///         (we have TODO adding wrapper of service backend which writes to syslog. Use that).
//          OR - maybe - just always do logging. Thats probably better, and have a flag in service wrapper
//          about log level? No - maybe thats obvihs too. Mabe just upagrade service code to use logger!!!
//          I think that would always - or nearly always - be desirable. Maybe make configurable. But no need
//          as a user can always use their own servcie impl!
//

namespace {
    struct   AppRep_ : Main::IApplicationRep {
        AppRep_ () {
        }
        virtual ~AppRep_ () {
        }

    public:
        virtual void  MainLoop () override {
            Execution::Sleep (1 * 24 * 60 * 60);    // wait 1 day ... simple test....
        }
        virtual Main::ServiceDescription  GetServiceDescription () const override {
            Main::ServiceDescription    t;
            t.fPrettyName = L"Test Service";
            t.fRegistrationName = L"Test-Service";
            return t;
        }
    };
}

#if 0
usage --start, or --stop or --status or --restart
#endif

int main (int argc, const char* argv[])
{
#if     qUseLogger && qHas_Syslog
    Logger::Get ().SetAppender (Logger::SysLogAppender (L"Stroika-Sample-SimpleService"));
#endif

    Sequence<String>  args    =   Execution::ParseCommandLine (argc, argv);
    shared_ptr<Main::IServiceIntegrationRep>    serviceIntegrationRep   =   Main::mkDefaultServiceIntegrationRep ();
    if (Execution::MatchesCommandLineArgument (args, L"run2Idle")) {
        serviceIntegrationRep = shared_ptr<Main::IServiceIntegrationRep> (new Main::RunTilIdleService ());
    }
    Main    m (shared_ptr<AppRep_> (new AppRep_ ()), serviceIntegrationRep);
    if (Execution::MatchesCommandLineArgument (args, L"status")) {
        cout << m.GetServiceStatusMessage ().AsUTF8<string> ();
        return EXIT_SUCCESS;
    }
    else if (Execution::MatchesCommandLineArgument (args, L"help")) {
        //ShowUsage_ ();
        return EXIT_SUCCESS;
    }
    try {
        m.Run (args);
    }
    catch (const std::exception& e) {
#if     qUseLogger
        // @todo - WRONG - GENERICALLYT HANLDLE e.wwhat() codepage issue better
        // not sure what codepage to use for convert???
        Logger::Get ().Log (Logger::Priority::eError, Characters::NarrowSDKStringToWide (e.what ()));
#endif
        cerr << "FAILED: '" << e.what () << "'" << endl;
        return EXIT_FAILURE;
    }
    catch (const Execution::StringException& e) {
#if     qUseLogger
        Logger::Get ().Log (Logger::Priority::eError, e.As<wstring> ());
#endif
        cerr << "FAILED: '" << Characters::WideStringToNarrowSDKString (e.As<wstring> ()) << "'" << endl;
        return EXIT_FAILURE;
    }
    catch (...) {
#if     qUseLogger
        Logger::Get ().Log (Logger::Priority::eError, L"Unknown Exception...");
#endif
        cerr << "Exception - terminating..." << endl;
        return EXIT_FAILURE;
    }
    return EXIT_SUCCESS;
}
<commit_msg>Start at ShowUsage for SimpleService sample<commit_after>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2013.  All rights reserved
 */
#include    "Stroika/Frameworks/StroikaPreComp.h"

#include    <iostream>

#include    "Stroika/Foundation/Execution/CommandLine.h"
#include    "Stroika/Foundation/Execution/Event.h"
#include    "Stroika/Foundation/Execution/Sleep.h"
#include    "Stroika/Foundation/Memory/Optional.h"
#include    "Stroika/Frameworks/Service/Main.h"

using   namespace std;

using   namespace Stroika::Foundation;
using   namespace Stroika::Frameworks::Service;

using   Containers::Sequence;

/*
 *  Almost always would want to use logger with a service. But demarcate so clear what is 'service' demo
 *  and what is logger demo.
 */
#ifndef     qUseLogger
#define     qUseLogger 1
#endif

#if qUseLogger
#include    "Stroika/Foundation/Execution/Logger.h"
#endif

#if qUseLogger
using   Execution::Logger;
#endif

/// *** TODO ****
/// add option to log to LOGGER instead of stderr!!!
///         (we have TODO adding wrapper of service backend which writes to syslog. Use that).
//          OR - maybe - just always do logging. Thats probably better, and have a flag in service wrapper
//          about log level? No - maybe thats obvihs too. Mabe just upagrade service code to use logger!!!
//          I think that would always - or nearly always - be desirable. Maybe make configurable. But no need
//          as a user can always use their own servcie impl!
//

namespace {
    struct   AppRep_ : Main::IApplicationRep {
        AppRep_ () {
        }
        virtual ~AppRep_ () {
        }

    public:
        virtual void  MainLoop () override {
            Execution::Sleep (1 * 24 * 60 * 60);    // wait 1 day ... simple test....
        }
        virtual Main::ServiceDescription  GetServiceDescription () const override {
            Main::ServiceDescription    t;
            t.fPrettyName = L"Test Service";
            t.fRegistrationName = L"Test-Service";
            return t;
        }
    };
}

namespace {
	void	ShowUsage_ ()
	{
		cerr << "Usage: Sample-SimpleService ";
		cerr << "[--start] ";
		cerr << "[--stop] ";
		cerr << "[--status] ";
		cerr << "[--restart] ";
		cerr << "[--run2Idle] ";
		cerr << "[--help] ";
		cerr << endl;
	}
}

int main (int argc, const char* argv[])
{
#if     qUseLogger && qHas_Syslog
    Logger::Get ().SetAppender (Logger::SysLogAppender (L"Stroika-Sample-SimpleService"));
#endif

    Sequence<String>  args    =   Execution::ParseCommandLine (argc, argv);
    shared_ptr<Main::IServiceIntegrationRep>    serviceIntegrationRep   =   Main::mkDefaultServiceIntegrationRep ();
    if (Execution::MatchesCommandLineArgument (args, L"run2Idle")) {
        serviceIntegrationRep = shared_ptr<Main::IServiceIntegrationRep> (new Main::RunTilIdleService ());
    }
    Main    m (shared_ptr<AppRep_> (new AppRep_ ()), serviceIntegrationRep);
    if (Execution::MatchesCommandLineArgument (args, L"status")) {
        cout << m.GetServiceStatusMessage ().AsUTF8<string> ();
        return EXIT_SUCCESS;
    }
    else if (Execution::MatchesCommandLineArgument (args, L"help")) {
        ShowUsage_ ();
        return EXIT_SUCCESS;
    }
    try {
        m.Run (args);
    }
    catch (const std::exception& e) {
#if     qUseLogger
        // @todo - WRONG - GENERICALLYT HANLDLE e.wwhat() codepage issue better
        // not sure what codepage to use for convert???
        Logger::Get ().Log (Logger::Priority::eError, Characters::NarrowSDKStringToWide (e.what ()));
#endif
        cerr << "FAILED: '" << e.what () << "'" << endl;
        return EXIT_FAILURE;
    }
    catch (const Execution::StringException& e) {
#if     qUseLogger
        Logger::Get ().Log (Logger::Priority::eError, e.As<wstring> ());
#endif
        cerr << "FAILED: '" << Characters::WideStringToNarrowSDKString (e.As<wstring> ()) << "'" << endl;
        return EXIT_FAILURE;
    }
    catch (...) {
#if     qUseLogger
        Logger::Get ().Log (Logger::Priority::eError, L"Unknown Exception...");
#endif
        cerr << "Exception - terminating..." << endl;
        return EXIT_FAILURE;
    }
    return EXIT_SUCCESS;
}
<|endoftext|>


<commit_before>/******************************************************************************
*       SOFA, Simulation Open-Framework Architecture, development version     *
*                (c) 2006-2017 INRIA, USTL, UJF, CNRS, MGH                    *
*                                                                             *
* This program is free software; you can redistribute it and/or modify it     *
* under the terms of the GNU Lesser General Public License as published by    *
* the Free Software Foundation; either version 2.1 of the License, or (at     *
* your option) any later version.                                             *
*                                                                             *
* This program is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or       *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *
* for more details.                                                           *
*                                                                             *
* You should have received a copy of the GNU Lesser General Public License    *
* along with this program. If not, see <http://www.gnu.org/licenses/>.        *
*******************************************************************************
* Authors: The SOFA Team and external contributors (see Authors.txt)          *
*                                                                             *
* Contact information: contact@sofa-framework.org                             *
******************************************************************************/
#include <sofa/helper/gl/Capture.h>
#include <sofa/helper/system/SetDirectory.h>

#include <sys/types.h>
#include <sys/stat.h>

#include <cstdio>		// sprintf and friends
#include <sofa/helper/logging/Messaging.h>

namespace sofa
{

namespace helper
{

namespace gl
{

Capture::Capture()
    : prefix("capture"), counter(-1)
{
}

bool Capture::saveScreen(const std::string& filename, int compression_level)
{
    std::string extension = sofa::helper::system::SetDirectory::GetExtension(filename.c_str());
    std::transform(extension.begin(),extension.end(),extension.begin(),::tolower );

    //test if we can export in lossless image
    bool imageSupport = helper::io::Image::FactoryImage::getInstance()->hasKey(extension);
    if(!imageSupport)
    {
        msg_error("Capture") << "Could not write " << extension  << "image format (no support found)" ;
        return false;
    }

    helper::io::Image* img =  helper::io::Image::FactoryImage::getInstance()->createObject(extension, "");

    GLint viewport[4];
    glGetIntegerv(GL_VIEWPORT,viewport);
    img->init(viewport[2], viewport[3], 1, 1, io::Image::UNORM8, io::Image::RGB);
    glReadBuffer(GL_FRONT);
    glPixelStorei(GL_PACK_ALIGNMENT, 1);
    glReadPixels(viewport[0], viewport[1], viewport[2], viewport[3], GL_RGB, GL_UNSIGNED_BYTE, img->getPixels());

    if (!img->save(filename, compression_level))
        return false;

    msg_info("Capture") << "Saved "<<img->getWidth()<<"x"<<img->getHeight()<<" screen image to "<<filename ;
    glReadBuffer(GL_BACK);
    return true;
}

std::string Capture::findFilename()
{
    std::string filename;
#ifndef PS3
    char buf[32];
    int c;
    c = 0;
    struct stat st;
    do
    {
        ++c;
        sprintf(buf, "%08d",c);
        filename = prefix;
        filename += buf;
#ifdef SOFA_HAVE_PNG
        filename += ".png";
#else
        filename += ".bmp";
#endif
    }
    while (stat(filename.c_str(),&st)==0);
    counter = c+1;

    sprintf(buf, "%08d",c);
    filename = prefix;
    filename += buf;
#ifdef SOFA_HAVE_PNG
    filename += ".png";
#else
    filename += ".bmp";
#endif
#endif
    return filename;
}

bool Capture::saveScreen(int compression_level)
{
    return saveScreen(findFilename(), compression_level);
}

} // namespace gl

} // namespace helper

} // namespace sofa

<commit_msg>[SofaHelper] Capture: fix using png if supported<commit_after>/******************************************************************************
*       SOFA, Simulation Open-Framework Architecture, development version     *
*                (c) 2006-2017 INRIA, USTL, UJF, CNRS, MGH                    *
*                                                                             *
* This program is free software; you can redistribute it and/or modify it     *
* under the terms of the GNU Lesser General Public License as published by    *
* the Free Software Foundation; either version 2.1 of the License, or (at     *
* your option) any later version.                                             *
*                                                                             *
* This program is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or       *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *
* for more details.                                                           *
*                                                                             *
* You should have received a copy of the GNU Lesser General Public License    *
* along with this program. If not, see <http://www.gnu.org/licenses/>.        *
*******************************************************************************
* Authors: The SOFA Team and external contributors (see Authors.txt)          *
*                                                                             *
* Contact information: contact@sofa-framework.org                             *
******************************************************************************/
#include <sofa/helper/gl/Capture.h>
#include <sofa/helper/system/SetDirectory.h>

#include <sys/types.h>
#include <sys/stat.h>

#include <cstdio>		// sprintf and friends
#include <sofa/helper/logging/Messaging.h>

namespace sofa
{

namespace helper
{

namespace gl
{

Capture::Capture()
    : prefix("capture"), counter(-1)
{
}

bool Capture::saveScreen(const std::string& filename, int compression_level)
{
    std::string extension = sofa::helper::system::SetDirectory::GetExtension(filename.c_str());
    std::transform(extension.begin(),extension.end(),extension.begin(),::tolower );

    //test if we can export in lossless image
    bool imageSupport = helper::io::Image::FactoryImage::getInstance()->hasKey(extension);
    if(!imageSupport)
    {
        msg_error("Capture") << "Could not write " << extension  << "image format (no support found)" ;
        return false;
    }

    helper::io::Image* img =  helper::io::Image::FactoryImage::getInstance()->createObject(extension, "");

    GLint viewport[4];
    glGetIntegerv(GL_VIEWPORT,viewport);
    img->init(viewport[2], viewport[3], 1, 1, io::Image::UNORM8, io::Image::RGB);
    glReadBuffer(GL_FRONT);
    glPixelStorei(GL_PACK_ALIGNMENT, 1);
    glReadPixels(viewport[0], viewport[1], viewport[2], viewport[3], GL_RGB, GL_UNSIGNED_BYTE, img->getPixels());

    if (!img->save(filename, compression_level))
        return false;

    msg_info("Capture") << "Saved "<<img->getWidth()<<"x"<<img->getHeight()<<" screen image to "<<filename ;
    glReadBuffer(GL_BACK);
    return true;
}

std::string Capture::findFilename()
{
    bool pngSupport = helper::io::Image::FactoryImage::getInstance()->hasKey("png")
            || helper::io::Image::FactoryImage::getInstance()->hasKey("PNG");

    bool bmpSupport = helper::io::Image::FactoryImage::getInstance()->hasKey("bmp")
            || helper::io::Image::FactoryImage::getInstance()->hasKey("BMP");

    std::string filename = "";

    if(!pngSupport && !bmpSupport)
        return filename;

#ifndef PS3
    char buf[32];
    int c;
    c = 0;
    struct stat st;
    do
    {
        ++c;
        sprintf(buf, "%08d",c);
        filename = prefix;
        filename += buf;
        if(pngSupport)
            filename += ".png";
        else
            filename += ".bmp";
    }
    while (stat(filename.c_str(),&st)==0);
    counter = c+1;

    sprintf(buf, "%08d",c);
    filename = prefix;
    filename += buf;
    if(pngSupport)
        filename += ".png";
    else
        filename += ".bmp";
#endif

    return filename;
}

bool Capture::saveScreen(int compression_level)
{
    return saveScreen(findFilename(), compression_level);
}

} // namespace gl

} // namespace helper

} // namespace sofa

<|endoftext|>


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

#include "spotcheck.h"

#include <fstream>
#include <sstream>

#include <iface/dve2/dve2.hh>
#include <ltlparse/public.hh>
#include <tgba/tgbaproduct.hh>
#include <tgbaalgos/dotty.hh>
#include <tgbaalgos/emptiness.hh>
#include <tgbaalgos/translate.hh>

#include "unop.h"
#include "visitor.h"

//#define trace std::cerr
#define trace while (0) std::cerr

namespace spaction {

bool
spot_check(const std::string &ltl_string, const std::string &modelfile) {
    // spot parsing of the instantiated formula
    spot::ltl::parse_error_list pel;
    const spot::ltl::formula *ltl_formula = spot::ltl::parse(ltl_string, pel);
    if (spot::ltl::format_parse_errors(std::cerr, ltl_string, pel)) {
        ltl_formula->destroy();
        exit(1);
    }

    trace << "spot parsing done" << std::endl;

    // to store atomic propositions appearing in the formula
    spot::ltl::atomic_prop_set atomic_propositions;
    // bdd dictionnary
    spot::bdd_dict *bdd_dictionnary = new spot::bdd_dict();
    const spot::tgba *property_automaton;
    // NB: embedding the translation in a block is mandatory for proper deallocation
    {
        // translate the formula into an automaton
        spot::translator formula_translator(bdd_dictionnary);
        property_automaton = formula_translator.run(&ltl_formula);
    }

    trace << "tgba built" << std::endl;

    // collect atomic propositions from formula
    atomic_prop_collect(ltl_formula, &atomic_propositions);

    trace << "ap collected" << std::endl;

    // load divine model
    spot::kripke *model = spot::load_dve2(modelfile, bdd_dictionnary, &atomic_propositions);

    trace << "dve loaded" << std::endl;

    // synchronized product of both automata
    spot::tgba *product = new spot::tgba_product(model, property_automaton);

    trace << "product built" << std::endl;

    // \debug
    {
        // output automaton in .dot
        static int i = 0;
        std::stringstream autname;
        autname << "automaton_" << i << ".dot";
        std::ofstream out(autname.str());
        spot::dotty_reachable(out, property_automaton, false);
        out.close();
        // output kripke in .dot
        out = std::ofstream("model.dot");
        spot::dotty_reachable(out, model);
        out.close();
        // output product in .dot
        std::stringstream prodname;
        prodname << "product_" << i++ << ".dot";
        out = std::ofstream(prodname.str());
        spot::dotty_reachable(out, product);
        out.close();
    }

    // emptiness check of the product automaton
    const char* echeck_algo = "Cou99";
    const char* err;
    spot::emptiness_check_instantiator* echeck_inst = nullptr;
    echeck_inst = spot::emptiness_check_instantiator::construct(echeck_algo, &err);
    // \todo properly catch incorrect instantiation of emptiness checker
    assert(echeck_inst);

    // the real emptiness check
    spot::emptiness_check* emptiness_checker = echeck_inst->instantiate(product);
    // \todo properly catch incorrect instantation
    assert(emptiness_checker);

    trace << "emptichecker built" << std::endl;

    spot::emptiness_check_result *result = nullptr;
    try {
        result = emptiness_checker->check();
    } catch (std::bad_alloc) {
        std::cerr << "out of memory during emptiness check" << std::endl;
        assert(false);
    }

    trace << "all done, prepare for delete" << std::endl;

    // free all the stuff
    delete result;
    trace << "result deleted" << std::endl;
    delete product;
    trace << "product deleted" << std::endl;
    delete model;
    trace << "model deleted" << std::endl;
    delete property_automaton;
    trace << "tgba deleted" << std::endl;
    delete bdd_dictionnary;
    trace << "bdd dict deleted" << std::endl;
    ltl_formula->destroy();
    trace << "formula deleted" << std::endl;

    trace << "all freed, return" << std::endl;

    trace << "result is " << !result << std::endl;

    trace << "done block" << std::endl;

    // return the result
    return !result;
}

static bool
spot_check_inf(const cltl_formula *formula, int n, const std::string &modelname) {
    // instantiate the cost formula
    std::string ltl_string;
    {
        cltl_formula *tmp = instantiate_inf(formula, n);
        ltl_string = tmp->dump();
        tmp->destroy();
    }
    return spot_check(ltl_string, modelname);
}

unsigned int
find_bound_min(const cltl_formula *f, const std::string &modelname) {
    // min holds the greatest tested number for which spot_check returns true
    // max holds the smallest tested number for which spot_check returns false
    unsigned int max = 0;
    unsigned int min = 0;

    if (!spot_check_inf(f, max, modelname))
        return max;

    // increase
    do {
        // \todo safe checks to detect int overflow
        if (!max)   max = 1;
        else        max *= 2;
    } while (spot_check_inf(f, max, modelname));

    // decrease
    min = max / 2;
    while (min + 1 != max) {
        unsigned int tmp = (min + max) / 2;
        if (spot_check_inf(f, tmp, modelname))
            min = tmp;
        else
            max = tmp;
    }
    return min;
}

static bool
spot_check_sup(const cltl_formula *formula, int n, const std::string &modelname) {
    // instantiate the cost formula
    std::string ltl_string;
    {
        cltl_formula *tmp = instantiate_sup(formula, n);
        ltl_string = tmp->dump();
        tmp->destroy();
    }
    return spot_check(ltl_string, modelname);
}

unsigned int
find_bound_max(const cltl_formula *f, const std::string &modelname) {
    // min holds the greatest tested number for which spot_check returns true
    // max holds the smallest tested number for which spot_check returns false
    unsigned int max = 0;
    unsigned int min = 0;

    if (spot_check_sup(f, max, modelname))
        return max;

    // increase
    do {
        // \todo safe checks to detect int overflow
        if (!max)   max = 1;
        else        max *= 2;
    } while (!spot_check_sup(f, max, modelname));

    // decrease
    min = max / 2;
    while (min + 1 != max) {
        unsigned int tmp = (min + max) / 2;
        if (!spot_check_sup(f, tmp, modelname))
            min = tmp;
        else
            max = tmp;
    }
    return min;
}

}  // namespace spaction
<commit_msg>Adding a line of output<commit_after>// This source file is part of spaction
//
// Copyright 2014 Software Modeling and Verification Group
// University of Geneva
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "spotcheck.h"

#include <fstream>
#include <sstream>

#include <iface/dve2/dve2.hh>
#include <ltlparse/public.hh>
#include <tgba/tgbaproduct.hh>
#include <tgbaalgos/dotty.hh>
#include <tgbaalgos/emptiness.hh>
#include <tgbaalgos/translate.hh>

#include "unop.h"
#include "visitor.h"

//#define trace std::cerr
#define trace while (0) std::cerr

namespace spaction {

bool
spot_check(const std::string &ltl_string, const std::string &modelfile) {
    // spot parsing of the instantiated formula
    spot::ltl::parse_error_list pel;
    const spot::ltl::formula *ltl_formula = spot::ltl::parse(ltl_string, pel);
    if (spot::ltl::format_parse_errors(std::cerr, ltl_string, pel)) {
        ltl_formula->destroy();
        exit(1);
    }

    trace << "spot parsing done" << std::endl;

    // to store atomic propositions appearing in the formula
    spot::ltl::atomic_prop_set atomic_propositions;
    // bdd dictionnary
    spot::bdd_dict *bdd_dictionnary = new spot::bdd_dict();
    const spot::tgba *property_automaton;
    // NB: embedding the translation in a block is mandatory for proper deallocation
    {
        // translate the formula into an automaton
        spot::translator formula_translator(bdd_dictionnary);
        property_automaton = formula_translator.run(&ltl_formula);
    }

    trace << "tgba built" << std::endl;

    // collect atomic propositions from formula
    atomic_prop_collect(ltl_formula, &atomic_propositions);

    trace << "ap collected" << std::endl;

    // load divine model
    spot::kripke *model = spot::load_dve2(modelfile, bdd_dictionnary, &atomic_propositions);

    trace << "dve loaded" << std::endl;

    // synchronized product of both automata
    spot::tgba *product = new spot::tgba_product(model, property_automaton);

    trace << "product built" << std::endl;

    // \debug
    {
        // output automaton in .dot
        static int i = 0;
        std::stringstream autname;
        autname << "automaton_" << i << ".dot";
        std::ofstream out(autname.str());
        spot::dotty_reachable(out, property_automaton, false);
        out.close();
        // output kripke in .dot
        out = std::ofstream("model.dot");
        spot::dotty_reachable(out, model);
        out.close();
        // output product in .dot
        std::stringstream prodname;
        prodname << "product_" << i++ << ".dot";
        out = std::ofstream(prodname.str());
        spot::dotty_reachable(out, product);
        out.close();
    }

    // emptiness check of the product automaton
    const char* echeck_algo = "Cou99";
    const char* err;
    spot::emptiness_check_instantiator* echeck_inst = nullptr;
    echeck_inst = spot::emptiness_check_instantiator::construct(echeck_algo, &err);
    // \todo properly catch incorrect instantiation of emptiness checker
    assert(echeck_inst);

    // the real emptiness check
    spot::emptiness_check* emptiness_checker = echeck_inst->instantiate(product);
    // \todo properly catch incorrect instantation
    assert(emptiness_checker);

    trace << "emptichecker built" << std::endl;

    spot::emptiness_check_result *result = nullptr;
    try {
        result = emptiness_checker->check();
    } catch (std::bad_alloc) {
        std::cerr << "out of memory during emptiness check" << std::endl;
        assert(false);
    }

    trace << "all done, prepare for delete" << std::endl;

    // free all the stuff
    delete result;
    trace << "result deleted" << std::endl;
    delete product;
    trace << "product deleted" << std::endl;
    delete model;
    trace << "model deleted" << std::endl;
    delete property_automaton;
    trace << "tgba deleted" << std::endl;
    delete bdd_dictionnary;
    trace << "bdd dict deleted" << std::endl;
    ltl_formula->destroy();
    trace << "formula deleted" << std::endl;

    trace << "all freed, return" << std::endl;

    trace << "result is " << !result << std::endl;

    trace << "done block" << std::endl;

    // return the result
    return !result;
}

static bool
spot_check_inf(const cltl_formula *formula, int n, const std::string &modelname) {
    // instantiate the cost formula
    std::string ltl_string;
    {
        cltl_formula *tmp = instantiate_inf(formula, n);
        ltl_string = tmp->dump();
        tmp->destroy();
    }
    return spot_check(ltl_string, modelname);
}

unsigned int
find_bound_min(const cltl_formula *f, const std::string &modelname) {
    // min holds the greatest tested number for which spot_check returns true
    // max holds the smallest tested number for which spot_check returns false
    unsigned int max = 0;
    unsigned int min = 0;

    if (!spot_check_inf(f, max, modelname))
        return max;

    // increase
    do {
        // \todo safe checks to detect int overflow
        if (!max)   max = 1;
        else        max *= 2;
    } while (spot_check_inf(f, max, modelname));

    // decrease
    min = max / 2;
    while (min + 1 != max) {
        unsigned int tmp = (min + max) / 2;
        if (spot_check_inf(f, tmp, modelname))
            min = tmp;
        else
            max = tmp;
    }
    return min;
}

static bool
spot_check_sup(const cltl_formula *formula, int n, const std::string &modelname) {
    std::cerr << "checking " << n << std::endl;
    // instantiate the cost formula
    std::string ltl_string;
    {
        cltl_formula *tmp = instantiate_sup(formula, n);
        ltl_string = tmp->dump();
        tmp->destroy();
    }
    return spot_check(ltl_string, modelname);
}

unsigned int
find_bound_max(const cltl_formula *f, const std::string &modelname) {
    // min holds the greatest tested number for which spot_check returns true
    // max holds the smallest tested number for which spot_check returns false
    unsigned int max = 0;
    unsigned int min = 0;

    if (spot_check_sup(f, max, modelname))
        return max;

    // increase
    do {
        // \todo safe checks to detect int overflow
        if (!max)   max = 1;
        else        max *= 2;
    } while (!spot_check_sup(f, max, modelname));

    // decrease
    min = max / 2;
    while (min + 1 != max) {
        unsigned int tmp = (min + max) / 2;
        if (!spot_check_sup(f, tmp, modelname))
            min = tmp;
        else
            max = tmp;
    }
    return min;
}

}  // namespace spaction
<|endoftext|>