<commit_before>// Copyright 2015-2020 Elviss Strazdins. All rights reserved.

#if defined(__APPLE__)
#  include <TargetConditionals.h>
#endif
#include <stdexcept>
#include "../core/Setup.h"
#include "Graphics.hpp"
#include "Commands.hpp"
#include "RenderDevice.hpp"
#include "../events/EventHandler.hpp"
#include "../events/EventDispatcher.hpp"
#include "../core/Engine.hpp"
#include "../core/Window.hpp"
#include "../utils/Log.hpp"

#if TARGET_OS_IOS
#  include "metal/ios/MetalRenderDeviceIOS.hpp"
#  include "opengl/ios/OGLRenderDeviceIOS.hpp"
#elif TARGET_OS_TV
#  include "metal/tvos/MetalRenderDeviceTVOS.hpp"
#  include "opengl/tvos/OGLRenderDeviceTVOS.hpp"
#elif TARGET_OS_MAC
#  include "metal/macos/MetalRenderDeviceMacOS.hpp"
#  include "opengl/macos/OGLRenderDeviceMacOS.hpp"
#elif defined(__ANDROID__)
#  include "opengl/android/OGLRenderDeviceAndroid.hpp"
#elif defined(__linux__)
#  include "opengl/linux/OGLRenderDeviceLinux.hpp"
#elif defined(_WIN32)
#  include "opengl/windows/OGLRenderDeviceWin.hpp"
#elif defined(__EMSCRIPTEN__)
#  include "opengl/emscripten/OGLRenderDeviceEm.hpp"
#endif

#include "empty/EmptyRenderDevice.hpp"
#include "opengl/OGLRenderDevice.hpp"
#include "direct3d11/D3D11RenderDevice.hpp"
#include "metal/MetalRenderDevice.hpp"

namespace ouzel::graphics
{
    Driver Graphics::getDriver(const std::string& driver)
    {
        if (driver.empty() || driver == "default")
        {
            auto availableDrivers = getAvailableRenderDrivers();

            if (availableDrivers.find(Driver::metal) != availableDrivers.end())
                return Driver::metal;
            else if (availableDrivers.find(Driver::direct3D11) != availableDrivers.end())
                return Driver::direct3D11;
            else if (availableDrivers.find(Driver::openGL) != availableDrivers.end())
                return Driver::openGL;
            else
                return Driver::empty;
        }
        else if (driver == "empty")
            return Driver::empty;
        else if (driver == "opengl")
            return Driver::openGL;
        else if (driver == "direct3d11")
            return Driver::direct3D11;
        else if (driver == "metal")
            return Driver::metal;
        else
            throw std::runtime_error("Invalid graphics driver");
    }

    std::set<Driver> Graphics::getAvailableRenderDrivers()
    {
        static std::set<Driver> availableDrivers;

        if (availableDrivers.empty())
        {
            availableDrivers.insert(Driver::empty);

#if OUZEL_COMPILE_OPENGL
            availableDrivers.insert(Driver::openGL);
#endif
#if OUZEL_COMPILE_DIRECT3D11
            availableDrivers.insert(Driver::direct3D11);
#endif
#if OUZEL_COMPILE_METAL
            if (metal::RenderDevice::available())
                availableDrivers.insert(Driver::metal);
#endif
        }

        return availableDrivers;
    }

    Graphics::Graphics(Driver driver,
                       core::Window& initWindow,
                       const Settings& settings):
        textureFilter(settings.textureFilter),
        maxAnisotropy(settings.maxAnisotropy),
        size(initWindow.getResolution())
    {
        switch (driver)
        {
#if OUZEL_COMPILE_OPENGL
            case Driver::openGL:
                logger.log(Log::Level::info) << "Using OpenGL render driver";
#  if TARGET_OS_IOS
                device = std::make_unique<opengl::ios::RenderDevice>(settings, initWindow, std::bind(&Graphics::handleEvent, this, std::placeholders::_1));
#  elif TARGET_OS_TV
                device = std::make_unique<opengl::tvos::RenderDevice>(settings, initWindow, std::bind(&Graphics::handleEvent, this, std::placeholders::_1));
#  elif TARGET_OS_MAC
                device = std::make_unique<opengl::macos::RenderDevice>(settings, initWindow, std::bind(&Graphics::handleEvent, this, std::placeholders::_1));
#  elif defined(__ANDROID__)
                device = std::make_unique<opengl::android::RenderDevice>(settings, initWindow, std::bind(&Graphics::handleEvent, this, std::placeholders::_1));
#  elif defined(__linux__)
                device = std::make_unique<opengl::linux::RenderDevice>(settings, initWindow, std::bind(&Graphics::handleEvent, this, std::placeholders::_1));
#  elif defined(_WIN32)
                device = std::make_unique<opengl::windows::RenderDevice>(settings, initWindow, std::bind(&Graphics::handleEvent, this, std::placeholders::_1));
#  elif defined(__EMSCRIPTEN__)
                device = std::make_unique<opengl::emscripten::RenderDevice>(settings, initWindow, std::bind(&Graphics::handleEvent, this, std::placeholders::_1));
#  else
                device = std::make_unique<opengl::RenderDevice>(settings, initWindow, std::bind(&Graphics::handleEvent, this, std::placeholders::_1));
#  endif
                break;
#endif
#if OUZEL_COMPILE_DIRECT3D11
            case Driver::direct3D11:
                logger.log(Log::Level::info) << "Using Direct3D 11 render driver";
                device = std::make_unique<d3d11::RenderDevice>(settings, initWindow, std::bind(&Graphics::handleEvent, this, std::placeholders::_1));
                break;
#endif
#if OUZEL_COMPILE_METAL
            case Driver::metal:
                logger.log(Log::Level::info) << "Using Metal render driver";
#  if TARGET_OS_IOS
                device = std::make_unique<metal::ios::RenderDevice>(settings, initWindow, std::bind(&Graphics::handleEvent, this, std::placeholders::_1));
#  elif TARGET_OS_TV
                device = std::make_unique<metal::tvos::RenderDevice>(settings, initWindow, std::bind(&Graphics::handleEvent, this, std::placeholders::_1));
#  elif TARGET_OS_MAC
                device = std::make_unique<metal::macos::RenderDevice>(settings, initWindow, std::bind(&Graphics::handleEvent, this, std::placeholders::_1));
#  endif
                break;
#endif
            default:
                logger.log(Log::Level::info) << "Not using render driver";
                device = std::make_unique<empty::RenderDevice>(settings, initWindow, std::bind(&Graphics::handleEvent, this, std::placeholders::_1));
                break;
        }
    }

    void Graphics::handleEvent(const RenderDevice::Event& event)
    {
        if (event.type == RenderDevice::Event::Type::frame)
        {
            std::unique_lock lock(frameMutex);
            newFrame = true;
            refillQueue = true;
            lock.unlock();
            frameCondition.notify_all();
        }
    }

    void Graphics::setSize(const Size2U& newSize)
    {
        size = newSize;

        addCommand(std::make_unique<ResizeCommand>(newSize));
    }

    void Graphics::saveScreenshot(const std::string& filename)
    {
        device->executeOnRenderThread(std::bind(&RenderDevice::generateScreenshot, device.get(), filename));
    }

    void Graphics::setRenderTarget(std::size_t renderTarget)
    {
        addCommand(std::make_unique<SetRenderTargetCommand>(renderTarget));
    }

    void Graphics::clearRenderTarget(bool clearColorBuffer,
                                     bool clearDepthBuffer,
                                     bool clearStencilBuffer,
                                     Color clearColor,
                                     float clearDepth,
                                     std::uint32_t clearStencil)
    {
        addCommand(std::make_unique<ClearRenderTargetCommand>(clearColorBuffer,
                                                              clearDepthBuffer,
                                                              clearStencilBuffer,
                                                              clearColor,
                                                              clearDepth,
                                                              clearStencil));
    }

    void Graphics::setScissorTest(bool enabled, const RectF& rectangle)
    {
        addCommand(std::make_unique<SetScissorTestCommand>(enabled, rectangle));
    }

    void Graphics::setViewport(const RectF& viewport)
    {
        addCommand(std::make_unique<SetViewportCommand>(viewport));
    }

    void Graphics::setDepthStencilState(std::size_t depthStencilState,
                                        std::uint32_t stencilReferenceValue)
    {
        addCommand(std::make_unique<SetDepthStencilStateCommand>(depthStencilState,
                                                                 stencilReferenceValue));
    }

    void Graphics::setPipelineState(std::size_t blendState,
                                    std::size_t shader,
                                    CullMode cullMode,
                                    FillMode fillMode)
    {
        addCommand(std::make_unique<SetPipelineStateCommand>(blendState,
                                                             shader,
                                                             cullMode,
                                                             fillMode));
    }

    void Graphics::draw(std::size_t indexBuffer,
                        std::uint32_t indexCount,
                        std::uint32_t indexSize,
                        std::size_t vertexBuffer,
                        DrawMode drawMode,
                        std::uint32_t startIndex)
    {
        if (!indexBuffer || !vertexBuffer)
            throw std::runtime_error("Invalid mesh buffer passed to render queue");

        addCommand(std::make_unique<DrawCommand>(indexBuffer,
                                                 indexCount,
                                                 indexSize,
                                                 vertexBuffer,
                                                 drawMode,
                                                 startIndex));
    }

    void Graphics::pushDebugMarker(const std::string& name)
    {
        addCommand(std::make_unique<PushDebugMarkerCommand>(name));
    }

    void Graphics::popDebugMarker()
    {
        addCommand(std::make_unique<PopDebugMarkerCommand>());
    }

    void Graphics::setShaderConstants(const std::vector<std::vector<float>>& fragmentShaderConstants,
                                      const std::vector<std::vector<float>>& vertexShaderConstants)
    {
        addCommand(std::make_unique<SetShaderConstantsCommand>(fragmentShaderConstants,
                                                               vertexShaderConstants));
    }

    void Graphics::setTextures(const std::vector<std::size_t>& textures)
    {
        addCommand(std::make_unique<SetTexturesCommand>(textures));
    }

    void Graphics::present()
    {
        refillQueue = false;
        addCommand(std::make_unique<PresentCommand>());
        device->submitCommandBuffer(std::move(commandBuffer));
        commandBuffer = CommandBuffer();
    }

    void Graphics::waitForNextFrame()
    {
        std::unique_lock lock(frameMutex);
        while (!newFrame) frameCondition.wait(lock);
        newFrame = false;
    }
}
<commit_msg>Add helper function for creating render device<commit_after>// Copyright 2015-2020 Elviss Strazdins. All rights reserved.

#if defined(__APPLE__)
#  include <TargetConditionals.h>
#endif
#include <stdexcept>
#include "../core/Setup.h"
#include "Graphics.hpp"
#include "Commands.hpp"
#include "RenderDevice.hpp"
#include "../events/EventHandler.hpp"
#include "../events/EventDispatcher.hpp"
#include "../core/Engine.hpp"
#include "../core/Window.hpp"
#include "../utils/Log.hpp"

#if TARGET_OS_IOS
#  include "metal/ios/MetalRenderDeviceIOS.hpp"
#  include "opengl/ios/OGLRenderDeviceIOS.hpp"
#elif TARGET_OS_TV
#  include "metal/tvos/MetalRenderDeviceTVOS.hpp"
#  include "opengl/tvos/OGLRenderDeviceTVOS.hpp"
#elif TARGET_OS_MAC
#  include "metal/macos/MetalRenderDeviceMacOS.hpp"
#  include "opengl/macos/OGLRenderDeviceMacOS.hpp"
#elif defined(__ANDROID__)
#  include "opengl/android/OGLRenderDeviceAndroid.hpp"
#elif defined(__linux__)
#  include "opengl/linux/OGLRenderDeviceLinux.hpp"
#elif defined(_WIN32)
#  include "opengl/windows/OGLRenderDeviceWin.hpp"
#elif defined(__EMSCRIPTEN__)
#  include "opengl/emscripten/OGLRenderDeviceEm.hpp"
#endif

#include "empty/EmptyRenderDevice.hpp"
#include "opengl/OGLRenderDevice.hpp"
#include "direct3d11/D3D11RenderDevice.hpp"
#include "metal/MetalRenderDevice.hpp"

namespace ouzel::graphics
{
    Driver Graphics::getDriver(const std::string& driver)
    {
        if (driver.empty() || driver == "default")
        {
            auto availableDrivers = getAvailableRenderDrivers();

            if (availableDrivers.find(Driver::metal) != availableDrivers.end())
                return Driver::metal;
            else if (availableDrivers.find(Driver::direct3D11) != availableDrivers.end())
                return Driver::direct3D11;
            else if (availableDrivers.find(Driver::openGL) != availableDrivers.end())
                return Driver::openGL;
            else
                return Driver::empty;
        }
        else if (driver == "empty")
            return Driver::empty;
        else if (driver == "opengl")
            return Driver::openGL;
        else if (driver == "direct3d11")
            return Driver::direct3D11;
        else if (driver == "metal")
            return Driver::metal;
        else
            throw std::runtime_error("Invalid graphics driver");
    }

    std::set<Driver> Graphics::getAvailableRenderDrivers()
    {
        static std::set<Driver> availableDrivers;

        if (availableDrivers.empty())
        {
            availableDrivers.insert(Driver::empty);

#if OUZEL_COMPILE_OPENGL
            availableDrivers.insert(Driver::openGL);
#endif
#if OUZEL_COMPILE_DIRECT3D11
            availableDrivers.insert(Driver::direct3D11);
#endif
#if OUZEL_COMPILE_METAL
            if (metal::RenderDevice::available())
                availableDrivers.insert(Driver::metal);
#endif
        }

        return availableDrivers;
    }

    namespace
    {
        std::unique_ptr<RenderDevice> createRenderDevice(Driver driver,
                                                         core::Window& window,
                                                         const Settings& settings,
                                                         const std::function<void(const RenderDevice::Event&)>& callback)
        {
            switch (driver)
            {
#if OUZEL_COMPILE_OPENGL
                case Driver::openGL:
                    logger.log(Log::Level::info) << "Using OpenGL render driver";
#  if TARGET_OS_IOS
                    return std::make_unique<opengl::ios::RenderDevice>(settings, window, callback);
#  elif TARGET_OS_TV
                    return std::make_unique<opengl::tvos::RenderDevice>(settings, window, callback);
#  elif TARGET_OS_MAC
                    return std::make_unique<opengl::macos::RenderDevice>(settings, window, callback);
#  elif defined(__ANDROID__)
                    return std::make_unique<opengl::android::RenderDevice>(settings, window, callback);
#  elif defined(__linux__)
                    return std::make_unique<opengl::linux::RenderDevice>(settings, window, callback);
#  elif defined(_WIN32)
                    return std::make_unique<opengl::windows::RenderDevice>(settings, window, callback);
#  elif defined(__EMSCRIPTEN__)
                    return std::make_unique<opengl::emscripten::RenderDevice>(settings, window, callback);
#  else
                    return std::make_unique<opengl::RenderDevice>(settings, window, callback);
#  endif
#endif
#if OUZEL_COMPILE_DIRECT3D11
                case Driver::direct3D11:
                    logger.log(Log::Level::info) << "Using Direct3D 11 render driver";
                    return std::make_unique<d3d11::RenderDevice>(settings, window, callback);
#endif
#if OUZEL_COMPILE_METAL
                case Driver::metal:
                    logger.log(Log::Level::info) << "Using Metal render driver";
#  if TARGET_OS_IOS
                    return std::make_unique<metal::ios::RenderDevice>(settings, window, callback);
#  elif TARGET_OS_TV
                    return std::make_unique<metal::tvos::RenderDevice>(settings, window, callback);
#  elif TARGET_OS_MAC
                    return std::make_unique<metal::macos::RenderDevice>(settings, window, callback);
#  endif
#endif
                default:
                    logger.log(Log::Level::info) << "Not using render driver";
                    return std::make_unique<empty::RenderDevice>(settings, window, callback);
            }
        }
    }

    Graphics::Graphics(Driver driver,
                       core::Window& initWindow,
                       const Settings& settings):
        device(createRenderDevice(driver, initWindow, settings, std::bind(&Graphics::handleEvent, this, std::placeholders::_1))),
        textureFilter(settings.textureFilter),
        maxAnisotropy(settings.maxAnisotropy),
        size(initWindow.getResolution())
    {

    }

    void Graphics::handleEvent(const RenderDevice::Event& event)
    {
        if (event.type == RenderDevice::Event::Type::frame)
        {
            std::unique_lock lock(frameMutex);
            newFrame = true;
            refillQueue = true;
            lock.unlock();
            frameCondition.notify_all();
        }
    }

    void Graphics::setSize(const Size2U& newSize)
    {
        size = newSize;

        addCommand(std::make_unique<ResizeCommand>(newSize));
    }

    void Graphics::saveScreenshot(const std::string& filename)
    {
        device->executeOnRenderThread(std::bind(&RenderDevice::generateScreenshot, device.get(), filename));
    }

    void Graphics::setRenderTarget(std::size_t renderTarget)
    {
        addCommand(std::make_unique<SetRenderTargetCommand>(renderTarget));
    }

    void Graphics::clearRenderTarget(bool clearColorBuffer,
                                     bool clearDepthBuffer,
                                     bool clearStencilBuffer,
                                     Color clearColor,
                                     float clearDepth,
                                     std::uint32_t clearStencil)
    {
        addCommand(std::make_unique<ClearRenderTargetCommand>(clearColorBuffer,
                                                              clearDepthBuffer,
                                                              clearStencilBuffer,
                                                              clearColor,
                                                              clearDepth,
                                                              clearStencil));
    }

    void Graphics::setScissorTest(bool enabled, const RectF& rectangle)
    {
        addCommand(std::make_unique<SetScissorTestCommand>(enabled, rectangle));
    }

    void Graphics::setViewport(const RectF& viewport)
    {
        addCommand(std::make_unique<SetViewportCommand>(viewport));
    }

    void Graphics::setDepthStencilState(std::size_t depthStencilState,
                                        std::uint32_t stencilReferenceValue)
    {
        addCommand(std::make_unique<SetDepthStencilStateCommand>(depthStencilState,
                                                                 stencilReferenceValue));
    }

    void Graphics::setPipelineState(std::size_t blendState,
                                    std::size_t shader,
                                    CullMode cullMode,
                                    FillMode fillMode)
    {
        addCommand(std::make_unique<SetPipelineStateCommand>(blendState,
                                                             shader,
                                                             cullMode,
                                                             fillMode));
    }

    void Graphics::draw(std::size_t indexBuffer,
                        std::uint32_t indexCount,
                        std::uint32_t indexSize,
                        std::size_t vertexBuffer,
                        DrawMode drawMode,
                        std::uint32_t startIndex)
    {
        if (!indexBuffer || !vertexBuffer)
            throw std::runtime_error("Invalid mesh buffer passed to render queue");

        addCommand(std::make_unique<DrawCommand>(indexBuffer,
                                                 indexCount,
                                                 indexSize,
                                                 vertexBuffer,
                                                 drawMode,
                                                 startIndex));
    }

    void Graphics::pushDebugMarker(const std::string& name)
    {
        addCommand(std::make_unique<PushDebugMarkerCommand>(name));
    }

    void Graphics::popDebugMarker()
    {
        addCommand(std::make_unique<PopDebugMarkerCommand>());
    }

    void Graphics::setShaderConstants(const std::vector<std::vector<float>>& fragmentShaderConstants,
                                      const std::vector<std::vector<float>>& vertexShaderConstants)
    {
        addCommand(std::make_unique<SetShaderConstantsCommand>(fragmentShaderConstants,
                                                               vertexShaderConstants));
    }

    void Graphics::setTextures(const std::vector<std::size_t>& textures)
    {
        addCommand(std::make_unique<SetTexturesCommand>(textures));
    }

    void Graphics::present()
    {
        refillQueue = false;
        addCommand(std::make_unique<PresentCommand>());
        device->submitCommandBuffer(std::move(commandBuffer));
        commandBuffer = CommandBuffer();
    }

    void Graphics::waitForNextFrame()
    {
        std::unique_lock lock(frameMutex);
        while (!newFrame) frameCondition.wait(lock);
        newFrame = false;
    }
}
<|endoftext|>


<commit_before>// Jubatus: Online machine learning framework for distributed environment
// Copyright (C) 2013 Preferred Infrastructure and Nippon Telegraph and Telephone Corporation.
//
// 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

#ifndef JUBATUS_CORE_COMMON_ASSERT_HPP_
#define JUBATUS_CORE_COMMON_ASSERT_HPP_

#ifndef JUBATUS_DISABLE_ASSERTIONS

#include <stdlib.h>
#include <assert.h>
#include <iostream>

#include <string>
#include "jubatus/util/lang/cast.h"

#define JUBA_CHECK(a, op, b, message) { \
    using jubatus::util::lang::lexical_cast; \
    if (!((a)op(b))) { \
      std::cerr << "ASSERTION FAILED: " << message << ": " \
                << #a << " " << #op << " " << #b \
                << " (" << __FILE__ << ":" << __LINE__ << ")" << std::endl; \
      std::cerr << "... where  " << #a << " = " \
                << lexical_cast<std::string>(a) << std::endl \
                << "      and  " << #b << " = " \
                << lexical_cast<std::string>(b) << std::endl; \
      std::terminate(); \
    }}

// declares expr to be true; if false, messages are shown
#define JUBATUS_ASSERT_MSG(expr, message)  \
    do { \
      using jubatus::util::lang::lexical_cast; \
      if (!(expr)) { \
        std::cerr << "ASSERTION FAILED: " << message << ": " \
                  << #expr << " == " << lexical_cast<std::string>(expr) \
                  << " (" << __FILE__ << ":" << __LINE__ << ")" << std::endl; \
        std::terminate(); \
      } \
    } while (0)

// declares expr to be true
// unlike glog CHECK, this macro cannot take trailing `<<';
// please use JUBATUS_ASSERT_MSG if you need extra messages.
#define JUBATUS_ASSERT(expr)  \
    do { JUBATUS_ASSERT_MSG(expr, ""); } while (0)

// declares control flow not to reach here
#define JUBATUS_ASSERT_UNREACHABLE()  \
    do { JUBATUS_ASSERT_MSG(0, "control flow not to reach here"); } while (0)

// helpers to compare values
#define JUBATUS_ASSERT_EQ(a, b, messages)   \
    do { JUBA_CHECK(a, ==, b, messages); } while (0)
#define JUBATUS_ASSERT_NE(a, b, messages)   \
    do { JUBA_CHECK(a, !=, b, messages); } while (0)
#define JUBATUS_ASSERT_LE(a, b, messages)   \
    do { JUBA_CHECK(a, <=, b, messages); } while (0)
#define JUBATUS_ASSERT_LT(a, b, messages)   \
    do { JUBA_CHECK(a, <, b, messages);  } while (0)
#define JUBATUS_ASSERT_GE(a, b, messages)   \
    do { JUBA_CHECK(a, >=, b, messages); } while (0)
#define JUBATUS_ASSERT_GT(a, b, messages)   \
    do { JUBA_CHECK(a, >, b, messages);  } while (0)

#else  // #ifndef JUBATUS_DISABLE_ASSERTIONS

#define JUBATUS_ASSERT(expr) ((void)0)
#define JUBATUS_ASSERT_MSG(expr, msg) ((void)0)

#ifndef __has_builtin
  #define __has_builtin(x) 0
#endif

#if __has_builtin(__builtin_unreachable) || \
    __GNUC__ == 4 && __GNUC_MINOR__ >= 5
  // TODO(gintenlabo): Add __GUNC__ >= 5 if GCC 5.x has __builtin_unreachable
  #define JUBATUS_ASSERT_UNREACHABLE() __builtin_unreachable()
#else
  #include <exception>  // NOLINT
  #define JUBATUS_ASSERT_UNREACHABLE() std::terminate()
#endif

#define JUBATUS_ASSERT_EQ(a, b, messages) ((void)0)
#define JUBATUS_ASSERT_NE(a, b, messages) ((void)0)
#define JUBATUS_ASSERT_LE(a, b, messages) ((void)0)
#define JUBATUS_ASSERT_LT(a, b, messages) ((void)0)
#define JUBATUS_ASSERT_GE(a, b, messages) ((void)0)
#define JUBATUS_ASSERT_GT(a, b, messages) ((void)0)

#endif  // #ifndef JUBATUS_DISABLE_ASSERTIONS

#endif  // JUBATUS_CORE_COMMON_ASSERT_HPP_
<commit_msg>do not print meaningless value<commit_after>// Jubatus: Online machine learning framework for distributed environment
// Copyright (C) 2013 Preferred Infrastructure and Nippon Telegraph and Telephone Corporation.
//
// 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

#ifndef JUBATUS_CORE_COMMON_ASSERT_HPP_
#define JUBATUS_CORE_COMMON_ASSERT_HPP_

#ifndef JUBATUS_DISABLE_ASSERTIONS

#include <stdlib.h>
#include <assert.h>
#include <iostream>

#include <string>
#include "jubatus/util/lang/cast.h"

#define JUBA_CHECK(a, op, b, message) { \
    using jubatus::util::lang::lexical_cast; \
    if (!((a)op(b))) { \
      std::cerr << "ASSERTION FAILED: " << message << ": " \
                << #a << " " << #op << " " << #b \
                << " (" << __FILE__ << ":" << __LINE__ << ")" << std::endl; \
      std::cerr << "... where  " << #a << " = " \
                << lexical_cast<std::string>(a) << std::endl \
                << "      and  " << #b << " = " \
                << lexical_cast<std::string>(b) << std::endl; \
      std::terminate(); \
    }}

// declares expr to be true; if false, messages are shown
#define JUBATUS_ASSERT_MSG(expr, message)  \
    do { \
      if (!(expr)) { \
        std::cerr << "ASSERTION FAILED: " << message << ": " << #expr \
                  << " (" << __FILE__ << ":" << __LINE__ << ")" << std::endl; \
        std::terminate(); \
      } \
    } while (0)

// declares expr to be true
// unlike glog CHECK, this macro cannot take trailing `<<';
// please use JUBATUS_ASSERT_MSG if you need extra messages.
#define JUBATUS_ASSERT(expr)  \
    do { JUBATUS_ASSERT_MSG(expr, ""); } while (0)

// declares control flow not to reach here
#define JUBATUS_ASSERT_UNREACHABLE()  \
    do { JUBATUS_ASSERT_MSG(0, "control flow not to reach here"); } while (0)

// helpers to compare values
#define JUBATUS_ASSERT_EQ(a, b, messages)   \
    do { JUBA_CHECK(a, ==, b, messages); } while (0)
#define JUBATUS_ASSERT_NE(a, b, messages)   \
    do { JUBA_CHECK(a, !=, b, messages); } while (0)
#define JUBATUS_ASSERT_LE(a, b, messages)   \
    do { JUBA_CHECK(a, <=, b, messages); } while (0)
#define JUBATUS_ASSERT_LT(a, b, messages)   \
    do { JUBA_CHECK(a, <, b, messages);  } while (0)
#define JUBATUS_ASSERT_GE(a, b, messages)   \
    do { JUBA_CHECK(a, >=, b, messages); } while (0)
#define JUBATUS_ASSERT_GT(a, b, messages)   \
    do { JUBA_CHECK(a, >, b, messages);  } while (0)

#else  // #ifndef JUBATUS_DISABLE_ASSERTIONS

#define JUBATUS_ASSERT(expr) ((void)0)
#define JUBATUS_ASSERT_MSG(expr, msg) ((void)0)

#ifndef __has_builtin
  #define __has_builtin(x) 0
#endif

#if __has_builtin(__builtin_unreachable) || \
    __GNUC__ == 4 && __GNUC_MINOR__ >= 5
  // TODO(gintenlabo): Add __GUNC__ >= 5 if GCC 5.x has __builtin_unreachable
  #define JUBATUS_ASSERT_UNREACHABLE() __builtin_unreachable()
#else
  #include <exception>  // NOLINT
  #define JUBATUS_ASSERT_UNREACHABLE() std::terminate()
#endif

#define JUBATUS_ASSERT_EQ(a, b, messages) ((void)0)
#define JUBATUS_ASSERT_NE(a, b, messages) ((void)0)
#define JUBATUS_ASSERT_LE(a, b, messages) ((void)0)
#define JUBATUS_ASSERT_LT(a, b, messages) ((void)0)
#define JUBATUS_ASSERT_GE(a, b, messages) ((void)0)
#define JUBATUS_ASSERT_GT(a, b, messages) ((void)0)

#endif  // #ifndef JUBATUS_DISABLE_ASSERTIONS

#endif  // JUBATUS_CORE_COMMON_ASSERT_HPP_
<|endoftext|>


<commit_before>// Copyright (c) 2016-2018 The Syscoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <test/test_syscoin_services.h>
#include <util/time.h>
#include <rpc/server.h>
#include <services/asset.h>
#include <base58.h>
#include <chainparams.h>
#include <boost/test/unit_test.hpp>
#include <iterator>
#include <key.h>
using namespace std;
BOOST_GLOBAL_FIXTURE( SyscoinTestingSetup );
BOOST_FIXTURE_TEST_SUITE(syscoin_asset_allocation_tests, BasicSyscoinTestingSetup)

BOOST_AUTO_TEST_CASE(generate_asset_allocation_address_sync)
{
	UniValue r;
	printf("Running generate_asset_allocation_address_sync...\n");
	GenerateBlocks(5);
	string newaddress = GetNewFundedAddress("node1");
    BOOST_CHECK_NO_THROW(r = CallExtRPC("node1", "getnewaddress"));
    string newaddressreceiver = r.get_str();
	string guid = AssetNew("node1", newaddress, "data", "''", "8", "10000", "1000000");

	AssetSend("node1", guid, "\"[{\\\"address\\\":\\\"" + newaddressreceiver + "\\\",\\\"amount\\\":5000}]\"");
	BOOST_CHECK_NO_THROW(r = CallRPC("node1", "assetallocationinfo " + guid + " " + newaddressreceiver ));
	UniValue balance = find_value(r.get_obj(), "balance");
	BOOST_CHECK_NO_THROW(r = CallRPC("node2", "assetallocationinfo " + guid + " " + newaddressreceiver ));
	balance = find_value(r.get_obj(), "balance");
	StopNode("node2");
	StartNode("node2");
	GenerateBlocks(5, "node2");
	BOOST_CHECK_NO_THROW(r = CallRPC("node1", "assetallocationinfo " + guid + " " + newaddressreceiver ));
	balance = find_value(r.get_obj(), "balance");
	BOOST_CHECK_NO_THROW(r = CallRPC("node2", "assetallocationinfo " + guid + " " + newaddressreceiver ));
	balance = find_value(r.get_obj(), "balance");

}
BOOST_AUTO_TEST_CASE(generate_asset_allocation_lock)
{
    UniValue r;
    printf("Running generate_asset_allocation_lock...\n");
    GenerateBlocks(5);
    string txid;
    string newaddress1 = GetNewFundedAddress("node2");
    string newaddress = GetNewFundedAddress("node1", txid);

    BOOST_CHECK_NO_THROW(r = CallRPC("node1", "getrawtransaction " + txid + " true" ));
    UniValue voutArray = find_value(r.get_obj(), "vout");
    int vout = 0;
    for(unsigned int i = 0;i<voutArray.size();i++){
        UniValue scriptObj = find_value(voutArray[i].get_obj(), "scriptPubKey").get_obj();
        UniValue addressesArray = find_value(scriptObj, "addresses");
        for(unsigned int j = 0;j<addressesArray.size();j++){
            if(addressesArray[j].get_str() == newaddress)
                vout = i;
        }
    }
    string voutstr = itostr(vout);
    // lock outpoint so other txs can't spend through wallet auto-selection
    BOOST_CHECK_NO_THROW(CallRPC("node1", "lockunspent false \"[{\\\"txid\\\":\\\"" + txid + "\\\",\\\"vout\\\":" + voutstr + "}]\"" ));

    string guid = AssetNew("node1", newaddress, "data","''", "8", "1", "100000");

    AssetSend("node1", guid, "\"[{\\\"address\\\":\\\"" + newaddress + "\\\",\\\"amount\\\":1}]\"");
    BOOST_CHECK_NO_THROW(r = CallRPC("node1", "assetallocationinfo " + guid + " " + newaddress ));
    UniValue balance = find_value(r.get_obj(), "balance");
    BOOST_CHECK_EQUAL(AssetAmountFromValue(balance, 8), 1 * COIN);

    LockAssetAllocation("node1", guid, newaddress, txid, voutstr);

    // unlock now to test spending
    BOOST_CHECK_NO_THROW(CallRPC("node1", "lockunspent true \"[{\\\"txid\\\":\\\"" + txid + "\\\",\\\"vout\\\":" + voutstr + "}]\""));
    // cannot spend as normal through sendrawtransaction
    BOOST_CHECK_NO_THROW(r = CallRPC("node1", "createrawtransaction \"[{\\\"txid\\\":\\\"" + txid + "\\\",\\\"vout\\\":" + voutstr + "}]\" \"[{\\\"" + newaddress1 + "\\\":0.01}]\"", true, false));
	printf("createraw %s\n", r.get_str());
    BOOST_CHECK_NO_THROW(r = CallRPC("node1", "signrawtransactionwithwallet " + r.get_str()));
    string hex_str = find_value(r.get_obj(), "hex").get_str();
    BOOST_CHECK_NO_THROW(r = CallRPC("node1", "testmempoolaccept \"[\\\"" + hex_str + "\\\"]\""));
    BOOST_CHECK(find_value(r.get_array()[0].get_obj(), "allowed").get_bool());
    BOOST_CHECK_THROW(r = CallRPC("node1", "sendrawtransaction " + hex_str, true, false), runtime_error);

    string txid0 = AssetAllocationTransfer(false, "node1", guid, newaddress, "\"[{\\\"address\\\":\\\"" + newaddress1 + "\\\",\\\"amount\\\":0.11}]\"");
    BOOST_CHECK_NO_THROW(r = CallRPC("node1", "assetallocationinfo " + guid + " " + newaddress1 ));
    balance = find_value(r.get_obj(), "balance");
    BOOST_CHECK_EQUAL(AssetAmountFromValue(balance, 8), 0.11 * COIN);
    BOOST_CHECK_NO_THROW(r = CallRPC("node1", "getrawtransaction " + txid0 + " true" ));
    UniValue vinArray = find_value(r.get_obj(), "vin");
    bool found = false;
    for(unsigned int i = 0;i<vinArray.size();i++){
        if(find_value(vinArray[i].get_obj(), "txid").get_str() == txid && find_value(vinArray[i].get_obj(), "vout").get_int() == vout){
            found = true;
            break;
        }
    }
    BOOST_CHECK(found);

}
BOOST_AUTO_TEST_CASE(generate_asset_allocation_send_address)
{
	UniValue r;
	printf("Running generate_asset_allocation_send_address...\n");
	GenerateBlocks(5);
    GenerateBlocks(101, "node2");
	string newaddress1 = GetNewFundedAddress("node1");
    CallRPC("node2", "sendtoaddress " + newaddress1 + " 1", true, false);
    CallRPC("node2", "sendtoaddress " + newaddress1 + " 1", true, false);
	GenerateBlocks(5);
	GenerateBlocks(5, "node2");
    BOOST_CHECK_NO_THROW(r = CallExtRPC("node1", "getnewaddress"));
    string newaddress2 = r.get_str();

	string guid = AssetNew("node1", newaddress1, "data","''", "8", "1", "100000");

	AssetSend("node1", guid, "\"[{\\\"address\\\":\\\"" + newaddress1 + "\\\",\\\"amount\\\":1}]\"");
	BOOST_CHECK_NO_THROW(r = CallRPC("node1", "assetallocationinfo " + guid + " " + newaddress1 ));
	UniValue balance = find_value(r.get_obj(), "balance");
	BOOST_CHECK_EQUAL(AssetAmountFromValue(balance, 8), 1 * COIN);

	string txid0 = AssetAllocationTransfer(false, "node1", guid, newaddress1, "\"[{\\\"address\\\":\\\"" + newaddress2 + "\\\",\\\"amount\\\":0.11}]\"");
	BOOST_CHECK_NO_THROW(r = CallRPC("node1", "assetallocationinfo " + guid + " " + newaddress2 ));
	balance = find_value(r.get_obj(), "balance");
	BOOST_CHECK_EQUAL(AssetAmountFromValue(balance, 8), 0.11 * COIN);

	BOOST_CHECK_NO_THROW(r = CallRPC("node1", "assetallocationsenderstatus " + guid + " " + newaddress1 + " " + txid0));
	BOOST_CHECK_EQUAL(find_value(r.get_obj(), "status").get_int(), ZDAG_NOT_FOUND);

	// send using zdag
	string txid1 = AssetAllocationTransfer(true, "node1", guid, newaddress1, "\"[{\\\"address\\\":\\\"" + newaddress2 + "\\\",\\\"amount\\\":0.12}]\"");
	BOOST_CHECK_NO_THROW(r = CallRPC("node1", "assetallocationinfo " + guid + " " + newaddress2));
	balance = find_value(r.get_obj(), "balance_zdag");
	BOOST_CHECK_EQUAL(AssetAmountFromValue(balance, 8), 0.23 * COIN);

	// non zdag cannot be found since it was already mined, but ends up briefly in conflict state because sender is conflicted
	BOOST_CHECK_NO_THROW(r = CallRPC("node1", "assetallocationsenderstatus " + guid + " " + newaddress1 + " " + txid0));
	BOOST_CHECK_EQUAL(find_value(r.get_obj(), "status").get_int(), ZDAG_MINOR_CONFLICT);

	// first tx should have to wait 1 sec for good status
	BOOST_CHECK_NO_THROW(r = CallRPC("node1", "assetallocationsenderstatus " + guid + " " + newaddress1 + " " + txid1));
	BOOST_CHECK_EQUAL(find_value(r.get_obj(), "status").get_int(), ZDAG_MINOR_CONFLICT);

	// check just sender
	BOOST_CHECK_NO_THROW(r = CallRPC("node1", "assetallocationsenderstatus " + guid + " " + newaddress1 + " ''"));
	BOOST_CHECK_EQUAL(find_value(r.get_obj(), "status").get_int(), ZDAG_MINOR_CONFLICT);

	// wait for 1 second as required by unit test
	MilliSleep(1000);
	// second send
	string txid2 = AssetAllocationTransfer(true, "node1", guid, newaddress1, "\"[{\\\"address\\\":\\\"" + newaddress2 + "\\\",\\\"amount\\\":0.13}]\"");
	BOOST_CHECK_NO_THROW(r = CallRPC("node1", "assetallocationinfo " + guid + " " + newaddress2 ));
	balance = find_value(r.get_obj(), "balance_zdag");
	BOOST_CHECK_EQUAL(AssetAmountFromValue(balance, 8), 0.36 * COIN);

	// sender is conflicted so txid0 is conflicted by extension even if its not found
	BOOST_CHECK_NO_THROW(r = CallRPC("node1", "assetallocationsenderstatus " + guid + " " + newaddress1 + " " + txid0));
	BOOST_CHECK_EQUAL(find_value(r.get_obj(), "status").get_int(), ZDAG_MINOR_CONFLICT);

	// first ones now OK because it was found explicitly
	BOOST_CHECK_NO_THROW(r = CallRPC("node1", "assetallocationsenderstatus " + guid + " " + newaddress1 + " " + txid1));
	BOOST_CHECK_EQUAL(find_value(r.get_obj(), "status").get_int(), ZDAG_STATUS_OK);

	// second one hasn't waited enough time yet
	BOOST_CHECK_NO_THROW(r = CallRPC("node1", "assetallocationsenderstatus " + guid + " " + newaddress1 + " " + txid2));
	BOOST_CHECK_EQUAL(find_value(r.get_obj(), "status").get_int(), ZDAG_MINOR_CONFLICT);

	// check just sender
	BOOST_CHECK_NO_THROW(r = CallRPC("node1", "assetallocationsenderstatus " + guid + " " + newaddress1 + " ''"));
	BOOST_CHECK_EQUAL(find_value(r.get_obj(), "status").get_int(), ZDAG_MINOR_CONFLICT);

	// wait for 1.5 second to clear minor warning status
	MilliSleep(1500);
	BOOST_CHECK_NO_THROW(r = CallRPC("node1", "assetallocationsenderstatus " + guid + " " + newaddress1 + " " + txid0));
	BOOST_CHECK_EQUAL(find_value(r.get_obj(), "status").get_int(), ZDAG_NOT_FOUND);

	BOOST_CHECK_NO_THROW(r = CallRPC("node1", "assetallocationsenderstatus " + guid + " " + newaddress1 + " " + txid1));
	BOOST_CHECK_EQUAL(find_value(r.get_obj(), "status").get_int(), ZDAG_STATUS_OK);

	BOOST_CHECK_NO_THROW(r = CallRPC("node1", "assetallocationsenderstatus " + guid + " " + newaddress1 + " " + txid2));
	BOOST_CHECK_EQUAL(find_value(r.get_obj(), "status").get_int(), ZDAG_STATUS_OK);

	// check just sender as well
	BOOST_CHECK_NO_THROW(r = CallRPC("node1", "assetallocationsenderstatus " + guid + " " + newaddress1 + " ''"));
	BOOST_CHECK_EQUAL(find_value(r.get_obj(), "status").get_int(), ZDAG_STATUS_OK);

	// after pow, should get not found on all of them
	GenerateBlocks(1);

	BOOST_CHECK_NO_THROW(r = CallRPC("node1", "assetallocationsenderstatus " + guid + " " + newaddress1 + " " + txid0));
	BOOST_CHECK_EQUAL(find_value(r.get_obj(), "status").get_int(), ZDAG_NOT_FOUND);

	BOOST_CHECK_NO_THROW(r = CallRPC("node1", "assetallocationsenderstatus " + guid + " " + newaddress1 + " " + txid1));
	BOOST_CHECK_EQUAL(find_value(r.get_obj(), "status").get_int(), ZDAG_NOT_FOUND);

	BOOST_CHECK_NO_THROW(r = CallRPC("node1", "assetallocationsenderstatus " + guid + " " + newaddress1 + " " + txid2));
	BOOST_CHECK_EQUAL(find_value(r.get_obj(), "status").get_int(), ZDAG_NOT_FOUND);

	// check just sender as well
	BOOST_CHECK_NO_THROW(r = CallRPC("node1", "assetallocationsenderstatus " + guid + " " + newaddress1 + " ''"));
	BOOST_CHECK_EQUAL(find_value(r.get_obj(), "status").get_int(), ZDAG_NOT_FOUND);
    ECC_Stop();
}
BOOST_AUTO_TEST_SUITE_END ()
<commit_msg>printf fix<commit_after>// Copyright (c) 2016-2018 The Syscoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <test/test_syscoin_services.h>
#include <util/time.h>
#include <rpc/server.h>
#include <services/asset.h>
#include <base58.h>
#include <chainparams.h>
#include <boost/test/unit_test.hpp>
#include <iterator>
#include <key.h>
using namespace std;
BOOST_GLOBAL_FIXTURE( SyscoinTestingSetup );
BOOST_FIXTURE_TEST_SUITE(syscoin_asset_allocation_tests, BasicSyscoinTestingSetup)

BOOST_AUTO_TEST_CASE(generate_asset_allocation_address_sync)
{
	UniValue r;
	printf("Running generate_asset_allocation_address_sync...\n");
	GenerateBlocks(5);
	string newaddress = GetNewFundedAddress("node1");
    BOOST_CHECK_NO_THROW(r = CallExtRPC("node1", "getnewaddress"));
    string newaddressreceiver = r.get_str();
	string guid = AssetNew("node1", newaddress, "data", "''", "8", "10000", "1000000");

	AssetSend("node1", guid, "\"[{\\\"address\\\":\\\"" + newaddressreceiver + "\\\",\\\"amount\\\":5000}]\"");
	BOOST_CHECK_NO_THROW(r = CallRPC("node1", "assetallocationinfo " + guid + " " + newaddressreceiver ));
	UniValue balance = find_value(r.get_obj(), "balance");
	BOOST_CHECK_NO_THROW(r = CallRPC("node2", "assetallocationinfo " + guid + " " + newaddressreceiver ));
	balance = find_value(r.get_obj(), "balance");
	StopNode("node2");
	StartNode("node2");
	GenerateBlocks(5, "node2");
	BOOST_CHECK_NO_THROW(r = CallRPC("node1", "assetallocationinfo " + guid + " " + newaddressreceiver ));
	balance = find_value(r.get_obj(), "balance");
	BOOST_CHECK_NO_THROW(r = CallRPC("node2", "assetallocationinfo " + guid + " " + newaddressreceiver ));
	balance = find_value(r.get_obj(), "balance");

}
BOOST_AUTO_TEST_CASE(generate_asset_allocation_lock)
{
    UniValue r;
    printf("Running generate_asset_allocation_lock...\n");
    GenerateBlocks(5);
    string txid;
    string newaddress1 = GetNewFundedAddress("node2");
    string newaddress = GetNewFundedAddress("node1", txid);

    BOOST_CHECK_NO_THROW(r = CallRPC("node1", "getrawtransaction " + txid + " true" ));
    UniValue voutArray = find_value(r.get_obj(), "vout");
    int vout = 0;
    for(unsigned int i = 0;i<voutArray.size();i++){
        UniValue scriptObj = find_value(voutArray[i].get_obj(), "scriptPubKey").get_obj();
        UniValue addressesArray = find_value(scriptObj, "addresses");
        for(unsigned int j = 0;j<addressesArray.size();j++){
            if(addressesArray[j].get_str() == newaddress)
                vout = i;
        }
    }
    string voutstr = itostr(vout);
    // lock outpoint so other txs can't spend through wallet auto-selection
    BOOST_CHECK_NO_THROW(CallRPC("node1", "lockunspent false \"[{\\\"txid\\\":\\\"" + txid + "\\\",\\\"vout\\\":" + voutstr + "}]\"" ));

    string guid = AssetNew("node1", newaddress, "data","''", "8", "1", "100000");

    AssetSend("node1", guid, "\"[{\\\"address\\\":\\\"" + newaddress + "\\\",\\\"amount\\\":1}]\"");
    BOOST_CHECK_NO_THROW(r = CallRPC("node1", "assetallocationinfo " + guid + " " + newaddress ));
    UniValue balance = find_value(r.get_obj(), "balance");
    BOOST_CHECK_EQUAL(AssetAmountFromValue(balance, 8), 1 * COIN);

    LockAssetAllocation("node1", guid, newaddress, txid, voutstr);

    // unlock now to test spending
    BOOST_CHECK_NO_THROW(CallRPC("node1", "lockunspent true \"[{\\\"txid\\\":\\\"" + txid + "\\\",\\\"vout\\\":" + voutstr + "}]\""));
    // cannot spend as normal through sendrawtransaction
    BOOST_CHECK_NO_THROW(r = CallRPC("node1", "createrawtransaction \"[{\\\"txid\\\":\\\"" + txid + "\\\",\\\"vout\\\":" + voutstr + "}]\" \"[{\\\"" + newaddress1 + "\\\":0.01}]\"", true, false));
	printf("createraw %s\n", r.get_str().c_str());
    BOOST_CHECK_NO_THROW(r = CallRPC("node1", "signrawtransactionwithwallet " + r.get_str()));
    string hex_str = find_value(r.get_obj(), "hex").get_str();
    BOOST_CHECK_NO_THROW(r = CallRPC("node1", "testmempoolaccept \"[\\\"" + hex_str + "\\\"]\""));
    BOOST_CHECK(find_value(r.get_array()[0].get_obj(), "allowed").get_bool());
    BOOST_CHECK_THROW(r = CallRPC("node1", "sendrawtransaction " + hex_str, true, false), runtime_error);

    string txid0 = AssetAllocationTransfer(false, "node1", guid, newaddress, "\"[{\\\"address\\\":\\\"" + newaddress1 + "\\\",\\\"amount\\\":0.11}]\"");
    BOOST_CHECK_NO_THROW(r = CallRPC("node1", "assetallocationinfo " + guid + " " + newaddress1 ));
    balance = find_value(r.get_obj(), "balance");
    BOOST_CHECK_EQUAL(AssetAmountFromValue(balance, 8), 0.11 * COIN);
    BOOST_CHECK_NO_THROW(r = CallRPC("node1", "getrawtransaction " + txid0 + " true" ));
    UniValue vinArray = find_value(r.get_obj(), "vin");
    bool found = false;
    for(unsigned int i = 0;i<vinArray.size();i++){
        if(find_value(vinArray[i].get_obj(), "txid").get_str() == txid && find_value(vinArray[i].get_obj(), "vout").get_int() == vout){
            found = true;
            break;
        }
    }
    BOOST_CHECK(found);

}
BOOST_AUTO_TEST_CASE(generate_asset_allocation_send_address)
{
	UniValue r;
	printf("Running generate_asset_allocation_send_address...\n");
	GenerateBlocks(5);
    GenerateBlocks(101, "node2");
	string newaddress1 = GetNewFundedAddress("node1");
    CallRPC("node2", "sendtoaddress " + newaddress1 + " 1", true, false);
    CallRPC("node2", "sendtoaddress " + newaddress1 + " 1", true, false);
	GenerateBlocks(5);
	GenerateBlocks(5, "node2");
    BOOST_CHECK_NO_THROW(r = CallExtRPC("node1", "getnewaddress"));
    string newaddress2 = r.get_str();

	string guid = AssetNew("node1", newaddress1, "data","''", "8", "1", "100000");

	AssetSend("node1", guid, "\"[{\\\"address\\\":\\\"" + newaddress1 + "\\\",\\\"amount\\\":1}]\"");
	BOOST_CHECK_NO_THROW(r = CallRPC("node1", "assetallocationinfo " + guid + " " + newaddress1 ));
	UniValue balance = find_value(r.get_obj(), "balance");
	BOOST_CHECK_EQUAL(AssetAmountFromValue(balance, 8), 1 * COIN);

	string txid0 = AssetAllocationTransfer(false, "node1", guid, newaddress1, "\"[{\\\"address\\\":\\\"" + newaddress2 + "\\\",\\\"amount\\\":0.11}]\"");
	BOOST_CHECK_NO_THROW(r = CallRPC("node1", "assetallocationinfo " + guid + " " + newaddress2 ));
	balance = find_value(r.get_obj(), "balance");
	BOOST_CHECK_EQUAL(AssetAmountFromValue(balance, 8), 0.11 * COIN);

	BOOST_CHECK_NO_THROW(r = CallRPC("node1", "assetallocationsenderstatus " + guid + " " + newaddress1 + " " + txid0));
	BOOST_CHECK_EQUAL(find_value(r.get_obj(), "status").get_int(), ZDAG_NOT_FOUND);

	// send using zdag
	string txid1 = AssetAllocationTransfer(true, "node1", guid, newaddress1, "\"[{\\\"address\\\":\\\"" + newaddress2 + "\\\",\\\"amount\\\":0.12}]\"");
	BOOST_CHECK_NO_THROW(r = CallRPC("node1", "assetallocationinfo " + guid + " " + newaddress2));
	balance = find_value(r.get_obj(), "balance_zdag");
	BOOST_CHECK_EQUAL(AssetAmountFromValue(balance, 8), 0.23 * COIN);

	// non zdag cannot be found since it was already mined, but ends up briefly in conflict state because sender is conflicted
	BOOST_CHECK_NO_THROW(r = CallRPC("node1", "assetallocationsenderstatus " + guid + " " + newaddress1 + " " + txid0));
	BOOST_CHECK_EQUAL(find_value(r.get_obj(), "status").get_int(), ZDAG_MINOR_CONFLICT);

	// first tx should have to wait 1 sec for good status
	BOOST_CHECK_NO_THROW(r = CallRPC("node1", "assetallocationsenderstatus " + guid + " " + newaddress1 + " " + txid1));
	BOOST_CHECK_EQUAL(find_value(r.get_obj(), "status").get_int(), ZDAG_MINOR_CONFLICT);

	// check just sender
	BOOST_CHECK_NO_THROW(r = CallRPC("node1", "assetallocationsenderstatus " + guid + " " + newaddress1 + " ''"));
	BOOST_CHECK_EQUAL(find_value(r.get_obj(), "status").get_int(), ZDAG_MINOR_CONFLICT);

	// wait for 1 second as required by unit test
	MilliSleep(1000);
	// second send
	string txid2 = AssetAllocationTransfer(true, "node1", guid, newaddress1, "\"[{\\\"address\\\":\\\"" + newaddress2 + "\\\",\\\"amount\\\":0.13}]\"");
	BOOST_CHECK_NO_THROW(r = CallRPC("node1", "assetallocationinfo " + guid + " " + newaddress2 ));
	balance = find_value(r.get_obj(), "balance_zdag");
	BOOST_CHECK_EQUAL(AssetAmountFromValue(balance, 8), 0.36 * COIN);

	// sender is conflicted so txid0 is conflicted by extension even if its not found
	BOOST_CHECK_NO_THROW(r = CallRPC("node1", "assetallocationsenderstatus " + guid + " " + newaddress1 + " " + txid0));
	BOOST_CHECK_EQUAL(find_value(r.get_obj(), "status").get_int(), ZDAG_MINOR_CONFLICT);

	// first ones now OK because it was found explicitly
	BOOST_CHECK_NO_THROW(r = CallRPC("node1", "assetallocationsenderstatus " + guid + " " + newaddress1 + " " + txid1));
	BOOST_CHECK_EQUAL(find_value(r.get_obj(), "status").get_int(), ZDAG_STATUS_OK);

	// second one hasn't waited enough time yet
	BOOST_CHECK_NO_THROW(r = CallRPC("node1", "assetallocationsenderstatus " + guid + " " + newaddress1 + " " + txid2));
	BOOST_CHECK_EQUAL(find_value(r.get_obj(), "status").get_int(), ZDAG_MINOR_CONFLICT);

	// check just sender
	BOOST_CHECK_NO_THROW(r = CallRPC("node1", "assetallocationsenderstatus " + guid + " " + newaddress1 + " ''"));
	BOOST_CHECK_EQUAL(find_value(r.get_obj(), "status").get_int(), ZDAG_MINOR_CONFLICT);

	// wait for 1.5 second to clear minor warning status
	MilliSleep(1500);
	BOOST_CHECK_NO_THROW(r = CallRPC("node1", "assetallocationsenderstatus " + guid + " " + newaddress1 + " " + txid0));
	BOOST_CHECK_EQUAL(find_value(r.get_obj(), "status").get_int(), ZDAG_NOT_FOUND);

	BOOST_CHECK_NO_THROW(r = CallRPC("node1", "assetallocationsenderstatus " + guid + " " + newaddress1 + " " + txid1));
	BOOST_CHECK_EQUAL(find_value(r.get_obj(), "status").get_int(), ZDAG_STATUS_OK);

	BOOST_CHECK_NO_THROW(r = CallRPC("node1", "assetallocationsenderstatus " + guid + " " + newaddress1 + " " + txid2));
	BOOST_CHECK_EQUAL(find_value(r.get_obj(), "status").get_int(), ZDAG_STATUS_OK);

	// check just sender as well
	BOOST_CHECK_NO_THROW(r = CallRPC("node1", "assetallocationsenderstatus " + guid + " " + newaddress1 + " ''"));
	BOOST_CHECK_EQUAL(find_value(r.get_obj(), "status").get_int(), ZDAG_STATUS_OK);

	// after pow, should get not found on all of them
	GenerateBlocks(1);

	BOOST_CHECK_NO_THROW(r = CallRPC("node1", "assetallocationsenderstatus " + guid + " " + newaddress1 + " " + txid0));
	BOOST_CHECK_EQUAL(find_value(r.get_obj(), "status").get_int(), ZDAG_NOT_FOUND);

	BOOST_CHECK_NO_THROW(r = CallRPC("node1", "assetallocationsenderstatus " + guid + " " + newaddress1 + " " + txid1));
	BOOST_CHECK_EQUAL(find_value(r.get_obj(), "status").get_int(), ZDAG_NOT_FOUND);

	BOOST_CHECK_NO_THROW(r = CallRPC("node1", "assetallocationsenderstatus " + guid + " " + newaddress1 + " " + txid2));
	BOOST_CHECK_EQUAL(find_value(r.get_obj(), "status").get_int(), ZDAG_NOT_FOUND);

	// check just sender as well
	BOOST_CHECK_NO_THROW(r = CallRPC("node1", "assetallocationsenderstatus " + guid + " " + newaddress1 + " ''"));
	BOOST_CHECK_EQUAL(find_value(r.get_obj(), "status").get_int(), ZDAG_NOT_FOUND);
    ECC_Stop();
}
BOOST_AUTO_TEST_SUITE_END ()
<|endoftext|>


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

#include "src/trace_processor/export_json.h"

#include "perfetto/base/temp_file.h"

#include "gmock/gmock.h"
#include "gtest/gtest.h"

#include <json/reader.h>
#include <json/value.h>

namespace perfetto {
namespace trace_processor {
namespace json {
namespace {

std::string ReadFile(FILE* input) {
  fseek(input, 0, SEEK_SET);
  const int kBufSize = 1000;
  char buffer[kBufSize];
  fread(buffer, sizeof(char), kBufSize, input);
  return std::string(buffer);
}

TEST(ExportJsonTest, EmptyStorage) {
  TraceStorage storage;

  base::TempFile temp_file = base::TempFile::Create();
  FILE* output = fopen(temp_file.path().c_str(), "w+");
  int code = ExportJson(&storage, output);

  EXPECT_EQ(code, kResultOk);

  Json::Reader reader;
  Json::Value result;

  EXPECT_TRUE(reader.parse(ReadFile(output), result));
  EXPECT_EQ(result["traceEvents"].size(), 0);
}

TEST(ExportJsonTest, StorageWithOneSlice) {
  const int64_t kTimestamp = 10000000;
  const int64_t kDuration = 10000;
  const int64_t kThreadID = 100;
  const char* kCategory = "cat";
  const char* kName = "name";

  TraceStorage storage;
  UniqueTid utid = storage.AddEmptyThread(kThreadID);
  StringId cat_id = storage.InternString(base::StringView(kCategory));
  StringId name_id = storage.InternString(base::StringView(kName));
  storage.mutable_nestable_slices()->AddSlice(
      kTimestamp, kDuration, utid, RefType::kRefUtid, cat_id, name_id, 0, 0, 0);

  base::TempFile temp_file = base::TempFile::Create();
  FILE* output = fopen(temp_file.path().c_str(), "w+");
  int code = ExportJson(&storage, output);

  EXPECT_EQ(code, kResultOk);

  Json::Reader reader;
  Json::Value result;
  EXPECT_TRUE(reader.parse(ReadFile(output), result));
  EXPECT_EQ(result["traceEvents"].size(), 1);

  Json::Value event = result["traceEvents"][0];
  EXPECT_EQ(event["ph"].asString(), "X");
  EXPECT_EQ(event["ts"].asInt64(), kTimestamp / 1000);
  EXPECT_EQ(event["dur"].asInt64(), kDuration / 1000);
  EXPECT_EQ(event["tid"].asUInt(), kThreadID);
  EXPECT_EQ(event["cat"].asString(), kCategory);
  EXPECT_EQ(event["name"].asString(), kName);
}

TEST(ExportJsonTest, StorageWithThreadName) {
  const int64_t kThreadID = 100;
  const char* kName = "thread";

  TraceStorage storage;
  UniqueTid utid = storage.AddEmptyThread(kThreadID);
  StringId name_id = storage.InternString(base::StringView(kName));
  storage.GetMutableThread(utid)->name_id = name_id;

  base::TempFile temp_file = base::TempFile::Create();
  FILE* output = fopen(temp_file.path().c_str(), "w+");
  int code = ExportJson(&storage, output);

  EXPECT_EQ(code, kResultOk);

  Json::Reader reader;
  Json::Value result;
  EXPECT_TRUE(reader.parse(ReadFile(output), result));
  EXPECT_EQ(result["traceEvents"].size(), 1);

  Json::Value event = result["traceEvents"][0];
  EXPECT_EQ(event["ph"].asString(), "M");
  EXPECT_EQ(event["tid"].asUInt(), kThreadID);
  EXPECT_EQ(event["name"].asString(), "thread_name");
  EXPECT_EQ(event["args"]["name"].asString(), kName);
}

TEST(ExportJsonTest, WrongRefType) {
  TraceStorage storage;
  storage.mutable_nestable_slices()->AddSlice(0, 0, 0, RefType::kRefCpuId, 0, 0,
                                              0, 0, 0);

  base::TempFile temp_file = base::TempFile::Create();
  FILE* output = fopen(temp_file.path().c_str(), "w+");
  int code = ExportJson(&storage, output);

  EXPECT_EQ(code, kResultWrongRefType);
}

}  // namespace
}  // namespace json
}  // namespace trace_processor
}  // namespace perfetto
<commit_msg>trace_processor: fix gcc compile<commit_after>/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "src/trace_processor/export_json.h"

#include "perfetto/base/temp_file.h"

#include "gmock/gmock.h"
#include "gtest/gtest.h"

#include <json/reader.h>
#include <json/value.h>

namespace perfetto {
namespace trace_processor {
namespace json {
namespace {

std::string ReadFile(FILE* input) {
  fseek(input, 0, SEEK_SET);
  const int kBufSize = 1000;
  char buffer[kBufSize];
  EXPECT_GT(fread(buffer, sizeof(char), kBufSize, input), 0);
  return std::string(buffer);
}

TEST(ExportJsonTest, EmptyStorage) {
  TraceStorage storage;

  base::TempFile temp_file = base::TempFile::Create();
  FILE* output = fopen(temp_file.path().c_str(), "w+");
  int code = ExportJson(&storage, output);

  EXPECT_EQ(code, kResultOk);

  Json::Reader reader;
  Json::Value result;

  EXPECT_TRUE(reader.parse(ReadFile(output), result));
  EXPECT_EQ(result["traceEvents"].size(), 0);
}

TEST(ExportJsonTest, StorageWithOneSlice) {
  const int64_t kTimestamp = 10000000;
  const int64_t kDuration = 10000;
  const int64_t kThreadID = 100;
  const char* kCategory = "cat";
  const char* kName = "name";

  TraceStorage storage;
  UniqueTid utid = storage.AddEmptyThread(kThreadID);
  StringId cat_id = storage.InternString(base::StringView(kCategory));
  StringId name_id = storage.InternString(base::StringView(kName));
  storage.mutable_nestable_slices()->AddSlice(
      kTimestamp, kDuration, utid, RefType::kRefUtid, cat_id, name_id, 0, 0, 0);

  base::TempFile temp_file = base::TempFile::Create();
  FILE* output = fopen(temp_file.path().c_str(), "w+");
  int code = ExportJson(&storage, output);

  EXPECT_EQ(code, kResultOk);

  Json::Reader reader;
  Json::Value result;
  EXPECT_TRUE(reader.parse(ReadFile(output), result));
  EXPECT_EQ(result["traceEvents"].size(), 1);

  Json::Value event = result["traceEvents"][0];
  EXPECT_EQ(event["ph"].asString(), "X");
  EXPECT_EQ(event["ts"].asInt64(), kTimestamp / 1000);
  EXPECT_EQ(event["dur"].asInt64(), kDuration / 1000);
  EXPECT_EQ(event["tid"].asUInt(), kThreadID);
  EXPECT_EQ(event["cat"].asString(), kCategory);
  EXPECT_EQ(event["name"].asString(), kName);
}

TEST(ExportJsonTest, StorageWithThreadName) {
  const int64_t kThreadID = 100;
  const char* kName = "thread";

  TraceStorage storage;
  UniqueTid utid = storage.AddEmptyThread(kThreadID);
  StringId name_id = storage.InternString(base::StringView(kName));
  storage.GetMutableThread(utid)->name_id = name_id;

  base::TempFile temp_file = base::TempFile::Create();
  FILE* output = fopen(temp_file.path().c_str(), "w+");
  int code = ExportJson(&storage, output);

  EXPECT_EQ(code, kResultOk);

  Json::Reader reader;
  Json::Value result;
  EXPECT_TRUE(reader.parse(ReadFile(output), result));
  EXPECT_EQ(result["traceEvents"].size(), 1);

  Json::Value event = result["traceEvents"][0];
  EXPECT_EQ(event["ph"].asString(), "M");
  EXPECT_EQ(event["tid"].asUInt(), kThreadID);
  EXPECT_EQ(event["name"].asString(), "thread_name");
  EXPECT_EQ(event["args"]["name"].asString(), kName);
}

TEST(ExportJsonTest, WrongRefType) {
  TraceStorage storage;
  storage.mutable_nestable_slices()->AddSlice(0, 0, 0, RefType::kRefCpuId, 0, 0,
                                              0, 0, 0);

  base::TempFile temp_file = base::TempFile::Create();
  FILE* output = fopen(temp_file.path().c_str(), "w+");
  int code = ExportJson(&storage, output);

  EXPECT_EQ(code, kResultWrongRefType);
}

}  // namespace
}  // namespace json
}  // namespace trace_processor
}  // namespace perfetto
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: property.hxx,v $
 *
 *  $Revision: 1.21 $
 *
 *  last change: $Author: rt $ $Date: 2005-01-11 14:06:08 $
 *
 *  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 _TOOLKIT_HELPER_PROPERTY_HXX_
#define _TOOLKIT_HELPER_PROPERTY_HXX_

#ifndef TOOLKIT_DLLAPI_H
#include <toolkit/dllapi.h>
#endif

#include <sal/types.h>

namespace com {
namespace sun {
namespace star {
namespace uno {
    class Type;
    class Any;
} } } }

namespace rtl {
    class OUString;
}

#define BASEPROPERTY_NOTFOUND                0

#define BASEPROPERTY_TEXT                    1  // ::rtl::OUString
#define BASEPROPERTY_BACKGROUNDCOLOR         2  // sal_Int32
#define BASEPROPERTY_FILLCOLOR               3  // sal_Int32
#define BASEPROPERTY_TEXTCOLOR               4  // sal_Int32
#define BASEPROPERTY_LINECOLOR               5  // sal_Int32
#define BASEPROPERTY_BORDER                  6  // sal_Int16
#define BASEPROPERTY_ALIGN                   7  // sal_Int16
#define BASEPROPERTY_FONTDESCRIPTOR          8  // ::com::sun::star::awt::FontDescriptor, war mal Font, aber nie gespeichert...
#define BASEPROPERTY_DROPDOWN                9  // sal_Bool
#define BASEPROPERTY_MULTILINE              10  // sal_Bool
#define BASEPROPERTY_STRINGITEMLIST         11  // UStringSequence
#define BASEPROPERTY_HSCROLL                12  // sal_Bool
#define BASEPROPERTY_VSCROLL                13  // sal_Bool
#define BASEPROPERTY_TABSTOP                14  // sal_Bool
#define BASEPROPERTY_STATE                  15  // sal_Int16
#define BASEPROPERTY_FONT_TYPE              16  // OLD: Font_Type
#define BASEPROPERTY_FONT_SIZE              17  // OLD: Font_Size
#define BASEPROPERTY_FONT_ATTRIBS           18  // OLD: Font_Attribs
#define BASEPROPERTY_DEFAULTCONTROL         19  // ::rtl::OUString (ServiceName)
#define BASEPROPERTY_LABEL                  20  // ::rtl::OUString
#define BASEPROPERTY_LINECOUNT              21  // sal_Int16
#define BASEPROPERTY_EXTDATEFORMAT          22  // sal_Int16
#define BASEPROPERTY_DATESHOWCENTURY        23  // sal_Bool
#define BASEPROPERTY_EXTTIMEFORMAT          24  // sal_Int16
#define BASEPROPERTY_NUMSHOWTHOUSANDSEP     25  // sal_Bool
#define BASEPROPERTY_CURRENCYSYMBOL         26  // ::rtl::OUString
#define BASEPROPERTY_SPIN                   27  // sal_Bool
#define BASEPROPERTY_STRICTFORMAT           28  // sal_Bool
#define BASEPROPERTY_DECIMALACCURACY        29  // sal_Int16
#define BASEPROPERTY_DATE                   30  // sal_Int32
#define BASEPROPERTY_DATEMIN                31  // sal_Int32
#define BASEPROPERTY_DATEMAX                32  // sal_Int32
#define BASEPROPERTY_TIME                   33  // sal_Int32
#define BASEPROPERTY_TIMEMIN                34  // sal_Int32
#define BASEPROPERTY_TIMEMAX                35  // sal_Int32
#define BASEPROPERTY_VALUE_INT32            36  // sal_Int32
#define BASEPROPERTY_VALUEMIN_INT32         37  // sal_Int32
#define BASEPROPERTY_VALUEMAX_INT32         38  // sal_Int32
#define BASEPROPERTY_VALUESTEP_INT32        39  // sal_Int32
#define BASEPROPERTY_EDITMASK               40  // ::rtl::OUString
#define BASEPROPERTY_LITERALMASK            41  // ::rtl::OUString
#define BASEPROPERTY_IMAGEURL               42  // ::rtl::OUString
#define BASEPROPERTY_READONLY               43  // sal_Bool
#define BASEPROPERTY_ENABLED                44  // sal_Bool
#define BASEPROPERTY_PRINTABLE              45  // sal_Bool
#define BASEPROPERTY_ECHOCHAR               46  // sal_Int16
#define BASEPROPERTY_MAXTEXTLEN             47  // sal_Int16
#define BASEPROPERTY_HARDLINEBREAKS         48  // sal_Int16
#define BASEPROPERTY_AUTOCOMPLETE           49  // sal_Bool
#define BASEPROPERTY_MULTISELECTION         50  // sal_Bool
#define BASEPROPERTY_SELECTEDITEMS          51  // INT16Sequence
#define BASEPROPERTY_VALUE_DOUBLE           52  // DOUBLE
#define BASEPROPERTY_VALUEMIN_DOUBLE        53  // DOUBLE
#define BASEPROPERTY_VALUEMAX_DOUBLE        54  // DOUBLE
#define BASEPROPERTY_VALUESTEP_DOUBLE       55  // DOUBLE
#define BASEPROPERTY_TRISTATE               56  // sal_Bool
#define BASEPROPERTY_DEFAULTBUTTON          57  // sal_Bool
#define BASEPROPERTY_HELPURL                58  // ::rtl::OUString
#define BASEPROPERTY_AUTOTOGGLE             59  // sal_Bool
//#define BASEPROPERTY_FOCUSSELECTIONHIDE       60  // sal_Bool
#define BASEPROPERTY_FORMATKEY              61  // sal_Bool
#define BASEPROPERTY_FORMATSSUPPLIER        62  // ::com::sun::star::util::XNumberFormatsSupplier
#define BASEPROPERTY_EFFECTIVE_VALUE        63  // Any (double or string)
#define BASEPROPERTY_TREATASNUMBER          64  // sal_Bool
#define BASEPROPERTY_EFFECTIVE_DEFAULT      65  // Any (double or string)
#define BASEPROPERTY_EFFECTIVE_MIN          66  // Double
#define BASEPROPERTY_EFFECTIVE_MAX          67  // Double
#define BASEPROPERTY_CURSYM_POSITION        68  // sal_Bool
#define BASEPROPERTY_TITLE                  69  // ::rtl::OUString
#define BASEPROPERTY_MOVEABLE               70  // sal_Bool
#define BASEPROPERTY_CLOSEABLE              71  // sal_Bool
#define BASEPROPERTY_SIZEABLE               72  // sal_Bool
#define BASEPROPERTY_HELPTEXT               73  // ::rtl::OUString
#define BASEPROPERTY_PROGRESSVALUE          74  // sal_Int32
#define BASEPROPERTY_PROGRESSVALUE_MIN      75  // sal_Int32
#define BASEPROPERTY_PROGRESSVALUE_MAX      76  // sal_Int32
#define BASEPROPERTY_SCROLLVALUE            77  // sal_Int32
#define BASEPROPERTY_SCROLLVALUE_MAX        78  // sal_Int32
#define BASEPROPERTY_LINEINCREMENT          79  // sal_Int32
#define BASEPROPERTY_BLOCKINCREMENT         80  // sal_Int32
#define BASEPROPERTY_VISIBLESIZE            81  // sal_Int32
#define BASEPROPERTY_ORIENTATION            82  // sal_Int32
#define BASEPROPERTY_FONTRELIEF             83  // sal_Int16
#define BASEPROPERTY_FONTEMPHASISMARK       84  // sal_Int16
#define BASEPROPERTY_TEXTLINECOLOR          85  // sal_Int32
#define BASEPROPERTY_IMAGEALIGN             86  // sal_Int16
#define BASEPROPERTY_SCALEIMAGE             87  // sal_Bool
#define BASEPROPERTY_PUSHBUTTONTYPE         88  // sal_Int16
#define BASEPROPERTY_DISPLAYBACKGROUNDCOLOR 89  // sal_Int32
#define BASEPROPERTY_AUTOMNEMONICS          90  // sal_Bool
#define BASEPROPERTY_MOUSETRANSPARENT       91  // sal_Bool
#define BASEPROPERTY_ACCESSIBLENAME         92  // ::rtl::OUString
#define BASEPROPERTY_PLUGINPARENT           93  // sal_Int64
#define BASEPROPERTY_SCROLLVALUE_MIN        94  // sal_Int32
#define BASEPROPERTY_REPEAT_DELAY           95  // sal_Int32
#define BASEPROPERTY_SYMBOL_COLOR           96  // sal_Int32
#define BASEPROPERTY_SPINVALUE              97  // sal_Int32
#define BASEPROPERTY_SPINVALUE_MIN          98  // sal_Int32
#define BASEPROPERTY_SPINVALUE_MAX          99  // sal_Int32
#define BASEPROPERTY_SPININCREMENT         100  // sal_Int32
#define BASEPROPERTY_REPEAT                101  // sal_Bool
#define BASEPROPERTY_ENFORCE_FORMAT        102  // sal_Bool
#define BASEPROPERTY_LIVE_SCROLL           103  // sal_Bool
#define BASEPROPERTY_LINE_END_FORMAT       104  // sal_Int16
#define BASEPROPERTY_ACTIVATED            105  // sal Bool
#define BASEPROPERTY_COMPLETE             106  // sal_Bool
#define BASEPROPERTY_CURRENTITEMID            107  // sal_Int16
#define BASEPROPERTY_TOGGLE                108  // sal_Bool
#define BASEPROPERTY_FOCUSONCLICK          109  // sal_Bool
#define BASEPROPERTY_HIDEINACTIVESELECTION 110  // sal_Bool
#define BASEPROPERTY_VISUALEFFECT          111  // sal_Int16
#define BASEPROPERTY_BORDERCOLOR           112  // sal_Int32
#define BASEPROPERTY_IMAGEPOSITION         113  // sal_Int16
#define BASEPROPERTY_NATIVE_WIDGET_LOOK    114  // sal_Bool

// Keine gebundenen Properties, werden immer aus der Property BASEPROPERTY_FONTDESCRIPTOR entnommen.
#define BASEPROPERTY_FONTDESCRIPTORPART_START           1000
#define BASEPROPERTY_FONTDESCRIPTORPART_NAME            1000    // ::rtl::OUString, not bound
#define BASEPROPERTY_FONTDESCRIPTORPART_STYLENAME       1001    // ::rtl::OUString, not bound
#define BASEPROPERTY_FONTDESCRIPTORPART_FAMILY          1002    // sal_Int16, not bound
#define BASEPROPERTY_FONTDESCRIPTORPART_CHARSET         1003    // sal_Int16, not bound
#define BASEPROPERTY_FONTDESCRIPTORPART_HEIGHT          1004    // sal_Int16, not bound
#define BASEPROPERTY_FONTDESCRIPTORPART_WEIGHT          1005    // Float, not bound
#define BASEPROPERTY_FONTDESCRIPTORPART_SLANT           1006    // sal_Int16, not bound
#define BASEPROPERTY_FONTDESCRIPTORPART_UNDERLINE       1007    // sal_Int16, not bound
#define BASEPROPERTY_FONTDESCRIPTORPART_STRIKEOUT       1008    // sal_Int16, not bound
#define BASEPROPERTY_FONTDESCRIPTORPART_WIDTH           1009    // sal_Int16, not bound
#define BASEPROPERTY_FONTDESCRIPTORPART_PITCH           1010    // sal_Int16, not bound
#define BASEPROPERTY_FONTDESCRIPTORPART_CHARWIDTH       1011    // Float, not bound
#define BASEPROPERTY_FONTDESCRIPTORPART_ORIENTATION     1012    // Float, not bound
#define BASEPROPERTY_FONTDESCRIPTORPART_KERNING         1013    // sal_Bool, not bound
#define BASEPROPERTY_FONTDESCRIPTORPART_WORDLINEMODE    1014    // sal_Bool, not bound
#define BASEPROPERTY_FONTDESCRIPTORPART_TYPE            1015    // sal_Int16, not bound
#define BASEPROPERTY_FONTDESCRIPTORPART_END             1015

#define PROPERTY_ALIGN_LEFT                     0
#define PROPERTY_ALIGN_CENTER                   1
#define PROPERTY_ALIGN_RIGHT                    2

#define PROPERTY_STATE_OFF                      0
#define PROPERTY_STATE_ON                       1
#define PROPERTY_STATE_DONTCARE                 2

TOOLKIT_DLLPUBLIC sal_uInt16        GetPropertyId( const ::rtl::OUString& rPropertyName );
const ::com::sun::star::uno::Type*  GetPropertyType( sal_uInt16 nPropertyId );
const ::rtl::OUString&              GetPropertyName( sal_uInt16 nPropertyId );
sal_Int16                           GetPropertyAttribs( sal_uInt16 nPropertyId );
sal_uInt16                          GetPropertyOrderNr( sal_uInt16 nPropertyId );
sal_Bool                            DoesDependOnOthers( sal_uInt16 nPropertyId );
sal_Bool                            CompareProperties( const ::com::sun::star::uno::Any& r1, const ::com::sun::star::uno::Any& r2 );

#endif // _TOOLKIT_HELPER_PROPERTY_HXX_

<commit_msg>INTEGRATION: CWS dba22 (1.20.20); FILE MERGED 2005/01/19 17:23:00 fs 1.20.20.2: RESYNC: (1.20-1.21); FILE MERGED 2004/12/29 11:10:43 fs 1.20.20.1: #i34551# vertical alignment<commit_after>/*************************************************************************
 *
 *  $RCSfile: property.hxx,v $
 *
 *  $Revision: 1.22 $
 *
 *  last change: $Author: kz $ $Date: 2005-01-21 16:46:30 $
 *
 *  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 _TOOLKIT_HELPER_PROPERTY_HXX_
#define _TOOLKIT_HELPER_PROPERTY_HXX_

#ifndef TOOLKIT_DLLAPI_H
#include <toolkit/dllapi.h>
#endif

#include <sal/types.h>

namespace com {
namespace sun {
namespace star {
namespace uno {
    class Type;
    class Any;
} } } }

namespace rtl {
    class OUString;
}

#define BASEPROPERTY_NOTFOUND                0

#define BASEPROPERTY_TEXT                    1  // ::rtl::OUString
#define BASEPROPERTY_BACKGROUNDCOLOR         2  // sal_Int32
#define BASEPROPERTY_FILLCOLOR               3  // sal_Int32
#define BASEPROPERTY_TEXTCOLOR               4  // sal_Int32
#define BASEPROPERTY_LINECOLOR               5  // sal_Int32
#define BASEPROPERTY_BORDER                  6  // sal_Int16
#define BASEPROPERTY_ALIGN                   7  // sal_Int16
#define BASEPROPERTY_FONTDESCRIPTOR          8  // ::com::sun::star::awt::FontDescriptor, war mal Font, aber nie gespeichert...
#define BASEPROPERTY_DROPDOWN                9  // sal_Bool
#define BASEPROPERTY_MULTILINE              10  // sal_Bool
#define BASEPROPERTY_STRINGITEMLIST         11  // UStringSequence
#define BASEPROPERTY_HSCROLL                12  // sal_Bool
#define BASEPROPERTY_VSCROLL                13  // sal_Bool
#define BASEPROPERTY_TABSTOP                14  // sal_Bool
#define BASEPROPERTY_STATE                  15  // sal_Int16
#define BASEPROPERTY_FONT_TYPE              16  // OLD: Font_Type
#define BASEPROPERTY_FONT_SIZE              17  // OLD: Font_Size
#define BASEPROPERTY_FONT_ATTRIBS           18  // OLD: Font_Attribs
#define BASEPROPERTY_DEFAULTCONTROL         19  // ::rtl::OUString (ServiceName)
#define BASEPROPERTY_LABEL                  20  // ::rtl::OUString
#define BASEPROPERTY_LINECOUNT              21  // sal_Int16
#define BASEPROPERTY_EXTDATEFORMAT          22  // sal_Int16
#define BASEPROPERTY_DATESHOWCENTURY        23  // sal_Bool
#define BASEPROPERTY_EXTTIMEFORMAT          24  // sal_Int16
#define BASEPROPERTY_NUMSHOWTHOUSANDSEP     25  // sal_Bool
#define BASEPROPERTY_CURRENCYSYMBOL         26  // ::rtl::OUString
#define BASEPROPERTY_SPIN                   27  // sal_Bool
#define BASEPROPERTY_STRICTFORMAT           28  // sal_Bool
#define BASEPROPERTY_DECIMALACCURACY        29  // sal_Int16
#define BASEPROPERTY_DATE                   30  // sal_Int32
#define BASEPROPERTY_DATEMIN                31  // sal_Int32
#define BASEPROPERTY_DATEMAX                32  // sal_Int32
#define BASEPROPERTY_TIME                   33  // sal_Int32
#define BASEPROPERTY_TIMEMIN                34  // sal_Int32
#define BASEPROPERTY_TIMEMAX                35  // sal_Int32
#define BASEPROPERTY_VALUE_INT32            36  // sal_Int32
#define BASEPROPERTY_VALUEMIN_INT32         37  // sal_Int32
#define BASEPROPERTY_VALUEMAX_INT32         38  // sal_Int32
#define BASEPROPERTY_VALUESTEP_INT32        39  // sal_Int32
#define BASEPROPERTY_EDITMASK               40  // ::rtl::OUString
#define BASEPROPERTY_LITERALMASK            41  // ::rtl::OUString
#define BASEPROPERTY_IMAGEURL               42  // ::rtl::OUString
#define BASEPROPERTY_READONLY               43  // sal_Bool
#define BASEPROPERTY_ENABLED                44  // sal_Bool
#define BASEPROPERTY_PRINTABLE              45  // sal_Bool
#define BASEPROPERTY_ECHOCHAR               46  // sal_Int16
#define BASEPROPERTY_MAXTEXTLEN             47  // sal_Int16
#define BASEPROPERTY_HARDLINEBREAKS         48  // sal_Int16
#define BASEPROPERTY_AUTOCOMPLETE           49  // sal_Bool
#define BASEPROPERTY_MULTISELECTION         50  // sal_Bool
#define BASEPROPERTY_SELECTEDITEMS          51  // INT16Sequence
#define BASEPROPERTY_VALUE_DOUBLE           52  // DOUBLE
#define BASEPROPERTY_VALUEMIN_DOUBLE        53  // DOUBLE
#define BASEPROPERTY_VALUEMAX_DOUBLE        54  // DOUBLE
#define BASEPROPERTY_VALUESTEP_DOUBLE       55  // DOUBLE
#define BASEPROPERTY_TRISTATE               56  // sal_Bool
#define BASEPROPERTY_DEFAULTBUTTON          57  // sal_Bool
#define BASEPROPERTY_HELPURL                58  // ::rtl::OUString
#define BASEPROPERTY_AUTOTOGGLE             59  // sal_Bool
//#define BASEPROPERTY_FOCUSSELECTIONHIDE       60  // sal_Bool
#define BASEPROPERTY_FORMATKEY              61  // sal_Bool
#define BASEPROPERTY_FORMATSSUPPLIER        62  // ::com::sun::star::util::XNumberFormatsSupplier
#define BASEPROPERTY_EFFECTIVE_VALUE        63  // Any (double or string)
#define BASEPROPERTY_TREATASNUMBER          64  // sal_Bool
#define BASEPROPERTY_EFFECTIVE_DEFAULT      65  // Any (double or string)
#define BASEPROPERTY_EFFECTIVE_MIN          66  // Double
#define BASEPROPERTY_EFFECTIVE_MAX          67  // Double
#define BASEPROPERTY_CURSYM_POSITION        68  // sal_Bool
#define BASEPROPERTY_TITLE                  69  // ::rtl::OUString
#define BASEPROPERTY_MOVEABLE               70  // sal_Bool
#define BASEPROPERTY_CLOSEABLE              71  // sal_Bool
#define BASEPROPERTY_SIZEABLE               72  // sal_Bool
#define BASEPROPERTY_HELPTEXT               73  // ::rtl::OUString
#define BASEPROPERTY_PROGRESSVALUE          74  // sal_Int32
#define BASEPROPERTY_PROGRESSVALUE_MIN      75  // sal_Int32
#define BASEPROPERTY_PROGRESSVALUE_MAX      76  // sal_Int32
#define BASEPROPERTY_SCROLLVALUE            77  // sal_Int32
#define BASEPROPERTY_SCROLLVALUE_MAX        78  // sal_Int32
#define BASEPROPERTY_LINEINCREMENT          79  // sal_Int32
#define BASEPROPERTY_BLOCKINCREMENT         80  // sal_Int32
#define BASEPROPERTY_VISIBLESIZE            81  // sal_Int32
#define BASEPROPERTY_ORIENTATION            82  // sal_Int32
#define BASEPROPERTY_FONTRELIEF             83  // sal_Int16
#define BASEPROPERTY_FONTEMPHASISMARK       84  // sal_Int16
#define BASEPROPERTY_TEXTLINECOLOR          85  // sal_Int32
#define BASEPROPERTY_IMAGEALIGN             86  // sal_Int16
#define BASEPROPERTY_SCALEIMAGE             87  // sal_Bool
#define BASEPROPERTY_PUSHBUTTONTYPE         88  // sal_Int16
#define BASEPROPERTY_DISPLAYBACKGROUNDCOLOR 89  // sal_Int32
#define BASEPROPERTY_AUTOMNEMONICS          90  // sal_Bool
#define BASEPROPERTY_MOUSETRANSPARENT       91  // sal_Bool
#define BASEPROPERTY_ACCESSIBLENAME         92  // ::rtl::OUString
#define BASEPROPERTY_PLUGINPARENT           93  // sal_Int64
#define BASEPROPERTY_SCROLLVALUE_MIN        94  // sal_Int32
#define BASEPROPERTY_REPEAT_DELAY           95  // sal_Int32
#define BASEPROPERTY_SYMBOL_COLOR           96  // sal_Int32
#define BASEPROPERTY_SPINVALUE              97  // sal_Int32
#define BASEPROPERTY_SPINVALUE_MIN          98  // sal_Int32
#define BASEPROPERTY_SPINVALUE_MAX          99  // sal_Int32
#define BASEPROPERTY_SPININCREMENT         100  // sal_Int32
#define BASEPROPERTY_REPEAT                101  // sal_Bool
#define BASEPROPERTY_ENFORCE_FORMAT        102  // sal_Bool
#define BASEPROPERTY_LIVE_SCROLL           103  // sal_Bool
#define BASEPROPERTY_LINE_END_FORMAT       104  // sal_Int16
#define BASEPROPERTY_ACTIVATED            105  // sal Bool
#define BASEPROPERTY_COMPLETE             106  // sal_Bool
#define BASEPROPERTY_CURRENTITEMID            107  // sal_Int16
#define BASEPROPERTY_TOGGLE                108  // sal_Bool
#define BASEPROPERTY_FOCUSONCLICK          109  // sal_Bool
#define BASEPROPERTY_HIDEINACTIVESELECTION 110  // sal_Bool
#define BASEPROPERTY_VISUALEFFECT          111  // sal_Int16
#define BASEPROPERTY_BORDERCOLOR           112  // sal_Int32
#define BASEPROPERTY_IMAGEPOSITION         113  // sal_Int16
#define BASEPROPERTY_NATIVE_WIDGET_LOOK    114  // sal_Bool
#define BASEPROPERTY_VERTICALALIGN         115  // VerticalAlignment

// Keine gebundenen Properties, werden immer aus der Property BASEPROPERTY_FONTDESCRIPTOR entnommen.
#define BASEPROPERTY_FONTDESCRIPTORPART_START           1000
#define BASEPROPERTY_FONTDESCRIPTORPART_NAME            1000    // ::rtl::OUString, not bound
#define BASEPROPERTY_FONTDESCRIPTORPART_STYLENAME       1001    // ::rtl::OUString, not bound
#define BASEPROPERTY_FONTDESCRIPTORPART_FAMILY          1002    // sal_Int16, not bound
#define BASEPROPERTY_FONTDESCRIPTORPART_CHARSET         1003    // sal_Int16, not bound
#define BASEPROPERTY_FONTDESCRIPTORPART_HEIGHT          1004    // sal_Int16, not bound
#define BASEPROPERTY_FONTDESCRIPTORPART_WEIGHT          1005    // Float, not bound
#define BASEPROPERTY_FONTDESCRIPTORPART_SLANT           1006    // sal_Int16, not bound
#define BASEPROPERTY_FONTDESCRIPTORPART_UNDERLINE       1007    // sal_Int16, not bound
#define BASEPROPERTY_FONTDESCRIPTORPART_STRIKEOUT       1008    // sal_Int16, not bound
#define BASEPROPERTY_FONTDESCRIPTORPART_WIDTH           1009    // sal_Int16, not bound
#define BASEPROPERTY_FONTDESCRIPTORPART_PITCH           1010    // sal_Int16, not bound
#define BASEPROPERTY_FONTDESCRIPTORPART_CHARWIDTH       1011    // Float, not bound
#define BASEPROPERTY_FONTDESCRIPTORPART_ORIENTATION     1012    // Float, not bound
#define BASEPROPERTY_FONTDESCRIPTORPART_KERNING         1013    // sal_Bool, not bound
#define BASEPROPERTY_FONTDESCRIPTORPART_WORDLINEMODE    1014    // sal_Bool, not bound
#define BASEPROPERTY_FONTDESCRIPTORPART_TYPE            1015    // sal_Int16, not bound
#define BASEPROPERTY_FONTDESCRIPTORPART_END             1015

#define PROPERTY_ALIGN_LEFT                     0
#define PROPERTY_ALIGN_CENTER                   1
#define PROPERTY_ALIGN_RIGHT                    2

#define PROPERTY_STATE_OFF                      0
#define PROPERTY_STATE_ON                       1
#define PROPERTY_STATE_DONTCARE                 2

TOOLKIT_DLLPUBLIC sal_uInt16        GetPropertyId( const ::rtl::OUString& rPropertyName );
const ::com::sun::star::uno::Type*  GetPropertyType( sal_uInt16 nPropertyId );
const ::rtl::OUString&              GetPropertyName( sal_uInt16 nPropertyId );
sal_Int16                           GetPropertyAttribs( sal_uInt16 nPropertyId );
sal_uInt16                          GetPropertyOrderNr( sal_uInt16 nPropertyId );
sal_Bool                            DoesDependOnOthers( sal_uInt16 nPropertyId );
sal_Bool                            CompareProperties( const ::com::sun::star::uno::Any& r1, const ::com::sun::star::uno::Any& r2 );

#endif // _TOOLKIT_HELPER_PROPERTY_HXX_

<|endoftext|>


<commit_before>/*********************************************************************
 *
 * Copyright (C) 2008,  Simon Kagstrom
 *
 * Filename:      basicblock.cc
 * Author:        Simon Kagstrom <simon.kagstrom@gmail.com>
 * Description:   Basic block implementation
 *
 * $Id:$
 *
 ********************************************************************/
#include <controller.hh>
#include <basicblock.hh>
#include <emit.hh>
#include <config.hh>

BasicBlock::BasicBlock(Instruction **insns,
		       bb_type_t type,
		       int first, int last) : CodeBlock()
{
  this->instructions = &(insns[first]);
  this->n_insns = last - first;
  this->type = type;

  this->address = this->instructions[0]->getAddress();
  this->size = this->n_insns * 4;
}

bool BasicBlock::pass1()
{
  bool out = true;

  for (int i = 0; i < this->n_insns; i++)
    {
      Instruction *insn = this->instructions[i];

      controller->setCurrentInstruction(insn);

      /* Compile the instruction */
      if (!insn->pass1())
	out = false;

      if ( (this->type == PROLOGUE && insn->getOpcode() == OP_SW && insn->getRs() == R_SP) ||
	   (this->type == EPILOGUE && insn->getOpcode() == OP_LW && insn->getRs() == R_SP) )
	{
	  int p_s[N_REGS];
	  int p_d[N_REGS];

	  memset(p_s, 0, sizeof(p_s));
	  memset(p_d, 0, sizeof(p_d));
	  insn->fillSources(p_s);
	  insn->fillDestinations(p_d);

	  /* Loop through all caller saved registers and for writes, simply skip them */
	  for (int j = 0;
	       mips_caller_saved[j] != R_ZERO;
	       j++)
	    {
	      MIPS_register_t reg = mips_caller_saved[j];

	      if ( (this->type == PROLOGUE && p_s[reg] != 0) ||
                   (this->type == EPILOGUE && p_d[reg] != 0) )
		{
		  this->instructions[i] = new Nop(insn->getAddress());
                  if (insn->isBranchTarget())
                    this->instructions[i]->setBranchTarget();
		  delete insn;
		  break;
		}
	    }
	}
    }

  return out;
}

static void pushRegister(MIPS_register_t reg)
{
  if (reg != R_RA)
    emit->bc_pushregister(reg);
  else
    emit->bc_pushconst(0);
}

void BasicBlock::traceRegisterValues(Instruction *insn)
{
  MIPS_register_t rs,rt,rd;

  rs = insn->getRs();
  rt = insn->getRt();
  rd = insn->getRd();

  /* Push all registers, then invoke the tracer */
  pushRegister(rs);
  pushRegister(rt);
  pushRegister(rd);

  emit->bc_invokestatic("CRunTime/emitRegisterTrace(III)V");
  if (insn->getDelayed())
    this->traceRegisterValues(insn->getDelayed());
}

void BasicBlock::commentInstruction(Instruction *insn)
{
  char buf[255];
  char out[255];

  /* Output a comment */
  int l = snprintf(buf, 255, "0x%x: ", insn->getAddress());
  l += instruction_to_string(insn, buf+l, 255);
  if (insn->hasDelaySlot())
    {
      buf[l] = ' ';
      instruction_to_string(insn->getDelayed(), buf+l+1, 255-l-1);
    }

  snprintf(out, 255, "0x%08x: %s", insn->getAddress(), buf);
  emit->bc_comment(out);

  if ( insn->getAddress() >= config->traceRange[0] && insn->getAddress() < config->traceRange[1])
    {
      emit->bc_ldc(buf);
      emit->bc_invokestatic("CRunTime/emitTrace(Ljava/lang/String;)V");
      this->traceRegisterValues(insn);
    }
}

bool BasicBlock::pass2()
{
  bool out = true;

  emit->bc_comment("--- basic block ---");
  for (int i = 0; i < this->n_insns; i++)
    {
      Instruction *insn = this->instructions[i];

      controller->setCurrentInstruction(insn);

      /* FIXME: Emit .line info if debug is on */
      if (insn->isBranchTarget() || controller->hasJumptabLabel(insn->getAddress()))
	emit->bc_label( "L_%x", insn->getAddress() );

      if (!insn->isNop())
	this->commentInstruction(insn);

      /* Compile the instruction */
      if (!insn->pass2())
	out = false;
    }

  return out;
}

int BasicBlock::fillDestinations(int *p)
{
  int out = 0;

  for (int i = 0; i < this->n_insns; i++)
    {
      Instruction *insn = this->instructions[i];
      Instruction *delayed = insn->getDelayed();
      Instruction *prefix = insn->getPrefix();

      out += insn->fillDestinations(p);
      if (delayed)
        out += delayed->fillDestinations(p);
      if (prefix)
        out += prefix->fillDestinations(p);
    }

  return out;
}

int BasicBlock::fillSources(int *p)
{
  int out = 0;

  for (int i = 0; i < this->n_insns; i++)
    {
      Instruction *insn = this->instructions[i];
      Instruction *delayed = insn->getDelayed();
      Instruction *prefix = insn->getPrefix();

      out += insn->fillSources(p);
      if (delayed)
        out += delayed->fillSources(p);
      if (prefix)
        out += prefix->fillSources(p);
    }

  return out;
}
<commit_msg>Implemented replacing of Jumps to other methods with Jal (curb some tail call optimizations), do pass1 after the instruction has been selected<commit_after>/*********************************************************************
 *
 * Copyright (C) 2008,  Simon Kagstrom
 *
 * Filename:      basicblock.cc
 * Author:        Simon Kagstrom <simon.kagstrom@gmail.com>
 * Description:   Basic block implementation
 *
 * $Id:$
 *
 ********************************************************************/
#include <controller.hh>
#include <basicblock.hh>
#include <emit.hh>
#include <config.hh>

BasicBlock::BasicBlock(Instruction **insns,
		       bb_type_t type,
		       int first, int last) : CodeBlock()
{
  this->instructions = &(insns[first]);
  this->n_insns = last - first;
  this->type = type;

  this->address = this->instructions[0]->getAddress();
  this->size = this->n_insns * 4;
}

bool BasicBlock::pass1()
{
  bool out = true;

  for (int i = 0; i < this->n_insns; i++)
    {
      Instruction *insn = this->instructions[i];

      controller->setCurrentInstruction(insn);

      if (insn->getOpcode() == OP_J)
        {
          uint32_t dstAddress = insn->getExtra() << 2;
          JavaMethod *src = controller->getMethodByAddress(insn->getAddress());
          JavaMethod *dst = controller->getMethodByAddress(dstAddress);

          if (src != dst)
            {
              /* Typically tail call optimizations, just "unoptimize" */
              emit->warning("Jump from 0x%x to 0x%x not within the same method, replacing with jal\n",
                            this->address, dstAddress);
              this->instructions[i] = InstructionFactory::getInstance()->createJal(insn->getAddress(),
                                                                                insn->getExtra());
              if (insn->isBranchTarget())
                this->instructions[i]->setBranchTarget();
              this->instructions[i]->setDelayed(insn->getDelayed());
              delete insn;
              insn = this->instructions[i];
            }
        }

      if ( (this->type == PROLOGUE && insn->getOpcode() == OP_SW && insn->getRs() == R_SP) ||
	   (this->type == EPILOGUE && insn->getOpcode() == OP_LW && insn->getRs() == R_SP) )
	{
	  int p_s[N_REGS];
	  int p_d[N_REGS];

	  memset(p_s, 0, sizeof(p_s));
	  memset(p_d, 0, sizeof(p_d));
	  insn->fillSources(p_s);
	  insn->fillDestinations(p_d);

	  /* Loop through all caller saved registers and for writes, simply skip them */
	  for (int j = 0;
	       mips_caller_saved[j] != R_ZERO;
	       j++)
	    {
	      MIPS_register_t reg = mips_caller_saved[j];

	      if ( (this->type == PROLOGUE && p_s[reg] != 0) ||
                   (this->type == EPILOGUE && p_d[reg] != 0) )
		{
		  this->instructions[i] = InstructionFactory::getInstance()->createNop(insn->getAddress());
                  if (insn->isBranchTarget())
                    this->instructions[i]->setBranchTarget();
		  delete insn;
                  insn = this->instructions[i];
		  break;
		}
	    }
	}

      /* Prepare the instruction */
      if (!insn->pass1())
	out = false;
    }

  return out;
}

static void pushRegister(MIPS_register_t reg)
{
  if (reg != R_RA)
    emit->bc_pushregister(reg);
  else
    emit->bc_pushconst(0);
}

void BasicBlock::traceRegisterValues(Instruction *insn)
{
  MIPS_register_t rs,rt,rd;

  rs = insn->getRs();
  rt = insn->getRt();
  rd = insn->getRd();

  /* Push all registers, then invoke the tracer */
  pushRegister(rs);
  pushRegister(rt);
  pushRegister(rd);

  emit->bc_invokestatic("CRunTime/emitRegisterTrace(III)V");
  if (insn->getDelayed())
    this->traceRegisterValues(insn->getDelayed());
}

void BasicBlock::commentInstruction(Instruction *insn)
{
  char buf[255];
  char out[255];

  /* Output a comment */
  int l = snprintf(buf, 255, "0x%x: ", insn->getAddress());
  l += instruction_to_string(insn, buf+l, 255);
  if (insn->hasDelaySlot())
    {
      buf[l] = ' ';
      instruction_to_string(insn->getDelayed(), buf+l+1, 255-l-1);
    }

  snprintf(out, 255, "0x%08x: %s", insn->getAddress(), buf);
  emit->bc_comment(out);

  if ( insn->getAddress() >= config->traceRange[0] && insn->getAddress() < config->traceRange[1])
    {
      emit->bc_ldc(buf);
      emit->bc_invokestatic("CRunTime/emitTrace(Ljava/lang/String;)V");
      this->traceRegisterValues(insn);
    }
}

bool BasicBlock::pass2()
{
  bool out = true;

  emit->bc_comment("--- basic block ---");
  for (int i = 0; i < this->n_insns; i++)
    {
      Instruction *insn = this->instructions[i];

      controller->setCurrentInstruction(insn);

      /* FIXME: Emit .line info if debug is on */
      if (insn->isBranchTarget() || controller->hasJumptabLabel(insn->getAddress()))
	emit->bc_label( "L_%x", insn->getAddress() );

      if (!insn->isNop())
	this->commentInstruction(insn);

      /* Compile the instruction */
      if (!insn->pass2())
	out = false;
    }

  return out;
}

int BasicBlock::fillDestinations(int *p)
{
  int out = 0;

  for (int i = 0; i < this->n_insns; i++)
    {
      Instruction *insn = this->instructions[i];
      Instruction *delayed = insn->getDelayed();
      Instruction *prefix = insn->getPrefix();

      out += insn->fillDestinations(p);
      if (delayed)
        out += delayed->fillDestinations(p);
      if (prefix)
        out += prefix->fillDestinations(p);
    }

  return out;
}

int BasicBlock::fillSources(int *p)
{
  int out = 0;

  for (int i = 0; i < this->n_insns; i++)
    {
      Instruction *insn = this->instructions[i];
      Instruction *delayed = insn->getDelayed();
      Instruction *prefix = insn->getPrefix();

      out += insn->fillSources(p);
      if (delayed)
        out += delayed->fillSources(p);
      if (prefix)
        out += prefix->fillSources(p);
    }

  return out;
}
<|endoftext|>