<commit_before>/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.
 */

/*
 * Copyright (C) 2015 ScyllaDB
 *
 * Modified by ScyllaDB
 */

/*
 * This file is part of Scylla.
 *
 * Scylla is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Scylla 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 Scylla.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "i_filter.hh"
#include "fb_utilities.hh"
#include "bytes.hh"
#include "utils/murmur_hash.hh"
#include "core/shared_ptr.hh"
#include "utils/large_bitset.hh"
#include <array>
#include <cstdlib>
#include "bloom_filter.hh"

namespace utils {
namespace filter {
static thread_local auto reusable_indexes = std::vector<long>();

void bloom_filter::set_indexes(int64_t base, int64_t inc, int count, long max, std::vector<long>& results) {
    for (int i = 0; i < count; i++) {
        results[i] = abs(base % max);
        base = static_cast<int64_t>(static_cast<uint64_t>(base) + static_cast<uint64_t>(inc));
    }
}

std::vector<long> bloom_filter::get_hash_buckets(const bytes_view& key, int hash_count, long max) {
    std::array<uint64_t, 2> h;
    hash(key, 0, h);

    auto indexes = std::vector<long>();

    indexes.resize(hash_count);
    set_indexes(h[0], h[1], hash_count, max, indexes);
    return indexes;
}

std::vector<long> bloom_filter::indexes(const bytes_view& key) {
    // we use the same array both for storing the hash result, and for storing the indexes we return,
    // so that we do not need to allocate two arrays.
    auto& idx = reusable_indexes;
    std::array<uint64_t, 2> h;
    hash(key, 0, h);

    idx.resize(_hash_count);
    set_indexes(h[0], h[1], _hash_count, _bitset.size(), idx);
    return idx;
}

filter_ptr create_filter(int hash, large_bitset&& bitset) {
    return std::make_unique<murmur3_bloom_filter>(hash, std::move(bitset));
}

filter_ptr create_filter(int hash, long num_elements, int buckets_per) {
    long num_bits = (num_elements * buckets_per) + bloom_calculations::EXCESS;
    num_bits = align_up<long>(num_bits, 64);  // Seems to be implied in origin
    large_bitset bitset(num_bits);
    return std::make_unique<murmur3_bloom_filter>(hash, std::move(bitset));
}
}
}
<commit_msg>bloom_filter: fix overflow for large filters<commit_after>/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.
 */

/*
 * Copyright (C) 2015 ScyllaDB
 *
 * Modified by ScyllaDB
 */

/*
 * This file is part of Scylla.
 *
 * Scylla is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Scylla 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 Scylla.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "i_filter.hh"
#include "fb_utilities.hh"
#include "bytes.hh"
#include "utils/murmur_hash.hh"
#include "core/shared_ptr.hh"
#include "utils/large_bitset.hh"
#include <array>
#include <cstdlib>
#include "bloom_filter.hh"

namespace utils {
namespace filter {
static thread_local auto reusable_indexes = std::vector<long>();

void bloom_filter::set_indexes(int64_t base, int64_t inc, int count, long max, std::vector<long>& results) {
    for (int i = 0; i < count; i++) {
        results[i] = std::abs(base % max);
        base = static_cast<int64_t>(static_cast<uint64_t>(base) + static_cast<uint64_t>(inc));
    }
}

std::vector<long> bloom_filter::get_hash_buckets(const bytes_view& key, int hash_count, long max) {
    std::array<uint64_t, 2> h;
    hash(key, 0, h);

    auto indexes = std::vector<long>();

    indexes.resize(hash_count);
    set_indexes(h[0], h[1], hash_count, max, indexes);
    return indexes;
}

std::vector<long> bloom_filter::indexes(const bytes_view& key) {
    // we use the same array both for storing the hash result, and for storing the indexes we return,
    // so that we do not need to allocate two arrays.
    auto& idx = reusable_indexes;
    std::array<uint64_t, 2> h;
    hash(key, 0, h);

    idx.resize(_hash_count);
    set_indexes(h[0], h[1], _hash_count, _bitset.size(), idx);
    return idx;
}

filter_ptr create_filter(int hash, large_bitset&& bitset) {
    return std::make_unique<murmur3_bloom_filter>(hash, std::move(bitset));
}

filter_ptr create_filter(int hash, long num_elements, int buckets_per) {
    long num_bits = (num_elements * buckets_per) + bloom_calculations::EXCESS;
    num_bits = align_up<long>(num_bits, 64);  // Seems to be implied in origin
    large_bitset bitset(num_bits);
    return std::make_unique<murmur3_bloom_filter>(hash, std::move(bitset));
}
}
}
<|endoftext|>


<commit_before>// For conditions of distribution and use, see copyright notice in license.txt

#include "StableHeaders.h"
#include "AvatarModule.h"
#include "Avatar/AvatarExporter.h"

#include "LLSDUtilities.h"
#include "XmlRpcEpi.h"

#include "Poco/MD5Engine.h"
#include "Poco/SHA1Engine.h"
#include "Poco/Base64Encoder.h"

#include <QByteArray>
#include <QUrl>

using namespace RexTypes;

// Time in which to reauthenticate if export has lasted long, in seconds
static const float REAUTHENTICATION_TIME = 60.0f;

namespace Avatar
{
    AvatarExporter::AvatarExporter() : ThreadTask("AvatarExport")
    {
    }

    void AvatarExporter::Work()
    {
        AvatarExporterResultPtr result(new AvatarExporterResult());

        AvatarExporterRequestPtr request = GetNextRequest<AvatarExporterRequest>();
        if (request)
            ProcessRequest(request, result);
        else
        {
            result->message_ = "No valid export request";
            result->success_ = false;
        }

        SetResult<AvatarExporterResult>(result);
    }

    void AvatarExporter::ProcessRequest(AvatarExporterRequestPtr request, AvatarExporterResultPtr result)
    {
        if (request->avatar_xml_.empty())
        {
            result->message_ = "Empty avatar description";
            result->success_ = false;
            return;
        }

        // Replace < > so that xmlrpc call doesn't get confused
        ReplaceSubstringInplace(request->avatar_xml_, "<", "<");
        ReplaceSubstringInplace(request->avatar_xml_, ">", ">");

        QUrl authserver_url(QString::fromStdString(request->authserver_));
        if (authserver_url.port() == -1)
        {
            authserver_url.setPort(10001);
            request->authserver_ = authserver_url.toString().toStdString();
        }

        // Authenticate first to get an uptodate sessionhash
        boost::timer export_timer; // For checking if we should refresh the hash further on
        std::string sessionhash;
        std::string avatar_url;
        std::string error;
        if (!LoginToAuthentication(request->account_, request->authserver_, request->password_, sessionhash, avatar_url, error))
        {
            result->message_ = "Failed authentication on avatar export: " + error;
            result->success_ = false;
            return;
        }

        AvatarModule::LogInfo("Authenticated for export");

        std::string export_url = ReplaceSubstring(avatar_url, "/avatar/", "/xmlrpc/");

        try
        {
            // Export avatar
            AvatarModule::LogInfo("Exporting avatar xml");

            XmlRpcEpi call;
            call.Connect(export_url);
            call.CreateCall("StoreAvatarHash");
            call.AddMember("account", request->account_);
            call.AddMember("UserServer", request->authserver_);
            call.AddMember("sessionhash", sessionhash);
            call.AddMember("generic xml", request->avatar_xml_);

            ExportAssetMap::const_iterator i = request->assets_.begin();
            while (i != request->assets_.end())
            {
                //! Here, the hash is the key and asset name is the value
                call.AddMember(i->second.hash_.c_str(), i->first);
                ++i;
            }

            call.Send();

            // Export assets
            bool reexport = false;
            if (call.HasReply("MissingItems"))
            {
                reexport = true;
                AvatarModule::LogInfo("Exporting assets");
                std::vector<std::string> items = call.GetVectorReply<std::string>("MissingItems");
                for (uint i = 0; i < items.size(); ++i)
                {
                    std::string name = items[i];
                    ExportAssetMap::const_iterator asset = request->assets_.find(name);
                    if (asset != request->assets_.end())
                    {
                        // Re-login to get a fresh hash if export has lasted long
                        if (export_timer.elapsed() > REAUTHENTICATION_TIME)
                        {
                            export_timer.restart();
                            std::string temp;
                            if (!LoginToAuthentication(request->account_, request->authserver_, request->password_, sessionhash, temp, error))
                            {
                                result->message_ = "Failed re-authentication on avatar export: " + error;
                                result->success_ = false;
                                return;
                            }
                        }

                        XmlRpcEpi asset_call;
                        asset_call.Connect(export_url);
                        asset_call.CreateCall("StoreItem");
                        asset_call.AddMember("account", request->account_);
                        asset_call.AddMember("UserServer", request->authserver_);
                        asset_call.AddMember("sessionhash", sessionhash);
                        asset_call.AddMember("itemname", name);
                        asset_call.AddMember("hashcode", asset->second.hash_);

                        AvatarModule::LogDebug("Exporting asset " + name + " hash " + asset->second.hash_ + " datasize " + ToString<int>(asset->second.data_.size()));

                        XMLRPC_VectorAppendBase64(asset_call.GetXMLRPCCall()->GetParamList(), "binaries", (const char*)(&asset->second.data_[0]), asset->second.data_.size());

                        asset_call.Send();

                        std::string status = asset_call.GetReply<std::string>("StoreItem");
                        if (status != "succeeded")
                        {
                            result->message_ = "Failed to store asset " + name;
                            result->success_ = false;
                            return;
                        }
                    }
                    else
                    {
                        AvatarModule::LogInfo("Storage requested unknown missing asset " + name);
                    }
                }
            }
            else
            {
                if (call.HasReply("Error"))
                {
                    result->message_ = call.GetReply<std::string>("Error");
                    result->success_ = false;
                    return;
                }
                if (call.HasReply("StoreAvatarHash"))
                {
                    result->message_ = call.GetReply<std::string>("StoreAvatarHash");
                    if (result->message_ != "failed")
                        result->success_ = true;
                    else
                        result->success_ = false;
                    return;
                }
            }

            if (reexport)
            {
                AvatarModule::LogInfo("Re-exporting avatar xml");

                // Re-login to get a fresh hash if export has lasted long
                if (export_timer.elapsed() > REAUTHENTICATION_TIME)
                {
                    export_timer.restart();
                    std::string temp;
                    if (!LoginToAuthentication(request->account_, request->authserver_, request->password_, sessionhash, temp, error))
                    {
                        result->message_ = "Failed re-authentication on avatar export: " + error;
                        result->success_ = false;
                        return;
                    }
                }

                // Re-export avatar after exporting assets
                XmlRpcEpi call;
                call.Connect(export_url);
                call.CreateCall("StoreAvatarHash");
                call.AddMember("account", request->account_);
                call.AddMember("UserServer", request->authserver_);
                call.AddMember("sessionhash", sessionhash);
                call.AddMember("generic xml", request->avatar_xml_);

                ExportAssetMap::const_iterator i = request->assets_.begin();
                while (i != request->assets_.end())
                {
                    call.AddMember(i->second.hash_.c_str(), i->first);
                    ++i;
                }

                call.Send();

                if (call.HasReply("Error"))
                {
                    result->message_ = call.GetReply<std::string>("Error");
                    result->success_ = false;
                    return;
                }
                if (call.HasReply("StoreAvatarHash"))
                {
                    result->message_ = call.GetReply<std::string>("StoreAvatarHash");
                    if (result->message_ != "failed")
                        result->success_ = true;
                    else
                        result->success_ = false;
                    return;
                }
            }
        }
        catch(XmlRpcException& ex)
        {
            result->message_ = ex.what();
            result->success_ = false;
            return;
        }
    }

    bool AvatarExporter::LoginToAuthentication(const std::string& account, const std::string& authserver, const std::string& password, std::string& sessionhash, std::string& avatar_url, std::string& error)
    {
        sessionhash = "";
        avatar_url = "";
        error = "";

        Poco::MD5Engine md5_engine;

        md5_engine.update(password.c_str(), password.size());
        std::string password_hash = "$1$" + md5_engine.digestToHex(md5_engine.digest());

        XmlRpcEpi call;
        try
        {
            call.Connect(authserver);
            call.CreateCall("ClientAuthentication");
            call.AddMember("account", account);
            call.AddMember("passwd", password_hash);
            call.Send();
            if (call.HasReply("sessionHash"))
            {
                sessionhash = call.GetReply<std::string>("sessionHash");
                avatar_url = call.GetReply<std::string>("avatarStorageUrl");
                return true;
            }
            else
            {
                if (call.HasReply("message"))
                    error = call.GetReply<std::string>("message");
                else
                    error = "Login failed";
                return false;
            }
        }
        catch(XmlRpcException& ex)
        {
            error = ex.what();
            return false;
        }

        return true;
    }

    void ExportAsset::CalculateHash()
    {
        Poco::SHA1Engine sha1_engine;
        sha1_engine.update(&data_[0], data_.size());
        const Poco::DigestEngine::Digest& digest = sha1_engine.digest();

        QByteArray bytes((const char*)&digest[0], digest.size());
        QByteArray encoded = bytes.toBase64();
        hash_ = std::string(encoded.constData());
    }
}<commit_msg>Fix AvatarExporter.cpp(277) : warning C4702: unreachable code<commit_after>// For conditions of distribution and use, see copyright notice in license.txt

#include "StableHeaders.h"
#include "AvatarModule.h"
#include "Avatar/AvatarExporter.h"

#include "LLSDUtilities.h"
#include "XmlRpcEpi.h"

#include <Poco/MD5Engine.h>
#include <Poco/SHA1Engine.h>
#include <Poco/Base64Encoder.h>

#include <QByteArray>
#include <QUrl>

using namespace RexTypes;

// Time in which to reauthenticate if export has lasted long, in seconds
static const float REAUTHENTICATION_TIME = 60.0f;

namespace Avatar
{
    AvatarExporter::AvatarExporter() : ThreadTask("AvatarExport")
    {
    }

    void AvatarExporter::Work()
    {
        AvatarExporterResultPtr result(new AvatarExporterResult());

        AvatarExporterRequestPtr request = GetNextRequest<AvatarExporterRequest>();
        if (request)
            ProcessRequest(request, result);
        else
        {
            result->message_ = "No valid export request";
            result->success_ = false;
        }

        SetResult<AvatarExporterResult>(result);
    }

    void AvatarExporter::ProcessRequest(AvatarExporterRequestPtr request, AvatarExporterResultPtr result)
    {
        if (request->avatar_xml_.empty())
        {
            result->message_ = "Empty avatar description";
            result->success_ = false;
            return;
        }

        // Replace < > so that xmlrpc call doesn't get confused
        ReplaceSubstringInplace(request->avatar_xml_, "<", "<");
        ReplaceSubstringInplace(request->avatar_xml_, ">", ">");

        QUrl authserver_url(QString::fromStdString(request->authserver_));
        if (authserver_url.port() == -1)
        {
            authserver_url.setPort(10001);
            request->authserver_ = authserver_url.toString().toStdString();
        }

        // Authenticate first to get an uptodate sessionhash
        boost::timer export_timer; // For checking if we should refresh the hash further on
        std::string sessionhash;
        std::string avatar_url;
        std::string error;
        if (!LoginToAuthentication(request->account_, request->authserver_, request->password_, sessionhash, avatar_url, error))
        {
            result->message_ = "Failed authentication on avatar export: " + error;
            result->success_ = false;
            return;
        }

        AvatarModule::LogInfo("Authenticated for export");

        std::string export_url = ReplaceSubstring(avatar_url, "/avatar/", "/xmlrpc/");

        try
        {
            // Export avatar
            AvatarModule::LogInfo("Exporting avatar xml");

            XmlRpcEpi call;
            call.Connect(export_url);
            call.CreateCall("StoreAvatarHash");
            call.AddMember("account", request->account_);
            call.AddMember("UserServer", request->authserver_);
            call.AddMember("sessionhash", sessionhash);
            call.AddMember("generic xml", request->avatar_xml_);

            ExportAssetMap::const_iterator i = request->assets_.begin();
            while (i != request->assets_.end())
            {
                //! Here, the hash is the key and asset name is the value
                call.AddMember(i->second.hash_.c_str(), i->first);
                ++i;
            }

            call.Send();

            // Export assets
            bool reexport = false;
            if (call.HasReply("MissingItems"))
            {
                reexport = true;
                AvatarModule::LogInfo("Exporting assets");
                std::vector<std::string> items = call.GetVectorReply<std::string>("MissingItems");
                for (uint i = 0; i < items.size(); ++i)
                {
                    std::string name = items[i];
                    ExportAssetMap::const_iterator asset = request->assets_.find(name);
                    if (asset != request->assets_.end())
                    {
                        // Re-login to get a fresh hash if export has lasted long
                        if (export_timer.elapsed() > REAUTHENTICATION_TIME)
                        {
                            export_timer.restart();
                            std::string temp;
                            if (!LoginToAuthentication(request->account_, request->authserver_, request->password_, sessionhash, temp, error))
                            {
                                result->message_ = "Failed re-authentication on avatar export: " + error;
                                result->success_ = false;
                                return;
                            }
                        }

                        XmlRpcEpi asset_call;
                        asset_call.Connect(export_url);
                        asset_call.CreateCall("StoreItem");
                        asset_call.AddMember("account", request->account_);
                        asset_call.AddMember("UserServer", request->authserver_);
                        asset_call.AddMember("sessionhash", sessionhash);
                        asset_call.AddMember("itemname", name);
                        asset_call.AddMember("hashcode", asset->second.hash_);

                        AvatarModule::LogDebug("Exporting asset " + name + " hash " + asset->second.hash_ + " datasize " + ToString<int>(asset->second.data_.size()));

                        XMLRPC_VectorAppendBase64(asset_call.GetXMLRPCCall()->GetParamList(), "binaries", (const char*)(&asset->second.data_[0]), asset->second.data_.size());

                        asset_call.Send();

                        std::string status = asset_call.GetReply<std::string>("StoreItem");
                        if (status != "succeeded")
                        {
                            result->message_ = "Failed to store asset " + name;
                            result->success_ = false;
                            return;
                        }
                    }
                    else
                    {
                        AvatarModule::LogInfo("Storage requested unknown missing asset " + name);
                    }
                }
            }
            else
            {
                if (call.HasReply("Error"))
                {
                    result->message_ = call.GetReply<std::string>("Error");
                    result->success_ = false;
                    return;
                }
                if (call.HasReply("StoreAvatarHash"))
                {
                    result->message_ = call.GetReply<std::string>("StoreAvatarHash");
                    if (result->message_ != "failed")
                        result->success_ = true;
                    else
                        result->success_ = false;
                    return;
                }
            }

            if (reexport)
            {
                AvatarModule::LogInfo("Re-exporting avatar xml");

                // Re-login to get a fresh hash if export has lasted long
                if (export_timer.elapsed() > REAUTHENTICATION_TIME)
                {
                    export_timer.restart();
                    std::string temp;
                    if (!LoginToAuthentication(request->account_, request->authserver_, request->password_, sessionhash, temp, error))
                    {
                        result->message_ = "Failed re-authentication on avatar export: " + error;
                        result->success_ = false;
                        return;
                    }
                }

                // Re-export avatar after exporting assets
                XmlRpcEpi call;
                call.Connect(export_url);
                call.CreateCall("StoreAvatarHash");
                call.AddMember("account", request->account_);
                call.AddMember("UserServer", request->authserver_);
                call.AddMember("sessionhash", sessionhash);
                call.AddMember("generic xml", request->avatar_xml_);

                ExportAssetMap::const_iterator i = request->assets_.begin();
                while (i != request->assets_.end())
                {
                    call.AddMember(i->second.hash_.c_str(), i->first);
                    ++i;
                }

                call.Send();

                if (call.HasReply("Error"))
                {
                    result->message_ = call.GetReply<std::string>("Error");
                    result->success_ = false;
                    return;
                }
                if (call.HasReply("StoreAvatarHash"))
                {
                    result->message_ = call.GetReply<std::string>("StoreAvatarHash");
                    if (result->message_ != "failed")
                        result->success_ = true;
                    else
                        result->success_ = false;
                    return;
                }
            }
        }
        catch(XmlRpcException& ex)
        {
            result->message_ = ex.what();
            result->success_ = false;
            return;
        }
    }

    bool AvatarExporter::LoginToAuthentication(const std::string& account, const std::string& authserver, const std::string& password, std::string& sessionhash, std::string& avatar_url, std::string& error)
    {
        sessionhash = "";
        avatar_url = "";
        error = "";

        Poco::MD5Engine md5_engine;

        md5_engine.update(password.c_str(), password.size());
        std::string password_hash = "$1$" + md5_engine.digestToHex(md5_engine.digest());

        XmlRpcEpi call;
        try
        {
            call.Connect(authserver);
            call.CreateCall("ClientAuthentication");
            call.AddMember("account", account);
            call.AddMember("passwd", password_hash);
            call.Send();
            if (call.HasReply("sessionHash"))
            {
                sessionhash = call.GetReply<std::string>("sessionHash");
                avatar_url = call.GetReply<std::string>("avatarStorageUrl");
                //return true; return at the end of this func
            }
            else
            {
                if (call.HasReply("message"))
                    error = call.GetReply<std::string>("message");
                else
                    error = "Login failed";
                return false;
            }
        }
        catch(XmlRpcException& ex)
        {
            error = ex.what();
            return false;
        }

        return true;
    }

    void ExportAsset::CalculateHash()
    {
        Poco::SHA1Engine sha1_engine;
        sha1_engine.update(&data_[0], data_.size());
        const Poco::DigestEngine::Digest& digest = sha1_engine.digest();

        QByteArray bytes((const char*)&digest[0], digest.size());
        QByteArray encoded = bytes.toBase64();
        hash_ = std::string(encoded.constData());
    }
}
<|endoftext|>


<commit_before>//=======================================================================
// Copyright Baptiste Wicht 2011.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)
//=======================================================================

#include <string>

#include "Options.hpp"
#include "Compiler.hpp"
#include "Utils.hpp"

#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MODULE Eddic Tests
#include <boost/test/unit_test.hpp>

void assertOutputEquals(const std::string& file, const std::string& output){
    eddic::parseOptions(0, {});

    eddic::Compiler compiler;

    int code = compiler.compileOnly("test/cases/" + file);

    BOOST_CHECK_EQUAL (code, 0);

    std::string out = eddic::execCommand("./a.out");

    BOOST_CHECK_EQUAL (output, out);
}

BOOST_AUTO_TEST_CASE( if_ ){
    assertOutputEquals("if.eddi", "Cool");
}

BOOST_AUTO_TEST_CASE( while_ ){
    assertOutputEquals("while.eddi", "01234");
}

BOOST_AUTO_TEST_CASE( for_ ){
    assertOutputEquals("for.eddi", "01234");
}

BOOST_AUTO_TEST_CASE( foreach_ ){
    //assertOutputEquals("foreach.eddi", "01234");
}

BOOST_AUTO_TEST_CASE( globals_ ){
    assertOutputEquals("globals.eddi", "1000a2000aa");
}
<commit_msg>Uncomment test<commit_after>//=======================================================================
// Copyright Baptiste Wicht 2011.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)
//=======================================================================

#include <string>

#include "Options.hpp"
#include "Compiler.hpp"
#include "Utils.hpp"

#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MODULE Eddic Tests
#include <boost/test/unit_test.hpp>

void assertOutputEquals(const std::string& file, const std::string& output){
    eddic::parseOptions(0, {});

    eddic::Compiler compiler;

    int code = compiler.compileOnly("test/cases/" + file);

    BOOST_CHECK_EQUAL (code, 0);

    std::string out = eddic::execCommand("./a.out");

    BOOST_CHECK_EQUAL (output, out);
}

BOOST_AUTO_TEST_CASE( if_ ){
    assertOutputEquals("if.eddi", "Cool");
}

BOOST_AUTO_TEST_CASE( while_ ){
    assertOutputEquals("while.eddi", "01234");
}

BOOST_AUTO_TEST_CASE( for_ ){
    assertOutputEquals("for.eddi", "01234");
}

BOOST_AUTO_TEST_CASE( foreach_ ){
    assertOutputEquals("foreach.eddi", "01234");
}

BOOST_AUTO_TEST_CASE( globals_ ){
    assertOutputEquals("globals.eddi", "1000a2000aa");
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: dpsave.hxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: obo $ $Date: 2004-06-04 13:55:09 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library 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 library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef SC_DPSAVE_HXX
#define SC_DPSAVE_HXX

#ifndef _STRING_HXX //autogen
#include <tools/string.hxx>
#endif

#ifndef _LIST_HXX //autogen wg. List
#include <tools/list.hxx>
#endif

#ifndef _COM_SUN_STAR_SHEET_XDIMENSIONSSUPPLIER_HPP_
#include <com/sun/star/sheet/XDimensionsSupplier.hpp>
#endif

namespace com { namespace sun { namespace star { namespace sheet {
    struct DataPilotFieldReference;
    struct DataPilotFieldSortInfo;
    struct DataPilotFieldAutoShowInfo;
    struct DataPilotFieldLayoutInfo;
} } } }

class SvStream;

// --------------------------------------------------------------------
//
//  classes to save Data Pilot settings
//

class ScDPSaveMember
{
private:
    String      aName;
    USHORT      nVisibleMode;
    USHORT      nShowDetailsMode;

public:
                            ScDPSaveMember(const String& rName);
                            ScDPSaveMember(const ScDPSaveMember& r);
                            ScDPSaveMember(SvStream& rStream);
                            ~ScDPSaveMember();

    BOOL                    operator== ( const ScDPSaveMember& r ) const;

    const String&           GetName() const { return aName; }
    BOOL                    HasIsVisible() const;
    void                    SetIsVisible(BOOL bSet);
    BOOL                    GetIsVisible() const { return BOOL(nVisibleMode); }
    BOOL                    HasShowDetails() const;
    void                    SetShowDetails(BOOL bSet);
    BOOL                    GetShowDetails() const { return BOOL(nShowDetailsMode); }

    void                    WriteToSource( const com::sun::star::uno::Reference<
                                            com::sun::star::uno::XInterface>& xMember );

    void                    Store( SvStream& rStream ) const;
};

class ScDPSaveDimension
{
private:
    String      aName;
    String*     pLayoutName;        // alternative name for layout, not used (yet)
    String*     pSelectedPage;
    BOOL        bIsDataLayout;
    BOOL        bDupFlag;
    USHORT      nOrientation;
    USHORT      nFunction;          // enum GeneralFunction, for data dimensions
    long        nUsedHierarchy;
    USHORT      nShowEmptyMode;     //! at level
    BOOL        bSubTotalDefault;   //! at level
    long        nSubTotalCount;
    USHORT*     pSubTotalFuncs;     // enum GeneralFunction
    ::com::sun::star::sheet::DataPilotFieldReference* pReferenceValue;
    ::com::sun::star::sheet::DataPilotFieldSortInfo*  pSortInfo;            // (level)
    ::com::sun::star::sheet::DataPilotFieldAutoShowInfo* pAutoShowInfo;     // (level)
    ::com::sun::star::sheet::DataPilotFieldLayoutInfo* pLayoutInfo;         // (level)
    List        aMemberList;

public:
                            ScDPSaveDimension(const String& rName, BOOL bDataLayout);
                            ScDPSaveDimension(const ScDPSaveDimension& r);
                            ScDPSaveDimension(SvStream& rStream);
                            ~ScDPSaveDimension();

    BOOL                    operator== ( const ScDPSaveDimension& r ) const;

    const List&             GetMembers() const { return aMemberList; }
    void                    AddMember(ScDPSaveMember* pMember) { aMemberList.Insert(pMember, LIST_APPEND); };

    void                    SetDupFlag(BOOL bSet)   { bDupFlag = bSet; }
    BOOL                    GetDupFlag() const      { return bDupFlag; }

    const String&           GetName() const         { return aName; }
    BOOL                    IsDataLayout() const    { return bIsDataLayout; }

    void                    SetOrientation(USHORT nNew);
    void                    SetSubTotals(BOOL bSet);        // to be removed!
    void                    SetSubTotals(long nCount, const USHORT* pFuncs);
    long                    GetSubTotalsCount() const { return nSubTotalCount; }
    USHORT                  GetSubTotalFunc(long nIndex) const { return pSubTotalFuncs[nIndex]; }
    void                    SetShowEmpty(BOOL bSet);
    BOOL                    GetShowEmpty() const { return BOOL(nShowEmptyMode); }
    void                    SetFunction(USHORT nNew);       // enum GeneralFunction
    USHORT                  GetFunction() const { return nFunction; }
    void                    SetUsedHierarchy(long nNew);
    long                    GetUsedHierarchy() const { return nUsedHierarchy; }
    void                    SetLayoutName(const String* pName);
    const String&           GetLayoutName() const;
    BOOL                    HasLayoutName() const;
    void                    ResetLayoutName();

    const ::com::sun::star::sheet::DataPilotFieldReference* GetReferenceValue() const   { return pReferenceValue; }
    void                    SetReferenceValue(const ::com::sun::star::sheet::DataPilotFieldReference* pNew);

    const ::com::sun::star::sheet::DataPilotFieldSortInfo* GetSortInfo() const          { return pSortInfo; }
    void                    SetSortInfo(const ::com::sun::star::sheet::DataPilotFieldSortInfo* pNew);
    const ::com::sun::star::sheet::DataPilotFieldAutoShowInfo* GetAutoShowInfo() const  { return pAutoShowInfo; }
    void                    SetAutoShowInfo(const ::com::sun::star::sheet::DataPilotFieldAutoShowInfo* pNew);
    const ::com::sun::star::sheet::DataPilotFieldLayoutInfo* GetLayoutInfo() const      { return pLayoutInfo; }
    void                    SetLayoutInfo(const ::com::sun::star::sheet::DataPilotFieldLayoutInfo* pNew);

    void                    SetCurrentPage( const String* pPage );      // NULL = no selection (all)
    BOOL                    HasCurrentPage() const;
    const String&           GetCurrentPage() const;

    USHORT                  GetOrientation() const  { return nOrientation; }

    ScDPSaveMember*         GetExistingMemberByName(const String& rName);
    ScDPSaveMember*         GetMemberByName(const String& rName);

    void                    WriteToSource( const com::sun::star::uno::Reference<
                                            com::sun::star::uno::XInterface>& xDim );

    void                    Store( SvStream& rStream ) const;
};

class ScDPSaveData
{
private:
    List        aDimList;
    USHORT      nColumnGrandMode;
    USHORT      nRowGrandMode;
    USHORT      nIgnoreEmptyMode;
    USHORT      nRepeatEmptyMode;

public:
                            ScDPSaveData();
                            ScDPSaveData(const ScDPSaveData& r);
                            ~ScDPSaveData();

    ScDPSaveData&           operator= ( const ScDPSaveData& r );

    BOOL                    operator== ( const ScDPSaveData& r ) const;

    const List&             GetDimensions() const { return aDimList; }
    void                    AddDimension(ScDPSaveDimension* pDim) { aDimList.Insert(pDim, LIST_APPEND); }

    ScDPSaveDimension*      GetDimensionByName(const String& rName);
    ScDPSaveDimension*      GetDataLayoutDimension();

    ScDPSaveDimension*      DuplicateDimension(const String& rName);
    ScDPSaveDimension&      DuplicateDimension(const ScDPSaveDimension& rDim);

    ScDPSaveDimension*      GetExistingDimensionByName(const String& rName);
    ScDPSaveDimension*      GetNewDimensionByName(const String& rName);

    void                    SetPosition( ScDPSaveDimension* pDim, long nNew );
    void                    SetColumnGrand( BOOL bSet );
    BOOL                    GetColumnGrand() const { return BOOL(nColumnGrandMode); }
    void                    SetRowGrand( BOOL bSet );
    BOOL                    GetRowGrand() const { return BOOL(nRowGrandMode); }
    void                    SetIgnoreEmptyRows( BOOL bSet );
    BOOL                    GetIgnoreEmptyRows() const { return BOOL(nIgnoreEmptyMode); }
    void                    SetRepeatIfEmpty( BOOL bSet );
    BOOL                    GetRepeatIfEmpty() const { return BOOL(nRepeatEmptyMode); }

    void                    WriteToSource( const com::sun::star::uno::Reference<
                                            com::sun::star::sheet::XDimensionsSupplier>& xSource );

    void                    Store( SvStream& rStream ) const;
    void                    Load( SvStream& rStream );

    BOOL                    IsEmpty() const;
};

#endif

<commit_msg>INTEGRATION: CWS tableoptions (1.4.34); FILE MERGED 2004/07/05 17:06:53 nn 1.4.34.1: #i25111# table options, drill to details<commit_after>/*************************************************************************
 *
 *  $RCSfile: dpsave.hxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: hr $ $Date: 2004-07-23 12:51:46 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library 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 library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef SC_DPSAVE_HXX
#define SC_DPSAVE_HXX

#ifndef _STRING_HXX //autogen
#include <tools/string.hxx>
#endif

#ifndef _LIST_HXX //autogen wg. List
#include <tools/list.hxx>
#endif

#ifndef _COM_SUN_STAR_SHEET_XDIMENSIONSSUPPLIER_HPP_
#include <com/sun/star/sheet/XDimensionsSupplier.hpp>
#endif

namespace com { namespace sun { namespace star { namespace sheet {
    struct DataPilotFieldReference;
    struct DataPilotFieldSortInfo;
    struct DataPilotFieldAutoShowInfo;
    struct DataPilotFieldLayoutInfo;
} } } }

class SvStream;

// --------------------------------------------------------------------
//
//  classes to save Data Pilot settings
//

class ScDPSaveMember
{
private:
    String      aName;
    USHORT      nVisibleMode;
    USHORT      nShowDetailsMode;

public:
                            ScDPSaveMember(const String& rName);
                            ScDPSaveMember(const ScDPSaveMember& r);
                            ScDPSaveMember(SvStream& rStream);
                            ~ScDPSaveMember();

    BOOL                    operator== ( const ScDPSaveMember& r ) const;

    const String&           GetName() const { return aName; }
    BOOL                    HasIsVisible() const;
    void                    SetIsVisible(BOOL bSet);
    BOOL                    GetIsVisible() const { return BOOL(nVisibleMode); }
    BOOL                    HasShowDetails() const;
    void                    SetShowDetails(BOOL bSet);
    BOOL                    GetShowDetails() const { return BOOL(nShowDetailsMode); }

    void                    WriteToSource( const com::sun::star::uno::Reference<
                                            com::sun::star::uno::XInterface>& xMember );

    void                    Store( SvStream& rStream ) const;
};

class ScDPSaveDimension
{
private:
    String      aName;
    String*     pLayoutName;        // alternative name for layout, not used (yet)
    String*     pSelectedPage;
    BOOL        bIsDataLayout;
    BOOL        bDupFlag;
    USHORT      nOrientation;
    USHORT      nFunction;          // enum GeneralFunction, for data dimensions
    long        nUsedHierarchy;
    USHORT      nShowEmptyMode;     //! at level
    BOOL        bSubTotalDefault;   //! at level
    long        nSubTotalCount;
    USHORT*     pSubTotalFuncs;     // enum GeneralFunction
    ::com::sun::star::sheet::DataPilotFieldReference* pReferenceValue;
    ::com::sun::star::sheet::DataPilotFieldSortInfo*  pSortInfo;            // (level)
    ::com::sun::star::sheet::DataPilotFieldAutoShowInfo* pAutoShowInfo;     // (level)
    ::com::sun::star::sheet::DataPilotFieldLayoutInfo* pLayoutInfo;         // (level)
    List        aMemberList;

public:
                            ScDPSaveDimension(const String& rName, BOOL bDataLayout);
                            ScDPSaveDimension(const ScDPSaveDimension& r);
                            ScDPSaveDimension(SvStream& rStream);
                            ~ScDPSaveDimension();

    BOOL                    operator== ( const ScDPSaveDimension& r ) const;

    const List&             GetMembers() const { return aMemberList; }
    void                    AddMember(ScDPSaveMember* pMember) { aMemberList.Insert(pMember, LIST_APPEND); };

    void                    SetDupFlag(BOOL bSet)   { bDupFlag = bSet; }
    BOOL                    GetDupFlag() const      { return bDupFlag; }

    const String&           GetName() const         { return aName; }
    BOOL                    IsDataLayout() const    { return bIsDataLayout; }

    void                    SetOrientation(USHORT nNew);
    void                    SetSubTotals(BOOL bSet);        // to be removed!
    void                    SetSubTotals(long nCount, const USHORT* pFuncs);
    long                    GetSubTotalsCount() const { return nSubTotalCount; }
    USHORT                  GetSubTotalFunc(long nIndex) const { return pSubTotalFuncs[nIndex]; }
    void                    SetShowEmpty(BOOL bSet);
    BOOL                    GetShowEmpty() const { return BOOL(nShowEmptyMode); }
    void                    SetFunction(USHORT nNew);       // enum GeneralFunction
    USHORT                  GetFunction() const { return nFunction; }
    void                    SetUsedHierarchy(long nNew);
    long                    GetUsedHierarchy() const { return nUsedHierarchy; }
    void                    SetLayoutName(const String* pName);
    const String&           GetLayoutName() const;
    BOOL                    HasLayoutName() const;
    void                    ResetLayoutName();

    const ::com::sun::star::sheet::DataPilotFieldReference* GetReferenceValue() const   { return pReferenceValue; }
    void                    SetReferenceValue(const ::com::sun::star::sheet::DataPilotFieldReference* pNew);

    const ::com::sun::star::sheet::DataPilotFieldSortInfo* GetSortInfo() const          { return pSortInfo; }
    void                    SetSortInfo(const ::com::sun::star::sheet::DataPilotFieldSortInfo* pNew);
    const ::com::sun::star::sheet::DataPilotFieldAutoShowInfo* GetAutoShowInfo() const  { return pAutoShowInfo; }
    void                    SetAutoShowInfo(const ::com::sun::star::sheet::DataPilotFieldAutoShowInfo* pNew);
    const ::com::sun::star::sheet::DataPilotFieldLayoutInfo* GetLayoutInfo() const      { return pLayoutInfo; }
    void                    SetLayoutInfo(const ::com::sun::star::sheet::DataPilotFieldLayoutInfo* pNew);

    void                    SetCurrentPage( const String* pPage );      // NULL = no selection (all)
    BOOL                    HasCurrentPage() const;
    const String&           GetCurrentPage() const;

    USHORT                  GetOrientation() const  { return nOrientation; }

    ScDPSaveMember*         GetExistingMemberByName(const String& rName);
    ScDPSaveMember*         GetMemberByName(const String& rName);

    void                    WriteToSource( const com::sun::star::uno::Reference<
                                            com::sun::star::uno::XInterface>& xDim );

    void                    Store( SvStream& rStream ) const;
};

class ScDPSaveData
{
private:
    List        aDimList;
    USHORT      nColumnGrandMode;
    USHORT      nRowGrandMode;
    USHORT      nIgnoreEmptyMode;
    USHORT      nRepeatEmptyMode;
    BOOL        bFilterButton;      // not passed to DataPilotSource
    BOOL        bDrillDown;         // not passed to DataPilotSource

public:
                            ScDPSaveData();
                            ScDPSaveData(const ScDPSaveData& r);
                            ~ScDPSaveData();

    ScDPSaveData&           operator= ( const ScDPSaveData& r );

    BOOL                    operator== ( const ScDPSaveData& r ) const;

    const List&             GetDimensions() const { return aDimList; }
    void                    AddDimension(ScDPSaveDimension* pDim) { aDimList.Insert(pDim, LIST_APPEND); }

    ScDPSaveDimension*      GetDimensionByName(const String& rName);
    ScDPSaveDimension*      GetDataLayoutDimension();

    ScDPSaveDimension*      DuplicateDimension(const String& rName);
    ScDPSaveDimension&      DuplicateDimension(const ScDPSaveDimension& rDim);

    ScDPSaveDimension*      GetExistingDimensionByName(const String& rName);
    ScDPSaveDimension*      GetNewDimensionByName(const String& rName);

    ScDPSaveDimension*      GetInnermostDimension(USHORT nOrientation);
    long                    GetDataDimensionCount() const;

    void                    SetPosition( ScDPSaveDimension* pDim, long nNew );
    void                    SetColumnGrand( BOOL bSet );
    BOOL                    GetColumnGrand() const { return BOOL(nColumnGrandMode); }
    void                    SetRowGrand( BOOL bSet );
    BOOL                    GetRowGrand() const { return BOOL(nRowGrandMode); }
    void                    SetIgnoreEmptyRows( BOOL bSet );
    BOOL                    GetIgnoreEmptyRows() const { return BOOL(nIgnoreEmptyMode); }
    void                    SetRepeatIfEmpty( BOOL bSet );
    BOOL                    GetRepeatIfEmpty() const { return BOOL(nRepeatEmptyMode); }

    void                    SetFilterButton( BOOL bSet );
    BOOL                    GetFilterButton() const { return bFilterButton; }
    void                    SetDrillDown( BOOL bSet );
    BOOL                    GetDrillDown() const { return bDrillDown; }

    void                    WriteToSource( const com::sun::star::uno::Reference<
                                            com::sun::star::sheet::XDimensionsSupplier>& xSource );

    void                    Store( SvStream& rStream ) const;
    void                    Load( SvStream& rStream );

    BOOL                    IsEmpty() const;
};

#endif

<|endoftext|>


<commit_before>// ======================================================================
/*!
 * \file
 * \brief Regression tests for class NFmiAreaFactory
 */
// ======================================================================

#include "NFmiGdalArea.h"

#include <boost/lexical_cast.hpp>
#include <regression/tframe.h>
#include <stdexcept>
#include <string>

std::string tostr(const NFmiPoint& p)
{
  std::ostringstream out;
  out << std::fixed << "(" << p.X() << "," << p.Y() << ")";
  return out.str();
}

//! Protection against conflicts with global functions
namespace NFmiAreaFactoryTest
{
// ----------------------------------------------------------------------

void create()
{
  {
    // WGS84
    NFmiGdalArea area("FMI", "EPSG:4326", NFmiPoint(20, 60), NFmiPoint(40, 70));
  }

  {
    // YKJ
    NFmiGdalArea area("FMI", "EPSG:2393", NFmiPoint(20, 60), NFmiPoint(40, 70));
  }

  TEST_PASSED();
}

// ----------------------------------------------------------------------

void areastr()
{
  NFmiGdalArea area("FMI", "EPSG:2393", NFmiPoint(20, 60), NFmiPoint(40, 70));

  std::string expected = "FMI:EPSG:2393|20,60,40,70";

  std::string result = area.AreaStr();
  if (result != expected) TEST_FAILED("Expected " + expected + ", got " + result + " instead");

  TEST_PASSED();
}

// ----------------------------------------------------------------------

void wkt()
{
  NFmiGdalArea area("FMI", "EPSG:2393", NFmiPoint(20, 60), NFmiPoint(40, 70));

  std::string expected =
      "PROJCS[\"KKJ / Finland Uniform Coordinate "
      "System\",GEOGCS[\"KKJ\",DATUM[\"Kartastokoordinaattijarjestelma_1966\",SPHEROID["
      "\"International "
      "1924\",6378388,297,AUTHORITY[\"EPSG\",\"7022\"]],TOWGS84[-96.062,-82.428,-121.753,4.801,0."
      "345,-1.376,1.496],AUTHORITY[\"EPSG\",\"6123\"]],PRIMEM[\"Greenwich\",0,AUTHORITY[\"EPSG\","
      "\"8901\"]],UNIT[\"degree\",0.0174532925199433,AUTHORITY[\"EPSG\",\"9122\"]],AUTHORITY["
      "\"EPSG\",\"4123\"]],PROJECTION[\"Transverse_Mercator\"],PARAMETER[\"latitude_of_origin\",0],"
      "PARAMETER[\"central_meridian\",27],PARAMETER[\"scale_factor\",1],PARAMETER[\"false_"
      "easting\",3500000],PARAMETER[\"false_northing\",0],UNIT[\"metre\",1,AUTHORITY[\"EPSG\","
      "\"9001\"]],AUTHORITY[\"EPSG\",\"2393\"]]";

  std::string result = area.WKT();
  if (result != expected) TEST_FAILED("Expected " + expected + ", got " + result + " instead");

  TEST_PASSED();
}

// ----------------------------------------------------------------------

void tolatlon()
{
  // YKJ
  NFmiGdalArea area("FMI", "EPSG:2393", NFmiPoint(20, 60), NFmiPoint(40, 70));

  {
    NFmiPoint xy = NFmiPoint(1, 0);
    NFmiPoint expect = NFmiPoint(40, 70);
    NFmiPoint latlon = area.ToLatLon(xy);
    if (expect.Distance(latlon) > 1)  // degrees
      TEST_FAILED("Failed to project " + tostr(xy) + " to " + tostr(expect) + ", got " +
                  tostr(latlon) + " instead");
  }

  {
    NFmiPoint xy = NFmiPoint(0, 1);
    NFmiPoint expect = NFmiPoint(20, 60);
    NFmiPoint latlon = area.ToLatLon(xy);
    if (expect.Distance(latlon) > 1)  // degrees
      TEST_FAILED("Failed to project " + tostr(xy) + " to " + tostr(expect) + ", got " +
                  tostr(latlon) + " instead");
  }

  TEST_PASSED();
}

// ----------------------------------------------------------------------

void toxy()
{
  // YKJ
  NFmiGdalArea area("FMI", "EPSG:2393", NFmiPoint(20, 60), NFmiPoint(40, 70));

  {
    NFmiPoint expect = NFmiPoint(1, 0);
    NFmiPoint latlon = NFmiPoint(40, 70);
    NFmiPoint xy = area.ToXY(latlon);
    if (expect.Distance(xy) > 0.01)  // xy-units
      TEST_FAILED("Failed to project " + tostr(latlon) + " to " + tostr(expect) + ", got " +
                  tostr(xy) + " instead");
  }

  {
    NFmiPoint expect = NFmiPoint(0, 1);
    NFmiPoint latlon = NFmiPoint(20, 60);
    NFmiPoint xy = area.ToXY(latlon);
    if (expect.Distance(xy) > 0.01)  // xy-units
      TEST_FAILED("Failed to project " + tostr(latlon) + " to " + tostr(expect) + ", got " +
                  tostr(xy) + " instead");
  }

  TEST_PASSED();
}

// ----------------------------------------------------------------------

void latlontoworldxy()
{
  // YKJ
  NFmiGdalArea area("FMI", "EPSG:2393", NFmiPoint(20, 60), NFmiPoint(40, 70));

  NFmiPoint expect = NFmiPoint(3388405, 6655915);
  NFmiPoint xy = area.LatLonToWorldXY(NFmiPoint(25, 60));
  if (expect.Distance(xy) > 1)  // meters
    TEST_FAILED("Failed to project 25,60 to " + tostr(expect) + ", got " + tostr(xy) + " instead");

  TEST_PASSED();
}

// ----------------------------------------------------------------------

void worldxytolatlon()
{
  // YKJ
  NFmiGdalArea area("FMI", "EPSG:2393", NFmiPoint(20, 60), NFmiPoint(40, 70));

  NFmiPoint wxy = NFmiPoint(3388888, 6655555);
  NFmiPoint expect = NFmiPoint(25, 60);
  NFmiPoint xy = area.WorldXYToLatLon(wxy);
  if (expect.Distance(xy) > 0.01)  // degrees
    TEST_FAILED("Failed to project " + tostr(wxy) + " to " + tostr(expect) + ", got " + tostr(xy) +
                " instead");

  TEST_PASSED();
}

// ----------------------------------------------------------------------

void worldxyheight()
{
  {
    // YKJ
    NFmiGdalArea area("FMI", "EPSG:2393", NFmiPoint(20, 60), NFmiPoint(40, 70));
    double h = std::round(area.WorldXYHeight() / 1000.0);
    if (h != 1147)
      TEST_FAILED("YKJ height should be 1147 km, got " + boost::lexical_cast<std::string>(h));
  }
  {
    NFmiGdalArea area("FMI", "WGS84", NFmiPoint(20, 60), NFmiPoint(40, 70));
    double h = std::round(area.WorldXYHeight() / 1000.0);
    if (h != 1112)
      TEST_FAILED("WGS84 height should be 1112, got " + boost::lexical_cast<std::string>(h));
  }

  TEST_PASSED();
}

// ----------------------------------------------------------------------

void worldxywidth()
{
  {
    // YKJ
    NFmiGdalArea area("FMI", "EPSG:2393", NFmiPoint(20, 60), NFmiPoint(40, 70));
    int h = std::round(area.WorldXYWidth() / 1000.0);
    if (h != 883)
      TEST_FAILED("YKJ width should be 883, got " + boost::lexical_cast<std::string>(h));
  }
  {
    NFmiGdalArea area("FMI", "WGS84", NFmiPoint(20, 60), NFmiPoint(40, 70));
    int h = std::round(area.WorldXYWidth() / 1000.0);
    if (h != 940)
      TEST_FAILED("WGS84 width should be 940, got " + boost::lexical_cast<std::string>(h));
  }

  TEST_PASSED();
}

// ----------------------------------------------------------------------
/*!
 * The actual test suite
 */
// ----------------------------------------------------------------------

class tests : public tframe::tests
{
  virtual const char* error_message_prefix() const { return "\n\t"; }
  void test(void)
  {
    TEST(create);
    TEST(areastr);
    TEST(wkt);
    TEST(tolatlon);
    TEST(toxy);
    TEST(latlontoworldxy);
    TEST(worldxytolatlon);
    TEST(worldxyheight);
    TEST(worldxywidth);
  }
};

}  // namespace NFmiAreaFactoryTest

//! The main program
int main(void)
{
  using namespace std;
  cout << endl << "NFmiGdalArea tester" << endl << "===================" << endl;
  NFmiAreaFactoryTest::tests t;
  return t.run();
}

// ======================================================================
<commit_msg>[tests] NFmiGdalAreaTest.cpp: disable some tests for GDAL 3+<commit_after>// ======================================================================
/*!
 * \file
 * \brief Regression tests for class NFmiAreaFactory
 */
// ======================================================================

#include "NFmiGdalArea.h"

#include <boost/lexical_cast.hpp>
#include <regression/tframe.h>
#include <stdexcept>
#include <string>
#include <gdal_version.h>

std::string tostr(const NFmiPoint& p)
{
  std::ostringstream out;
  out << std::fixed << "(" << p.X() << "," << p.Y() << ")";
  return out.str();
}

//! Protection against conflicts with global functions
namespace NFmiAreaFactoryTest
{
// ----------------------------------------------------------------------

void create()
{
  {
    // WGS84
    NFmiGdalArea area("FMI", "EPSG:4326", NFmiPoint(20, 60), NFmiPoint(40, 70));
  }

  {
    // YKJ
    NFmiGdalArea area("FMI", "EPSG:2393", NFmiPoint(20, 60), NFmiPoint(40, 70));
  }

  TEST_PASSED();
}

// ----------------------------------------------------------------------

void areastr()
{
  NFmiGdalArea area("FMI", "EPSG:2393", NFmiPoint(20, 60), NFmiPoint(40, 70));

  std::string expected = "FMI:EPSG:2393|20,60,40,70";

  std::string result = area.AreaStr();
  if (result != expected) TEST_FAILED("Expected " + expected + ", got " + result + " instead");

  TEST_PASSED();
}

// ----------------------------------------------------------------------

void wkt()
{
  NFmiGdalArea area("FMI", "EPSG:2393", NFmiPoint(20, 60), NFmiPoint(40, 70));

  std::string expected =
      "PROJCS[\"KKJ / Finland Uniform Coordinate "
      "System\",GEOGCS[\"KKJ\",DATUM[\"Kartastokoordinaattijarjestelma_1966\",SPHEROID["
      "\"International "
      "1924\",6378388,297,AUTHORITY[\"EPSG\",\"7022\"]],TOWGS84[-96.062,-82.428,-121.753,4.801,0."
      "345,-1.376,1.496],AUTHORITY[\"EPSG\",\"6123\"]],PRIMEM[\"Greenwich\",0,AUTHORITY[\"EPSG\","
      "\"8901\"]],UNIT[\"degree\",0.0174532925199433,AUTHORITY[\"EPSG\",\"9122\"]],AUTHORITY["
      "\"EPSG\",\"4123\"]],PROJECTION[\"Transverse_Mercator\"],PARAMETER[\"latitude_of_origin\",0],"
      "PARAMETER[\"central_meridian\",27],PARAMETER[\"scale_factor\",1],PARAMETER[\"false_"
      "easting\",3500000],PARAMETER[\"false_northing\",0],UNIT[\"metre\",1,AUTHORITY[\"EPSG\","
      "\"9001\"]],AUTHORITY[\"EPSG\",\"2393\"]]";

  std::string result = area.WKT();
  if (result != expected) TEST_FAILED("Expected " + expected + ", got " + result + " instead");

  TEST_PASSED();
}

// ----------------------------------------------------------------------

void tolatlon()
{
  // YKJ
  NFmiGdalArea area("FMI", "EPSG:2393", NFmiPoint(20, 60), NFmiPoint(40, 70));

  {
    NFmiPoint xy = NFmiPoint(1, 0);
    NFmiPoint expect = NFmiPoint(40, 70);
    NFmiPoint latlon = area.ToLatLon(xy);
    if (expect.Distance(latlon) > 1)  // degrees
      TEST_FAILED("Failed to project " + tostr(xy) + " to " + tostr(expect) + ", got " +
                  tostr(latlon) + " instead");
  }

  {
    NFmiPoint xy = NFmiPoint(0, 1);
    NFmiPoint expect = NFmiPoint(20, 60);
    NFmiPoint latlon = area.ToLatLon(xy);
    if (expect.Distance(latlon) > 1)  // degrees
      TEST_FAILED("Failed to project " + tostr(xy) + " to " + tostr(expect) + ", got " +
                  tostr(latlon) + " instead");
  }

  TEST_PASSED();
}

// ----------------------------------------------------------------------

void toxy()
{
  // YKJ
  NFmiGdalArea area("FMI", "EPSG:2393", NFmiPoint(20, 60), NFmiPoint(40, 70));

  {
    NFmiPoint expect = NFmiPoint(1, 0);
    NFmiPoint latlon = NFmiPoint(40, 70);
    NFmiPoint xy = area.ToXY(latlon);
    if (expect.Distance(xy) > 0.01)  // xy-units
      TEST_FAILED("Failed to project " + tostr(latlon) + " to " + tostr(expect) + ", got " +
                  tostr(xy) + " instead");
  }

  {
    NFmiPoint expect = NFmiPoint(0, 1);
    NFmiPoint latlon = NFmiPoint(20, 60);
    NFmiPoint xy = area.ToXY(latlon);
    if (expect.Distance(xy) > 0.01)  // xy-units
      TEST_FAILED("Failed to project " + tostr(latlon) + " to " + tostr(expect) + ", got " +
                  tostr(xy) + " instead");
  }

  TEST_PASSED();
}

// ----------------------------------------------------------------------

void latlontoworldxy()
{
  // YKJ
  NFmiGdalArea area("FMI", "EPSG:2393", NFmiPoint(20, 60), NFmiPoint(40, 70));

  NFmiPoint expect = NFmiPoint(3388405, 6655915);
  NFmiPoint xy = area.LatLonToWorldXY(NFmiPoint(25, 60));
  if (expect.Distance(xy) > 1)  // meters
    TEST_FAILED("Failed to project 25,60 to " + tostr(expect) + ", got " + tostr(xy) + " instead");

  TEST_PASSED();
}

// ----------------------------------------------------------------------

void worldxytolatlon()
{
  // YKJ
  NFmiGdalArea area("FMI", "EPSG:2393", NFmiPoint(20, 60), NFmiPoint(40, 70));

  NFmiPoint wxy = NFmiPoint(3388888, 6655555);
  NFmiPoint expect = NFmiPoint(25, 60);
  NFmiPoint xy = area.WorldXYToLatLon(wxy);
  if (expect.Distance(xy) > 0.01)  // degrees
    TEST_FAILED("Failed to project " + tostr(wxy) + " to " + tostr(expect) + ", got " + tostr(xy) +
                " instead");

  TEST_PASSED();
}

// ----------------------------------------------------------------------

void worldxyheight()
{
  {
    // YKJ
    NFmiGdalArea area("FMI", "EPSG:2393", NFmiPoint(20, 60), NFmiPoint(40, 70));
    double h = std::round(area.WorldXYHeight() / 1000.0);
    if (h != 1147)
      TEST_FAILED("YKJ height should be 1147 km, got " + boost::lexical_cast<std::string>(h));
  }
  {
    NFmiGdalArea area("FMI", "WGS84", NFmiPoint(20, 60), NFmiPoint(40, 70));
    double h = std::round(area.WorldXYHeight() / 1000.0);
    if (h != 1112)
      TEST_FAILED("WGS84 height should be 1112, got " + boost::lexical_cast<std::string>(h));
  }

  TEST_PASSED();
}

// ----------------------------------------------------------------------

void worldxywidth()
{
  {
    // YKJ
    NFmiGdalArea area("FMI", "EPSG:2393", NFmiPoint(20, 60), NFmiPoint(40, 70));
    int h = std::round(area.WorldXYWidth() / 1000.0);
    if (h != 883)
      TEST_FAILED("YKJ width should be 883, got " + boost::lexical_cast<std::string>(h));
  }
  {
    NFmiGdalArea area("FMI", "WGS84", NFmiPoint(20, 60), NFmiPoint(40, 70));
    int h = std::round(area.WorldXYWidth() / 1000.0);
    if (h != 940)
      TEST_FAILED("WGS84 width should be 940, got " + boost::lexical_cast<std::string>(h));
  }

  TEST_PASSED();
}

// ----------------------------------------------------------------------
/*!
 * The actual test suite
 */
// ----------------------------------------------------------------------

class tests : public tframe::tests
{
  virtual const char* error_message_prefix() const { return "\n\t"; }
  void test(void)
  {
    TEST(create);
    TEST(areastr);
    TEST(tolatlon);
    TEST(toxy);
#if GDAL_VERSION_MAJOR < 3
    TEST(wkt);
    TEST(latlontoworldxy);
    TEST(worldxytolatlon);
    TEST(worldxyheight);
    TEST(worldxywidth);
#endif
  }
};

}  // namespace NFmiAreaFactoryTest

//! The main program
int main(void)
{
  using namespace std;
  cout << endl << "NFmiGdalArea tester" << endl << "===================" << endl;
  NFmiAreaFactoryTest::tests t;
  return t.run();
}

// ======================================================================
<|endoftext|>


<commit_before>#include "SpriteEntity.h"

#include "../scenes/game_scene.h"

SpriteEntity::SpriteEntity(const char *spriteName)
	:	pszSpriteName(spriteName)
	,	pSprite(NULL)

{
	SEED_ASSERT(spriteName);
}

SpriteEntity::~SpriteEntity()
{
	pInput->RemoveKeyboardListener(this);
	Delete(pSprite);
}

void SpriteEntity::Load(Seed::IMetadataObject &metadata, Seed::SceneNode *sprites)
{
    strName = metadata.GetProperty("Class");

	pSprite = New(Sprite(*static_cast<Sprite *>(sprites->GetChildByName(pszSpriteName))));
    pSprite->SetPosition(metadata.GetPosition());

	gScene->Add(pSprite);

	fVelocity = 5.0f;
	vPlayerVectorDirection = VECTOR_ZERO;

	pInput->AddKeyboardListener(this);
}

void SpriteEntity::OnInputKeyboardPress(const EventInputKeyboard *ev)
{
	Key k = ev->GetKey();

	if (k == Seed::KeyUp)
	{
		// Sum the normalized vector up with the current vector
		vPlayerVectorDirection += VECTOR_UP;
	}

	if (k == Seed::KeyLeft)
	{
		// Sum the normalized vector left with the current vector
		vPlayerVectorDirection += VECTOR_LEFT;

		// Change the scale to turn the player sprite
		if (pSprite->GetScaleX() < 0)
			pSprite->SetScaleX(pSprite->GetScaleX() * -1);
	}

	if (k == Seed::KeyRight)
	{
		// Sum the normalized vector right with the current vector
		vPlayerVectorDirection += VECTOR_RIGHT;

		// Change the scale to turn the player sprite
		if (pSprite->GetScaleX() > 0)
			pSprite->SetScaleX(pSprite->GetScaleX() * -1);
	}

	if (k == Seed::KeyDown)
	{
		// Sum the normalized vector down with the current vector
		vPlayerVectorDirection += VECTOR_DOWN;
	}

	pSprite->AddPosition(vPlayerVectorDirection * fVelocity);
}

void SpriteEntity::OnInputKeyboardRelease(const EventInputKeyboard *ev)
{
	Key k = ev->GetKey();

	// Remove the directions
	if (k == Seed::KeyUp)
	{
		vPlayerVectorDirection -= VECTOR_UP;
	}

	if (k == Seed::KeyLeft)
	{
		vPlayerVectorDirection -= VECTOR_LEFT;
	}

	if (k == Seed::KeyRight)
	{
		vPlayerVectorDirection -= VECTOR_RIGHT;
	}

	if (k == Seed::KeyDown)
	{
		vPlayerVectorDirection -= VECTOR_DOWN;
	}

	if (k == Seed::KeyEscape)
		pSystem->Shutdown();
}

<commit_msg>Added WASD as a input too.<commit_after>#include "SpriteEntity.h"

#include "../scenes/game_scene.h"

SpriteEntity::SpriteEntity(const char *spriteName)
	:	pszSpriteName(spriteName)
	,	pSprite(NULL)

{
	SEED_ASSERT(spriteName);
}

SpriteEntity::~SpriteEntity()
{
	pInput->RemoveKeyboardListener(this);
	Delete(pSprite);
}

void SpriteEntity::Load(Seed::IMetadataObject &metadata, Seed::SceneNode *sprites)
{
	strName = metadata.GetProperty("Class");

	pSprite = New(Sprite(*static_cast<Sprite *>(sprites->GetChildByName(pszSpriteName))));
	pSprite->SetPosition(metadata.GetPosition());

	gScene->Add(pSprite);

	fVelocity = 5.0f;
	vPlayerVectorDirection = VECTOR_ZERO;

	pInput->AddKeyboardListener(this);
}

void SpriteEntity::OnInputKeyboardPress(const EventInputKeyboard *ev)
{
	Key k = ev->GetKey();

	if (k == Seed::KeyUp || k == Seed::KeyW)
	{
		// Sum the normalized vector up with the current vector
		vPlayerVectorDirection += VECTOR_UP;
	}

	if (k == Seed::KeyLeft || k == Seed::KeyA)
	{
		// Sum the normalized vector left with the current vector
		vPlayerVectorDirection += VECTOR_LEFT;

		// Change the scale to turn the player sprite
		if (pSprite->GetScaleX() > 0)
			pSprite->SetScaleX(pSprite->GetScaleX() * -1);
	}

	if (k == Seed::KeyRight || k == Seed::KeyD)
	{
		// Sum the normalized vector right with the current vector
		vPlayerVectorDirection += VECTOR_RIGHT;

		// Change the scale to turn the player sprite
		if (pSprite->GetScaleX() < 0)
			pSprite->SetScaleX(pSprite->GetScaleX() * -1);
	}

	if (k == Seed::KeyDown || k == Seed::KeyS)
	{
		// Sum the normalized vector down with the current vector
		vPlayerVectorDirection += VECTOR_DOWN;
	}

	pSprite->AddPosition(vPlayerVectorDirection * fVelocity);
}

void SpriteEntity::OnInputKeyboardRelease(const EventInputKeyboard *ev)
{
	Key k = ev->GetKey();

	// Remove the directions
	if (k == Seed::KeyUp)
	{
		vPlayerVectorDirection -= VECTOR_UP;
	}

	if (k == Seed::KeyLeft)
	{
		vPlayerVectorDirection -= VECTOR_LEFT;
	}

	if (k == Seed::KeyRight)
	{
		vPlayerVectorDirection -= VECTOR_RIGHT;
	}

	if (k == Seed::KeyDown)
	{
		vPlayerVectorDirection -= VECTOR_DOWN;
	}

	if (k == Seed::KeyEscape)
		pSystem->Shutdown();
}

<|endoftext|>


<commit_before>//===-LTOModule.cpp - LLVM Link Time Optimizer ----------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the Link Time Optimization library. This library is
// intended to be used by linker to optimize code at link time.
//
//===----------------------------------------------------------------------===//

#include "LTOModule.h"

#include "llvm/Module.h"
#include "llvm/ModuleProvider.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/Bitcode/ReaderWriter.h"
#include "llvm/Support/SystemUtils.h"
#include "llvm/Support/Mangler.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/System/Path.h"
#include "llvm/System/Process.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetMachineRegistry.h"
#include "llvm/Target/TargetAsmInfo.h"

#include <fstream>

using namespace llvm;

bool LTOModule::isBitcodeFile(const void* mem, size_t length)
{
    return ( llvm::sys::IdentifyFileType((char*)mem, length)
                                            == llvm::sys::Bitcode_FileType );
}

bool LTOModule::isBitcodeFile(const char* path)
{
    return llvm::sys::Path(path).isBitcodeFile();
}

bool LTOModule::isBitcodeFileForTarget(const void* mem, size_t length,
                                       const char* triplePrefix)
{
    MemoryBuffer* buffer = makeBuffer(mem, length);
    if ( buffer == NULL )
        return false;
    return isTargetMatch(buffer, triplePrefix);
}

bool LTOModule::isBitcodeFileForTarget(const char* path,
                                       const char* triplePrefix)
{
    MemoryBuffer *buffer = MemoryBuffer::getFile(path);
    if (buffer == NULL)
        return false;
    return isTargetMatch(buffer, triplePrefix);
}

// takes ownership of buffer
bool LTOModule::isTargetMatch(MemoryBuffer* buffer, const char* triplePrefix)
{
    OwningPtr<ModuleProvider> mp(getBitcodeModuleProvider(buffer));
    // on success, mp owns buffer and both are deleted at end of this method
    if ( !mp ) {
        delete buffer;
        return false;
    }
    std::string actualTarget = mp->getModule()->getTargetTriple();
    return ( strncmp(actualTarget.c_str(), triplePrefix,
                    strlen(triplePrefix)) == 0);
}

LTOModule::LTOModule(Module* m, TargetMachine* t)
 : _module(m), _target(t), _symbolsParsed(false)
{
}

LTOModule* LTOModule::makeLTOModule(const char* path, std::string& errMsg)
{
    OwningPtr<MemoryBuffer> buffer(MemoryBuffer::getFile(path, &errMsg));
    if ( !buffer )
        return NULL;
    return makeLTOModule(buffer.get(), errMsg);
}

/// makeBuffer - create a MemoryBuffer from a memory range.
/// MemoryBuffer requires the byte past end of the buffer to be a zero.
/// We might get lucky and already be that way, otherwise make a copy.
/// Also if next byte is on a different page, don't assume it is readable.
MemoryBuffer* LTOModule::makeBuffer(const void* mem, size_t length)
{
	const char* startPtr = (char*)mem;
	const char* endPtr = startPtr+length;
	if ( (((uintptr_t)endPtr & (sys::Process::GetPageSize()-1)) == 0)
	    || (*endPtr != 0) )
		return MemoryBuffer::getMemBufferCopy(startPtr, endPtr);
	else
		return MemoryBuffer::getMemBuffer(startPtr, endPtr);
}

LTOModule* LTOModule::makeLTOModule(const void* mem, size_t length,
                                                        std::string& errMsg)
{
    OwningPtr<MemoryBuffer> buffer(makeBuffer(mem, length));
    if ( !buffer )
        return NULL;
    return makeLTOModule(buffer.get(), errMsg);
}

LTOModule* LTOModule::makeLTOModule(MemoryBuffer* buffer, std::string& errMsg)
{
    // parse bitcode buffer
    OwningPtr<Module> m(ParseBitcodeFile(buffer, &errMsg));
    if ( !m )
        return NULL;
    // find machine architecture for this module
    const TargetMachineRegistry::entry* march =
            TargetMachineRegistry::getClosestStaticTargetForModule(*m, errMsg);
    if ( march == NULL )
        return NULL;
    // construct LTModule, hand over ownership of module and target
    std::string     features;
    TargetMachine*  target = march->CtorFn(*m, features);
    return new LTOModule(m.take(), target);
}

const char* LTOModule::getTargetTriple()
{
    return _module->getTargetTriple().c_str();
}

void LTOModule::addDefinedFunctionSymbol(Function* f, Mangler &mangler)
{
    // add to list of defined symbols
    addDefinedSymbol(f, mangler, true);

    // add external symbols referenced by this function.
    for (Function::iterator b = f->begin(); b != f->end(); ++b) {
        for (BasicBlock::iterator i = b->begin(); i != b->end(); ++i) {
            for (unsigned count = 0, total = i->getNumOperands();
                                        count != total; ++count) {
                findExternalRefs(i->getOperand(count), mangler);
            }
        }
    }
}

void LTOModule::addDefinedDataSymbol(GlobalValue* v, Mangler &mangler)
{
    // add to list of defined symbols
    addDefinedSymbol(v, mangler, false);

    // add external symbols referenced by this data.
    for (unsigned count = 0, total = v->getNumOperands();
                                                count != total; ++count) {
        findExternalRefs(v->getOperand(count), mangler);
    }
}

void LTOModule::addDefinedSymbol(GlobalValue* def, Mangler &mangler,
                                bool isFunction)
{
    // string is owned by _defines
    const char* symbolName = ::strdup(mangler.getValueName(def).c_str());

    // set alignment part log2() can have rounding errors
    uint32_t align = def->getAlignment();
    uint32_t attr = align ? CountTrailingZeros_32(def->getAlignment()) : 0;

    // set permissions part
    if ( isFunction )
        attr |= LTO_SYMBOL_PERMISSIONS_CODE;
    else {
        GlobalVariable* gv = dyn_cast<GlobalVariable>(def);
        if ( (gv != NULL) && gv->isConstant() )
            attr |= LTO_SYMBOL_PERMISSIONS_RODATA;
        else
            attr |= LTO_SYMBOL_PERMISSIONS_DATA;
    }

    // set definition part
    if ( def->hasWeakLinkage() || def->hasLinkOnceLinkage() ) {
        attr |= LTO_SYMBOL_DEFINITION_WEAK;
    }
    else if ( def->hasCommonLinkage()) {
        attr |= LTO_SYMBOL_DEFINITION_TENTATIVE;
    }
    else {
        attr |= LTO_SYMBOL_DEFINITION_REGULAR;
    }

    // set scope part
    if ( def->hasHiddenVisibility() )
        attr |= LTO_SYMBOL_SCOPE_HIDDEN;
    else if ( def->hasExternalLinkage() || def->hasWeakLinkage() )
        attr |= LTO_SYMBOL_SCOPE_DEFAULT;
    else
        attr |= LTO_SYMBOL_SCOPE_INTERNAL;

    // add to table of symbols
    NameAndAttributes info;
    info.name = symbolName;
    info.attributes = (lto_symbol_attributes)attr;
    _symbols.push_back(info);
    _defines[info.name] = 1;
}

void LTOModule::addPotentialUndefinedSymbol(GlobalValue* decl, Mangler &mangler)
{
   const char* name = mangler.getValueName(decl).c_str();
    // ignore all llvm.* symbols
    if ( strncmp(name, "llvm.", 5) != 0 ) {
        _undefines[name] = 1;
    }
}

// Find exeternal symbols referenced by VALUE. This is a recursive function.
void LTOModule::findExternalRefs(Value* value, Mangler &mangler) {

    if (GlobalValue* gv = dyn_cast<GlobalValue>(value)) {
        if ( !gv->hasExternalLinkage() )
            addPotentialUndefinedSymbol(gv, mangler);
		// If this is a variable definition, do not recursively process
		// initializer.  It might contain a reference to this variable
		// and cause an infinite loop.  The initializer will be
		// processed in addDefinedDataSymbol().
	    return;
    }

    // GlobalValue, even with InternalLinkage type, may have operands with
    // ExternalLinkage type. Do not ignore these operands.
    if (Constant* c = dyn_cast<Constant>(value)) {
        // Handle ConstantExpr, ConstantStruct, ConstantArry etc..
        for (unsigned i = 0, e = c->getNumOperands(); i != e; ++i)
            findExternalRefs(c->getOperand(i), mangler);
    }
}

void LTOModule::lazyParseSymbols()
{
    if ( !_symbolsParsed ) {
        _symbolsParsed = true;

        // Use mangler to add GlobalPrefix to names to match linker names.
        Mangler mangler(*_module, _target->getTargetAsmInfo()->getGlobalPrefix());

        // add functions
        for (Module::iterator f = _module->begin(); f != _module->end(); ++f) {
            if ( f->isDeclaration() )
                addPotentialUndefinedSymbol(f, mangler);
            else
                addDefinedFunctionSymbol(f, mangler);
        }

        // add data
        for (Module::global_iterator v = _module->global_begin(),
                                    e = _module->global_end(); v !=  e; ++v) {
            if ( v->isDeclaration() )
                addPotentialUndefinedSymbol(v, mangler);
            else
                addDefinedDataSymbol(v, mangler);
        }

        // make symbols for all undefines
        for (StringSet::iterator it=_undefines.begin();
                                                it != _undefines.end(); ++it) {
            // if this symbol also has a definition, then don't make an undefine
            // because it is a tentative definition
            if ( _defines.count(it->getKeyData(), it->getKeyData()+
                                                  it->getKeyLength()) == 0 ) {
                NameAndAttributes info;
                info.name = it->getKeyData();
                info.attributes = LTO_SYMBOL_DEFINITION_UNDEFINED;
                _symbols.push_back(info);
            }
        }
    }
}

uint32_t LTOModule::getSymbolCount()
{
    lazyParseSymbols();
    return _symbols.size();
}

lto_symbol_attributes LTOModule::getSymbolAttributes(uint32_t index)
{
    lazyParseSymbols();
    if ( index < _symbols.size() )
        return _symbols[index].attributes;
    else
        return lto_symbol_attributes(0);
}

const char* LTOModule::getSymbolName(uint32_t index)
{
    lazyParseSymbols();
    if ( index < _symbols.size() )
        return _symbols[index].name;
    else
        return NULL;
}

<commit_msg>use space insted of tabs<commit_after>//===-LTOModule.cpp - LLVM Link Time Optimizer ----------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the Link Time Optimization library. This library is
// intended to be used by linker to optimize code at link time.
//
//===----------------------------------------------------------------------===//

#include "LTOModule.h"

#include "llvm/Module.h"
#include "llvm/ModuleProvider.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/Bitcode/ReaderWriter.h"
#include "llvm/Support/SystemUtils.h"
#include "llvm/Support/Mangler.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/System/Path.h"
#include "llvm/System/Process.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetMachineRegistry.h"
#include "llvm/Target/TargetAsmInfo.h"

#include <fstream>

using namespace llvm;

bool LTOModule::isBitcodeFile(const void* mem, size_t length)
{
    return ( llvm::sys::IdentifyFileType((char*)mem, length)
                                            == llvm::sys::Bitcode_FileType );
}

bool LTOModule::isBitcodeFile(const char* path)
{
    return llvm::sys::Path(path).isBitcodeFile();
}

bool LTOModule::isBitcodeFileForTarget(const void* mem, size_t length,
                                       const char* triplePrefix)
{
    MemoryBuffer* buffer = makeBuffer(mem, length);
    if ( buffer == NULL )
        return false;
    return isTargetMatch(buffer, triplePrefix);
}

bool LTOModule::isBitcodeFileForTarget(const char* path,
                                       const char* triplePrefix)
{
    MemoryBuffer *buffer = MemoryBuffer::getFile(path);
    if (buffer == NULL)
        return false;
    return isTargetMatch(buffer, triplePrefix);
}

// takes ownership of buffer
bool LTOModule::isTargetMatch(MemoryBuffer* buffer, const char* triplePrefix)
{
    OwningPtr<ModuleProvider> mp(getBitcodeModuleProvider(buffer));
    // on success, mp owns buffer and both are deleted at end of this method
    if ( !mp ) {
        delete buffer;
        return false;
    }
    std::string actualTarget = mp->getModule()->getTargetTriple();
    return ( strncmp(actualTarget.c_str(), triplePrefix,
                    strlen(triplePrefix)) == 0);
}

LTOModule::LTOModule(Module* m, TargetMachine* t)
 : _module(m), _target(t), _symbolsParsed(false)
{
}

LTOModule* LTOModule::makeLTOModule(const char* path, std::string& errMsg)
{
    OwningPtr<MemoryBuffer> buffer(MemoryBuffer::getFile(path, &errMsg));
    if ( !buffer )
        return NULL;
    return makeLTOModule(buffer.get(), errMsg);
}

/// makeBuffer - create a MemoryBuffer from a memory range.
/// MemoryBuffer requires the byte past end of the buffer to be a zero.
/// We might get lucky and already be that way, otherwise make a copy.
/// Also if next byte is on a different page, don't assume it is readable.
MemoryBuffer* LTOModule::makeBuffer(const void* mem, size_t length)
{
    const char* startPtr = (char*)mem;
    const char* endPtr = startPtr+length;
    if ( (((uintptr_t)endPtr & (sys::Process::GetPageSize()-1)) == 0)
        || (*endPtr != 0) )
        return MemoryBuffer::getMemBufferCopy(startPtr, endPtr);
    else
        return MemoryBuffer::getMemBuffer(startPtr, endPtr);
}

LTOModule* LTOModule::makeLTOModule(const void* mem, size_t length,
                                                        std::string& errMsg)
{
    OwningPtr<MemoryBuffer> buffer(makeBuffer(mem, length));
    if ( !buffer )
        return NULL;
    return makeLTOModule(buffer.get(), errMsg);
}

LTOModule* LTOModule::makeLTOModule(MemoryBuffer* buffer, std::string& errMsg)
{
    // parse bitcode buffer
    OwningPtr<Module> m(ParseBitcodeFile(buffer, &errMsg));
    if ( !m )
        return NULL;
    // find machine architecture for this module
    const TargetMachineRegistry::entry* march =
            TargetMachineRegistry::getClosestStaticTargetForModule(*m, errMsg);
    if ( march == NULL )
        return NULL;
    // construct LTModule, hand over ownership of module and target
    std::string     features;
    TargetMachine*  target = march->CtorFn(*m, features);
    return new LTOModule(m.take(), target);
}

const char* LTOModule::getTargetTriple()
{
    return _module->getTargetTriple().c_str();
}

void LTOModule::addDefinedFunctionSymbol(Function* f, Mangler &mangler)
{
    // add to list of defined symbols
    addDefinedSymbol(f, mangler, true);

    // add external symbols referenced by this function.
    for (Function::iterator b = f->begin(); b != f->end(); ++b) {
        for (BasicBlock::iterator i = b->begin(); i != b->end(); ++i) {
            for (unsigned count = 0, total = i->getNumOperands();
                                        count != total; ++count) {
                findExternalRefs(i->getOperand(count), mangler);
            }
        }
    }
}

void LTOModule::addDefinedDataSymbol(GlobalValue* v, Mangler &mangler)
{
    // add to list of defined symbols
    addDefinedSymbol(v, mangler, false);

    // add external symbols referenced by this data.
    for (unsigned count = 0, total = v->getNumOperands();
                                                count != total; ++count) {
        findExternalRefs(v->getOperand(count), mangler);
    }
}

void LTOModule::addDefinedSymbol(GlobalValue* def, Mangler &mangler,
                                bool isFunction)
{
    // string is owned by _defines
    const char* symbolName = ::strdup(mangler.getValueName(def).c_str());

    // set alignment part log2() can have rounding errors
    uint32_t align = def->getAlignment();
    uint32_t attr = align ? CountTrailingZeros_32(def->getAlignment()) : 0;

    // set permissions part
    if ( isFunction )
        attr |= LTO_SYMBOL_PERMISSIONS_CODE;
    else {
        GlobalVariable* gv = dyn_cast<GlobalVariable>(def);
        if ( (gv != NULL) && gv->isConstant() )
            attr |= LTO_SYMBOL_PERMISSIONS_RODATA;
        else
            attr |= LTO_SYMBOL_PERMISSIONS_DATA;
    }

    // set definition part
    if ( def->hasWeakLinkage() || def->hasLinkOnceLinkage() ) {
        attr |= LTO_SYMBOL_DEFINITION_WEAK;
    }
    else if ( def->hasCommonLinkage()) {
        attr |= LTO_SYMBOL_DEFINITION_TENTATIVE;
    }
    else {
        attr |= LTO_SYMBOL_DEFINITION_REGULAR;
    }

    // set scope part
    if ( def->hasHiddenVisibility() )
        attr |= LTO_SYMBOL_SCOPE_HIDDEN;
    else if ( def->hasExternalLinkage() || def->hasWeakLinkage() )
        attr |= LTO_SYMBOL_SCOPE_DEFAULT;
    else
        attr |= LTO_SYMBOL_SCOPE_INTERNAL;

    // add to table of symbols
    NameAndAttributes info;
    info.name = symbolName;
    info.attributes = (lto_symbol_attributes)attr;
    _symbols.push_back(info);
    _defines[info.name] = 1;
}

void LTOModule::addPotentialUndefinedSymbol(GlobalValue* decl, Mangler &mangler)
{
   const char* name = mangler.getValueName(decl).c_str();
    // ignore all llvm.* symbols
    if ( strncmp(name, "llvm.", 5) != 0 ) {
        _undefines[name] = 1;
    }
}

// Find exeternal symbols referenced by VALUE. This is a recursive function.
void LTOModule::findExternalRefs(Value* value, Mangler &mangler) {

    if (GlobalValue* gv = dyn_cast<GlobalValue>(value)) {
        if ( !gv->hasExternalLinkage() )
            addPotentialUndefinedSymbol(gv, mangler);
        // If this is a variable definition, do not recursively process
        // initializer.  It might contain a reference to this variable
        // and cause an infinite loop.  The initializer will be
        // processed in addDefinedDataSymbol().
        return;
    }

    // GlobalValue, even with InternalLinkage type, may have operands with
    // ExternalLinkage type. Do not ignore these operands.
    if (Constant* c = dyn_cast<Constant>(value)) {
        // Handle ConstantExpr, ConstantStruct, ConstantArry etc..
        for (unsigned i = 0, e = c->getNumOperands(); i != e; ++i)
            findExternalRefs(c->getOperand(i), mangler);
    }
}

void LTOModule::lazyParseSymbols()
{
    if ( !_symbolsParsed ) {
        _symbolsParsed = true;

        // Use mangler to add GlobalPrefix to names to match linker names.
        Mangler mangler(*_module, _target->getTargetAsmInfo()->getGlobalPrefix());

        // add functions
        for (Module::iterator f = _module->begin(); f != _module->end(); ++f) {
            if ( f->isDeclaration() )
                addPotentialUndefinedSymbol(f, mangler);
            else
                addDefinedFunctionSymbol(f, mangler);
        }

        // add data
        for (Module::global_iterator v = _module->global_begin(),
                                    e = _module->global_end(); v !=  e; ++v) {
            if ( v->isDeclaration() )
                addPotentialUndefinedSymbol(v, mangler);
            else
                addDefinedDataSymbol(v, mangler);
        }

        // make symbols for all undefines
        for (StringSet::iterator it=_undefines.begin();
                                                it != _undefines.end(); ++it) {
            // if this symbol also has a definition, then don't make an undefine
            // because it is a tentative definition
            if ( _defines.count(it->getKeyData(), it->getKeyData()+
                                                  it->getKeyLength()) == 0 ) {
                NameAndAttributes info;
                info.name = it->getKeyData();
                info.attributes = LTO_SYMBOL_DEFINITION_UNDEFINED;
                _symbols.push_back(info);
            }
        }
    }
}

uint32_t LTOModule::getSymbolCount()
{
    lazyParseSymbols();
    return _symbols.size();
}

lto_symbol_attributes LTOModule::getSymbolAttributes(uint32_t index)
{
    lazyParseSymbols();
    if ( index < _symbols.size() )
        return _symbols[index].attributes;
    else
        return lto_symbol_attributes(0);
}

const char* LTOModule::getSymbolName(uint32_t index)
{
    lazyParseSymbols();
    if ( index < _symbols.size() )
        return _symbols[index].name;
    else
        return NULL;
}

<|endoftext|>