<commit_before>#ifndef PIXELBOOST_DISABLE_BOX2D

#include "Box2D/Box2D.h"

#include "pixelboost/logic/component/physics/2d/staticBody.h"
#include "pixelboost/logic/component/transform.h"
#include "pixelboost/logic/message/transform.h"
#include "pixelboost/logic/entity.h"
#include "pixelboost/physics/2d/helpers.h"

using namespace pb;

StaticBody2DComponent::StaticBody2DComponent(Entity* parent, b2World* world, BodyType type, glm::vec2 size)
    : PhysicsComponent(parent)
    , _World(world)
{
    pb::TransformComponent* transform = GetParent()->GetComponentByType<pb::TransformComponent>();
    glm::vec3 position = transform->GetPosition();

    b2BodyDef bodyDef;
    bodyDef.position = b2Vec2(position.x, position.y);
    bodyDef.type = b2_staticBody;
    bodyDef.userData = this;

    b2FixtureDef fixtureDef;

    switch (type)
    {
        case kBodyTypeCircle:
        {
            b2CircleShape circle;
            circle.m_radius = size.x;
            fixtureDef.shape = &circle;
            break;
        }

        case kBodyTypeRect:
        {
            b2PolygonShape rect;
            rect.SetAsBox(size.x, size.y);
            fixtureDef.shape = ▭
            break;
        }
    }

    _Body = world->CreateBody(&bodyDef);
    _Body->CreateFixture(&fixtureDef);

    GetParent()->RegisterMessageHandler(TransformChangedMessage::GetStaticType(), Entity::MessageHandler(this, &StaticBody2DComponent::OnTransformChanged));
}

StaticBody2DComponent::StaticBody2DComponent(Entity* parent, b2World* world, FixtureDefinition2D& definition)
    : PhysicsComponent(parent)
    , _World(world)
{
    pb::TransformComponent* transform = GetParent()->GetComponentByType<pb::TransformComponent>();
    glm::vec3 position = transform->GetPosition();
    glm::vec3 scale = transform->GetScale();

    _Body = PhysicsHelpers2D::CreateBodyFromDefinition(world, definition, glm::vec2(position.x,position.y), this, glm::vec2(scale.x, scale.y));
    _Body->SetTransform(b2Vec2(position.x, position.y), glm::radians(transform->GetRotation().z));

    GetParent()->RegisterMessageHandler(TransformChangedMessage::GetStaticType(), Entity::MessageHandler(this, &StaticBody2DComponent::OnTransformChanged));
}

StaticBody2DComponent::~StaticBody2DComponent()
{
    GetParent()->UnregisterMessageHandler(TransformChangedMessage::GetStaticType(), Entity::MessageHandler(this, &StaticBody2DComponent::OnTransformChanged));

    _World->DestroyBody(_Body);
}

pb::Uid StaticBody2DComponent::GetType()
{
    return GetStaticType();
}

pb::Uid StaticBody2DComponent::GetStaticType()
{
    return TypeHash("staticBody2D");
}

void StaticBody2DComponent::SetSensor(bool isSensor)
{
    b2Fixture* fixture = _Body->GetFixtureList();

    while (fixture)
    {
        fixture->SetSensor(isSensor);
        fixture = fixture->GetNext();
    }
}

void StaticBody2DComponent::OnTransformChanged(Uid sender, const Message& message)
{
    UpdateTransform();
}

void StaticBody2DComponent::UpdateTransform()
{
    TransformComponent* transform = GetParent()->GetComponentByType<TransformComponent>();

    if (transform)
    {
        glm::vec3 position = transform->GetPosition();
        glm::vec3 rotation = transform->GetRotation();
        _Body->SetTransform(b2Vec2(position.x, position.y), rotation.z);
    }
}

#endif<commit_msg>Fix use of out of scope variable<commit_after>#ifndef PIXELBOOST_DISABLE_BOX2D

#include "Box2D/Box2D.h"

#include "pixelboost/logic/component/physics/2d/staticBody.h"
#include "pixelboost/logic/component/transform.h"
#include "pixelboost/logic/message/transform.h"
#include "pixelboost/logic/entity.h"
#include "pixelboost/physics/2d/helpers.h"

using namespace pb;

StaticBody2DComponent::StaticBody2DComponent(Entity* parent, b2World* world, BodyType type, glm::vec2 size)
    : PhysicsComponent(parent)
    , _World(world)
{
    pb::TransformComponent* transform = GetParent()->GetComponentByType<pb::TransformComponent>();
    glm::vec3 position = transform->GetPosition();

    b2BodyDef bodyDef;
    bodyDef.position = b2Vec2(position.x, position.y);
    bodyDef.type = b2_staticBody;
    bodyDef.userData = this;

    b2FixtureDef fixtureDef;

    b2CircleShape circle;
    b2PolygonShape rect;

    switch (type)
    {
        case kBodyTypeCircle:
        {
            circle.m_radius = size.x;
            fixtureDef.shape = &circle;
            break;
        }

        case kBodyTypeRect:
        {
            rect.SetAsBox(size.x, size.y);
            fixtureDef.shape = ▭
            break;
        }
    }

    _Body = world->CreateBody(&bodyDef);
    _Body->CreateFixture(&fixtureDef);

    GetParent()->RegisterMessageHandler(TransformChangedMessage::GetStaticType(), Entity::MessageHandler(this, &StaticBody2DComponent::OnTransformChanged));
}

StaticBody2DComponent::StaticBody2DComponent(Entity* parent, b2World* world, FixtureDefinition2D& definition)
    : PhysicsComponent(parent)
    , _World(world)
{
    pb::TransformComponent* transform = GetParent()->GetComponentByType<pb::TransformComponent>();
    glm::vec3 position = transform->GetPosition();
    glm::vec3 scale = transform->GetScale();

    _Body = PhysicsHelpers2D::CreateBodyFromDefinition(world, definition, glm::vec2(position.x,position.y), this, glm::vec2(scale.x, scale.y));
    _Body->SetTransform(b2Vec2(position.x, position.y), glm::radians(transform->GetRotation().z));

    GetParent()->RegisterMessageHandler(TransformChangedMessage::GetStaticType(), Entity::MessageHandler(this, &StaticBody2DComponent::OnTransformChanged));
}

StaticBody2DComponent::~StaticBody2DComponent()
{
    GetParent()->UnregisterMessageHandler(TransformChangedMessage::GetStaticType(), Entity::MessageHandler(this, &StaticBody2DComponent::OnTransformChanged));

    _World->DestroyBody(_Body);
}

pb::Uid StaticBody2DComponent::GetType()
{
    return GetStaticType();
}

pb::Uid StaticBody2DComponent::GetStaticType()
{
    return TypeHash("staticBody2D");
}

void StaticBody2DComponent::SetSensor(bool isSensor)
{
    b2Fixture* fixture = _Body->GetFixtureList();

    while (fixture)
    {
        fixture->SetSensor(isSensor);
        fixture = fixture->GetNext();
    }
}

void StaticBody2DComponent::OnTransformChanged(Uid sender, const Message& message)
{
    UpdateTransform();
}

void StaticBody2DComponent::UpdateTransform()
{
    TransformComponent* transform = GetParent()->GetComponentByType<TransformComponent>();

    if (transform)
    {
        glm::vec3 position = transform->GetPosition();
        glm::vec3 rotation = transform->GetRotation();
        _Body->SetTransform(b2Vec2(position.x, position.y), rotation.z);
    }
}

#endif<|endoftext|>


<commit_before>/* Copyright (C) 2004 MySQL AB

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; version 2 of the License.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */

/*
  Utility program used to signal a safe_process it's time to shutdown

  Usage:
    safe_kill <pid>
*/

#include <windows.h>
#include <stdio.h>

int main(int argc, const char** argv )
{
  DWORD pid= -1;
  HANDLE shutdown_event;
  char safe_process_name[32]= {0};
  int retry_open_event= 100;

  if (argc != 2) {
    fprintf(stderr, "safe_kill <pid>\n");
    exit(2);
  }
  pid= atoi(argv[1]);

  _snprintf(safe_process_name, sizeof(safe_process_name), "safe_process[%d]", pid);

  /* Open the event to signal */
  while ((shutdown_event=
          OpenEvent(EVENT_MODIFY_STATE, FALSE, safe_process_name)) == NULL)
  {
    fprintf(stderr, "Failed to open shutdown_event '%s', error: %d\n",
            safe_process_name, GetLastError());

    /* Just check to see if pid exists */
    HANDLE pid_handle= OpenProcess(SYNCHRONIZE, FALSE, pid);
    if (pid_handle == NULL)
      fprintf(stderr, "Could not open process with pid %d, error: %d\n", pid);
	else
	  CloseHandle(pid_handle);

    if (retry_open_event--)
    {
      fprintf(stderr, "retrying...\n");
      Sleep(100); /* In milli seconds */
    }
    else
    {
      fprintf(stderr, "No more retries, exiting");
      exit(1);
    }
  }

  if(SetEvent(shutdown_event) == 0)
  {
    fprintf(stderr, "Failed to signal shutdown_event '%s', error: %d\n",
            safe_process_name, GetLastError());
    CloseHandle(shutdown_event);
    exit(1);
  }
  CloseHandle(shutdown_event);
  exit(0);
}

<commit_msg>Ignore all common signals Just retry OpenEvent a couple of times with a "yield" in between<commit_after>/* Copyright (C) 2004 MySQL AB

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; version 2 of the License.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */

/*
  Utility program used to signal a safe_process it's time to shutdown

  Usage:
    safe_kill <pid>
*/

#include <windows.h>
#include <stdio.h>
#include <signal.h>

int main(int argc, const char** argv )
{
  DWORD pid= -1;
  HANDLE shutdown_event;
  char safe_process_name[32]= {0};
  int retry_open_event= 100;
  /* Ignore any signals */
  signal(SIGINT,   SIG_IGN);
  signal(SIGBREAK, SIG_IGN);
  signal(SIGTERM,  SIG_IGN);

  if (argc != 2) {
    fprintf(stderr, "safe_kill <pid>\n");
    exit(2);
  }
  pid= atoi(argv[1]);

  _snprintf(safe_process_name, sizeof(safe_process_name),
            "safe_process[%d]", pid);

  /* Open the event to signal */
  while ((shutdown_event=
          OpenEvent(EVENT_MODIFY_STATE, FALSE, safe_process_name)) == NULL)
  {
    if (retry_open_event--)
      Sleep(0); /* yield */
    else
    {
      fprintf(stderr, "Failed to open shutdown_event '%s', error: %d\n",
            safe_process_name, GetLastError());
      exit(3);
    }
  }

  if(SetEvent(shutdown_event) == 0)
  {
    fprintf(stderr, "Failed to signal shutdown_event '%s', error: %d\n",
            safe_process_name, GetLastError());
    CloseHandle(shutdown_event);
    exit(4);
  }
  CloseHandle(shutdown_event);
  exit(0);
}

<|endoftext|>


<commit_before>#pragma once

#include "event_queue.hpp"
#include <mpark/variant.hpp>
#include <nlohmann/json.hpp>
#include <optional>
#include <pqrs/json.hpp>

namespace krbn {
namespace manipulator {
class event_definition {
public:
  enum class type {
    none,
    key_code,
    consumer_key_code,
    pointing_button,
    any,
    shell_command,
    select_input_source,
    set_variable,
    mouse_key,
  };

  using value_t = mpark::variant<mpark::monostate,
                                 key_code,
                                 consumer_key_code,
                                 pointing_button,
                                 type,                                                     // For any
                                 std::string,                                              // For shell_command
                                 std::vector<pqrs::osx::input_source_selector::specifier>, // For select_input_source
                                 std::pair<std::string, int>,                              // For set_variable
                                 mouse_key                                                 // For mouse_key
                                 >;

  event_definition(void) : type_(type::none),
                           value_(mpark::monostate()) {
  }

  virtual ~event_definition(void) {
  }

  type get_type(void) const {
    return type_;
  }

  const value_t& get_value(void) const {
    return value_;
  }

  std::optional<key_code> get_key_code(void) const {
    if (type_ == type::key_code) {
      return mpark::get<key_code>(value_);
    }
    return std::nullopt;
  }

  std::optional<consumer_key_code> get_consumer_key_code(void) const {
    if (type_ == type::consumer_key_code) {
      return mpark::get<consumer_key_code>(value_);
    }
    return std::nullopt;
  }

  std::optional<pointing_button> get_pointing_button(void) const {
    if (type_ == type::pointing_button) {
      return mpark::get<pointing_button>(value_);
    }
    return std::nullopt;
  }

  std::optional<type> get_any_type(void) const {
    if (type_ == type::any) {
      return mpark::get<type>(value_);
    }
    return std::nullopt;
  }

  std::optional<std::string> get_shell_command(void) const {
    if (type_ == type::shell_command) {
      return mpark::get<std::string>(value_);
    }
    return std::nullopt;
  }

  std::optional<std::vector<pqrs::osx::input_source_selector::specifier>> get_input_source_specifiers(void) const {
    if (type_ == type::select_input_source) {
      return mpark::get<std::vector<pqrs::osx::input_source_selector::specifier>>(value_);
    }
    return std::nullopt;
  }

  std::optional<std::pair<std::string, int>> get_set_variable(void) const {
    if (type_ == type::set_variable) {
      return mpark::get<std::pair<std::string, int>>(value_);
    }
    return std::nullopt;
  }

  std::optional<mouse_key> get_mouse_key(void) const {
    if (type_ == type::mouse_key) {
      return mpark::get<mouse_key>(value_);
    }
    return std::nullopt;
  }

  std::optional<event_queue::event> to_event(void) const {
    switch (type_) {
      case type::none:
        return std::nullopt;
      case type::key_code:
        return event_queue::event(mpark::get<key_code>(value_));
      case type::consumer_key_code:
        return event_queue::event(mpark::get<consumer_key_code>(value_));
      case type::pointing_button:
        return event_queue::event(mpark::get<pointing_button>(value_));
      case type::any:
        return std::nullopt;
      case type::shell_command:
        return event_queue::event::make_shell_command_event(mpark::get<std::string>(value_));
      case type::select_input_source:
        return event_queue::event::make_select_input_source_event(mpark::get<std::vector<pqrs::osx::input_source_selector::specifier>>(value_));
      case type::set_variable:
        return event_queue::event::make_set_variable_event(mpark::get<std::pair<std::string, int>>(value_));
      case type::mouse_key:
        return event_queue::event::make_mouse_key_event(mpark::get<mouse_key>(value_));
    }
  }

  bool handle_json(const std::string& key,
                   const nlohmann::json& value,
                   const nlohmann::json& json) {
    // Set type_ and values.

    // ----------------------------------------
    // key_code

    if (key == "key_code") {
      check_type(json);

      if (!value.is_string()) {
        throw pqrs::json::unmarshal_error(fmt::format("`{0}` must be string, but is `{1}`", key, value.dump()));
      }

      if (auto key_code = types::make_key_code(value.get<std::string>())) {
        type_ = type::key_code;
        value_ = *key_code;
      } else {
        throw pqrs::json::unmarshal_error(fmt::format("unknown `{0}`: `{1}`", key, value.dump()));
      }

      return true;
    }

    // ----------------------------------------
    // consumer_key_code

    if (key == "consumer_key_code") {
      check_type(json);

      if (!value.is_string()) {
        throw pqrs::json::unmarshal_error(fmt::format("`{0}` must be string, but is `{1}`", key, value.dump()));
      }

      if (auto consumer_key_code = types::make_consumer_key_code(value.get<std::string>())) {
        type_ = type::consumer_key_code;
        value_ = *consumer_key_code;
      } else {
        throw pqrs::json::unmarshal_error(fmt::format("unknown `{0}`: `{1}`", key, value.dump()));
      }

      return true;
    }

    // ----------------------------------------
    // pointing_button

    if (key == "pointing_button") {
      check_type(json);

      if (!value.is_string()) {
        throw pqrs::json::unmarshal_error(fmt::format("`{0}` must be string, but is `{1}`", key, value.dump()));
      }

      if (auto pointing_button = types::make_pointing_button(value.get<std::string>())) {
        type_ = type::pointing_button;
        value_ = *pointing_button;
      } else {
        throw pqrs::json::unmarshal_error(fmt::format("unknown `{0}`: `{1}`", key, value.dump()));
      }

      return true;
    }

    // ----------------------------------------
    // any

    if (key == "any") {
      check_type(json);

      if (!value.is_string()) {
        throw pqrs::json::unmarshal_error(fmt::format("`{0}` must be string, but is `{1}`", key, value.dump()));
      }

      if (value == "key_code") {
        type_ = type::any;
        value_ = type::key_code;
      } else if (value == "consumer_key_code") {
        type_ = type::any;
        value_ = type::consumer_key_code;
      } else if (value == "pointing_button") {
        type_ = type::any;
        value_ = type::pointing_button;
      } else {
        throw pqrs::json::unmarshal_error(fmt::format("unknown `{0}`: `{1}`", key, value.dump()));
      }

      return true;
    }

    // ----------------------------------------
    // shell_command

    if (key == "shell_command") {
      check_type(json);

      if (!value.is_string()) {
        throw pqrs::json::unmarshal_error(fmt::format("`{0}` must be string, but is `{1}`", key, value.dump()));
      }

      type_ = type::shell_command;
      value_ = value.get<std::string>();

      return true;
    }

    // ----------------------------------------
    // select_input_source

    if (key == "select_input_source") {
      check_type(json);

      std::vector<pqrs::osx::input_source_selector::specifier> input_source_specifiers;

      if (value.is_object()) {
        input_source_specifiers.push_back(value.get<pqrs::osx::input_source_selector::specifier>());
      } else if (value.is_array()) {
        input_source_specifiers = value.get<std::vector<pqrs::osx::input_source_selector::specifier>>();
      } else {
        throw pqrs::json::unmarshal_error(fmt::format("`{0}` must be object or array of objects, but is `{1}`", key, value.dump()));
      }

      type_ = type::select_input_source;
      value_ = input_source_specifiers;

      return true;
    }

    // ----------------------------------------
    // set_variable

    if (key == "set_variable") {
      check_type(json);

      if (!value.is_object()) {
        throw pqrs::json::unmarshal_error(fmt::format("`{0}` must be object, but is `{1}`", key, value.dump()));
      }

      // name

      std::string variable_name;

      {
        auto it = value.find("name");
        if (it == std::end(value)) {
          throw pqrs::json::unmarshal_error(fmt::format("`{0}.name` is not found in `{1}`", key, value.dump()));
        }

        if (!it.value().is_string()) {
          throw pqrs::json::unmarshal_error(fmt::format("`{0}.name` must be string, but is `{1}`", key, it.value().dump()));
        }
        variable_name = it.value().get<std::string>();
      }

      // value

      int variable_value;

      {
        auto it = value.find("value");
        if (it == std::end(value)) {
          throw pqrs::json::unmarshal_error(fmt::format("`{0}.value` is not found in `{1}`", key, value.dump()));
        }

        if (!it.value().is_number()) {
          throw pqrs::json::unmarshal_error(fmt::format("`{0}.value` must be number, but is `{1}`", key, it.value().dump()));
        }
        variable_value = it.value().get<int>();
      }

      type_ = type::set_variable;
      value_ = std::make_pair(variable_name, variable_value);

      return true;
    }

    // ----------------------------------------
    // mouse_key

    if (key == "mouse_key") {
      check_type(json);

      if (!value.is_object()) {
        throw pqrs::json::unmarshal_error(fmt::format("`{0}` must be object, but is `{1}`", key, value.dump()));
      }

      type_ = type::mouse_key;
      value_ = mouse_key(value);

      return true;
    }

    if (key == "description") {
      // Do nothing

      return true;
    }

    return false;
  }

  void check_type(const nlohmann::json& json) const {
    if (type_ != type::none) {
      throw pqrs::json::unmarshal_error(fmt::format("multiple types are specified: `{0}`", json.dump()));
    }
  }

protected:
  type type_;
  value_t value_;
};
} // namespace manipulator
} // namespace krbn
<commit_msg>update error messages<commit_after>#pragma once

#include "event_queue.hpp"
#include <mpark/variant.hpp>
#include <nlohmann/json.hpp>
#include <optional>
#include <pqrs/json.hpp>

namespace krbn {
namespace manipulator {
class event_definition {
public:
  enum class type {
    none,
    key_code,
    consumer_key_code,
    pointing_button,
    any,
    shell_command,
    select_input_source,
    set_variable,
    mouse_key,
  };

  using value_t = mpark::variant<mpark::monostate,
                                 key_code,
                                 consumer_key_code,
                                 pointing_button,
                                 type,                                                     // For any
                                 std::string,                                              // For shell_command
                                 std::vector<pqrs::osx::input_source_selector::specifier>, // For select_input_source
                                 std::pair<std::string, int>,                              // For set_variable
                                 mouse_key                                                 // For mouse_key
                                 >;

  event_definition(void) : type_(type::none),
                           value_(mpark::monostate()) {
  }

  virtual ~event_definition(void) {
  }

  type get_type(void) const {
    return type_;
  }

  const value_t& get_value(void) const {
    return value_;
  }

  std::optional<key_code> get_key_code(void) const {
    if (type_ == type::key_code) {
      return mpark::get<key_code>(value_);
    }
    return std::nullopt;
  }

  std::optional<consumer_key_code> get_consumer_key_code(void) const {
    if (type_ == type::consumer_key_code) {
      return mpark::get<consumer_key_code>(value_);
    }
    return std::nullopt;
  }

  std::optional<pointing_button> get_pointing_button(void) const {
    if (type_ == type::pointing_button) {
      return mpark::get<pointing_button>(value_);
    }
    return std::nullopt;
  }

  std::optional<type> get_any_type(void) const {
    if (type_ == type::any) {
      return mpark::get<type>(value_);
    }
    return std::nullopt;
  }

  std::optional<std::string> get_shell_command(void) const {
    if (type_ == type::shell_command) {
      return mpark::get<std::string>(value_);
    }
    return std::nullopt;
  }

  std::optional<std::vector<pqrs::osx::input_source_selector::specifier>> get_input_source_specifiers(void) const {
    if (type_ == type::select_input_source) {
      return mpark::get<std::vector<pqrs::osx::input_source_selector::specifier>>(value_);
    }
    return std::nullopt;
  }

  std::optional<std::pair<std::string, int>> get_set_variable(void) const {
    if (type_ == type::set_variable) {
      return mpark::get<std::pair<std::string, int>>(value_);
    }
    return std::nullopt;
  }

  std::optional<mouse_key> get_mouse_key(void) const {
    if (type_ == type::mouse_key) {
      return mpark::get<mouse_key>(value_);
    }
    return std::nullopt;
  }

  std::optional<event_queue::event> to_event(void) const {
    switch (type_) {
      case type::none:
        return std::nullopt;
      case type::key_code:
        return event_queue::event(mpark::get<key_code>(value_));
      case type::consumer_key_code:
        return event_queue::event(mpark::get<consumer_key_code>(value_));
      case type::pointing_button:
        return event_queue::event(mpark::get<pointing_button>(value_));
      case type::any:
        return std::nullopt;
      case type::shell_command:
        return event_queue::event::make_shell_command_event(mpark::get<std::string>(value_));
      case type::select_input_source:
        return event_queue::event::make_select_input_source_event(mpark::get<std::vector<pqrs::osx::input_source_selector::specifier>>(value_));
      case type::set_variable:
        return event_queue::event::make_set_variable_event(mpark::get<std::pair<std::string, int>>(value_));
      case type::mouse_key:
        return event_queue::event::make_mouse_key_event(mpark::get<mouse_key>(value_));
    }
  }

  bool handle_json(const std::string& key,
                   const nlohmann::json& value,
                   const nlohmann::json& json) {
    // Set type_ and values.

    // ----------------------------------------
    // key_code

    if (key == "key_code") {
      check_type(json);

      if (!value.is_string()) {
        throw pqrs::json::unmarshal_error(fmt::format("`{0}` must be string, but is `{1}`", key, value.dump()));
      }

      if (auto key_code = types::make_key_code(value.get<std::string>())) {
        type_ = type::key_code;
        value_ = *key_code;
      } else {
        throw pqrs::json::unmarshal_error(fmt::format("unknown `{0}`: `{1}`", key, value.dump()));
      }

      return true;
    }

    // ----------------------------------------
    // consumer_key_code

    if (key == "consumer_key_code") {
      check_type(json);

      if (!value.is_string()) {
        throw pqrs::json::unmarshal_error(fmt::format("`{0}` must be string, but is `{1}`", key, value.dump()));
      }

      if (auto consumer_key_code = types::make_consumer_key_code(value.get<std::string>())) {
        type_ = type::consumer_key_code;
        value_ = *consumer_key_code;
      } else {
        throw pqrs::json::unmarshal_error(fmt::format("unknown `{0}`: `{1}`", key, value.dump()));
      }

      return true;
    }

    // ----------------------------------------
    // pointing_button

    if (key == "pointing_button") {
      check_type(json);

      if (!value.is_string()) {
        throw pqrs::json::unmarshal_error(fmt::format("`{0}` must be string, but is `{1}`", key, value.dump()));
      }

      if (auto pointing_button = types::make_pointing_button(value.get<std::string>())) {
        type_ = type::pointing_button;
        value_ = *pointing_button;
      } else {
        throw pqrs::json::unmarshal_error(fmt::format("unknown `{0}`: `{1}`", key, value.dump()));
      }

      return true;
    }

    // ----------------------------------------
    // any

    if (key == "any") {
      check_type(json);

      if (!value.is_string()) {
        throw pqrs::json::unmarshal_error(fmt::format("`{0}` must be string, but is `{1}`", key, value.dump()));
      }

      if (value == "key_code") {
        type_ = type::any;
        value_ = type::key_code;
      } else if (value == "consumer_key_code") {
        type_ = type::any;
        value_ = type::consumer_key_code;
      } else if (value == "pointing_button") {
        type_ = type::any;
        value_ = type::pointing_button;
      } else {
        throw pqrs::json::unmarshal_error(fmt::format("unknown `{0}`: `{1}`", key, value.dump()));
      }

      return true;
    }

    // ----------------------------------------
    // shell_command

    if (key == "shell_command") {
      check_type(json);

      if (!value.is_string()) {
        throw pqrs::json::unmarshal_error(fmt::format("`{0}` must be string, but is `{1}`", key, value.dump()));
      }

      type_ = type::shell_command;
      value_ = value.get<std::string>();

      return true;
    }

    // ----------------------------------------
    // select_input_source

    if (key == "select_input_source") {
      check_type(json);

      std::vector<pqrs::osx::input_source_selector::specifier> input_source_specifiers;

      if (value.is_object()) {
        try {
          input_source_specifiers.push_back(value.get<pqrs::osx::input_source_selector::specifier>());
        } catch (const pqrs::json::unmarshal_error& e) {
          throw pqrs::json::unmarshal_error(fmt::format("`{0}` error: {1}", key, e.what()));
        }
      } else if (value.is_array()) {
        try {
          input_source_specifiers = value.get<std::vector<pqrs::osx::input_source_selector::specifier>>();
        } catch (const pqrs::json::unmarshal_error& e) {
          throw pqrs::json::unmarshal_error(fmt::format("`{0}` error: {1}", key, e.what()));
        }
      } else {
        throw pqrs::json::unmarshal_error(fmt::format("`{0}` must be object or array of objects, but is `{1}`", key, value.dump()));
      }

      type_ = type::select_input_source;
      value_ = input_source_specifiers;

      return true;
    }

    // ----------------------------------------
    // set_variable

    if (key == "set_variable") {
      check_type(json);

      if (!value.is_object()) {
        throw pqrs::json::unmarshal_error(fmt::format("`{0}` must be object, but is `{1}`", key, value.dump()));
      }

      // name

      std::string variable_name;

      {
        auto it = value.find("name");
        if (it == std::end(value)) {
          throw pqrs::json::unmarshal_error(fmt::format("`{0}.name` is not found in `{1}`", key, value.dump()));
        }

        if (!it.value().is_string()) {
          throw pqrs::json::unmarshal_error(fmt::format("`{0}.name` must be string, but is `{1}`", key, it.value().dump()));
        }
        variable_name = it.value().get<std::string>();
      }

      // value

      int variable_value;

      {
        auto it = value.find("value");
        if (it == std::end(value)) {
          throw pqrs::json::unmarshal_error(fmt::format("`{0}.value` is not found in `{1}`", key, value.dump()));
        }

        if (!it.value().is_number()) {
          throw pqrs::json::unmarshal_error(fmt::format("`{0}.value` must be number, but is `{1}`", key, it.value().dump()));
        }
        variable_value = it.value().get<int>();
      }

      type_ = type::set_variable;
      value_ = std::make_pair(variable_name, variable_value);

      return true;
    }

    // ----------------------------------------
    // mouse_key

    if (key == "mouse_key") {
      check_type(json);

      if (!value.is_object()) {
        throw pqrs::json::unmarshal_error(fmt::format("`{0}` must be object, but is `{1}`", key, value.dump()));
      }

      type_ = type::mouse_key;
      value_ = mouse_key(value);

      return true;
    }

    if (key == "description") {
      // Do nothing

      return true;
    }

    return false;
  }

  void check_type(const nlohmann::json& json) const {
    if (type_ != type::none) {
      throw pqrs::json::unmarshal_error(fmt::format("multiple types are specified: `{0}`", json.dump()));
    }
  }

protected:
  type type_;
  value_t value_;
};
} // namespace manipulator
} // namespace krbn
<|endoftext|>


<commit_before>/*
 * DesktopWin32DetectRHome.cpp
 *
 * Copyright (C) 2009-11 by RStudio, Inc.
 *
 * This program is licensed to you under the terms of version 3 of the
 * GNU Affero General Public License. This program is distributed WITHOUT
 * ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF NON-INFRINGEMENT,
 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Please refer to the
 * AGPL (http://www.gnu.org/licenses/agpl-3.0.txt) for more details.
 *
 */

#ifndef _WIN32
#error DesktopDetectRHome.cpp is Windows-specific
#endif

#include "DesktopDetectRHome.hpp"

#include <windows.h>

#include <boost/bind.hpp>

#include <core/system/System.hpp>

#include "DesktopRVersion.hpp"

using namespace core;

namespace desktop {

bool prepareEnvironment(Options &options)
{
   bool forceUi = ::GetAsyncKeyState(VK_CONTROL) & ~1;

   RVersion rVersion = detectRVersion(forceUi);
   if (!rVersion.isValid())
      return false;

   system::setenv("R_HOME", rVersion.homeDir().toStdString());

   std::string path =
         QDir::toNativeSeparators(rVersion.binDir()).toStdString() + ";" +
         system::getenv("PATH");
   system::setenv("PATH", path);

   return true;
}

} // namespace desktop
<commit_msg>cherry pick: use 8.3 path for R_HOME on windows<commit_after>/*
 * DesktopWin32DetectRHome.cpp
 *
 * Copyright (C) 2009-11 by RStudio, Inc.
 *
 * This program is licensed to you under the terms of version 3 of the
 * GNU Affero General Public License. This program is distributed WITHOUT
 * ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF NON-INFRINGEMENT,
 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Please refer to the
 * AGPL (http://www.gnu.org/licenses/agpl-3.0.txt) for more details.
 *
 */

#ifndef _WIN32
#error DesktopDetectRHome.cpp is Windows-specific
#endif

#include "DesktopDetectRHome.hpp"

#include <windows.h>

#include <boost/bind.hpp>

#include <core/system/System.hpp>

#include "DesktopRVersion.hpp"

using namespace core;

namespace desktop {

bool prepareEnvironment(Options &options)
{
   bool forceUi = ::GetAsyncKeyState(VK_CONTROL) & ~1;

   RVersion rVersion = detectRVersion(forceUi);
   if (!rVersion.isValid())
      return false;

   // get the short path version of the home dir
   std::string homePath =
         QDir::toNativeSeparators(rVersion.homeDir()).toStdString();
   DWORD len = ::GetShortPathName(homePath.c_str(), NULL, 0);
   std::vector<TCHAR> buffer(len, 0);
   if (::GetShortPathName(homePath.c_str(), &(buffer[0]), len) != 0)
   {
      // copy path to string and assign it we got one
      std::string shortHomePath(&(buffer[0]));
      if (!shortHomePath.empty())
         homePath = shortHomePath;
   }
   else
   {
      LOG_ERROR(systemError(::GetLastError(), ERROR_LOCATION));
   }

   // set R_HOME
   system::setenv("R_HOME", homePath);

   std::string path =
         QDir::toNativeSeparators(rVersion.binDir()).toStdString() + ";" +
         system::getenv("PATH");
   system::setenv("PATH", path);

   return true;
}

} // namespace desktop
<|endoftext|>


<commit_before>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs03.C $ */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2016,2019                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* 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.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */

///
/// @file mrs03.C
/// @brief Run and manage the DDR4 DDR4 loading
///
// *HWP HWP Owner: Brian Silver <bsilver@us.ibm.com>
// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com>
// *HWP Team: Memory
// *HWP Level: 1
// *HWP Consumed by: FSP:HB

#include <fapi2.H>

#include <mss.H>
#include <lib/dimm/ddr4/mrs_load_ddr4.H>

using fapi2::TARGET_TYPE_MCBIST;
using fapi2::TARGET_TYPE_DIMM;

using fapi2::FAPI2_RC_SUCCESS;

namespace mss
{

namespace ddr4
{

///
/// @brief mrs03_data ctor
/// @param[in] a fapi2::TARGET_TYPE_DIMM target
/// @param[out] fapi2::ReturnCode FAPI2_RC_SUCCESS iff ok
///
mrs03_data::mrs03_data( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, fapi2::ReturnCode& o_rc ):
    iv_mpr_mode(0),
    iv_mpr_page(0),
    iv_geardown(0),
    iv_pda(0),
    iv_crc_wr_latency(0),
    iv_temp_readout(0),
    iv_fine_refresh(0),
    iv_read_format(0)
{
    FAPI_TRY( mss::eff_mpr_mode(i_target, iv_mpr_mode) );
    FAPI_TRY( mss::eff_mpr_page(i_target, iv_mpr_page) );
    FAPI_TRY( mss::eff_geardown_mode(i_target, iv_geardown) );
    FAPI_TRY( mss::eff_per_dram_access(i_target, iv_pda) );
    FAPI_TRY( mss::eff_temp_readout(i_target, iv_temp_readout) );
    FAPI_TRY( mss::mrw_fine_refresh_mode(iv_fine_refresh) );
    FAPI_TRY( mss::eff_crc_wr_latency(i_target, iv_crc_wr_latency) );
    FAPI_TRY( mss::eff_mpr_rd_format(i_target, iv_read_format) );

    FAPI_INF("MR3 attributes: MPR_MODE: 0x%x, MPR_PAGE: 0x%x, GD: 0x%x, PDA: 0x%x, "
             "TEMP: 0x%x FR: 0x%x, CRC_WL: 0x%x, RF: 0x%x",
             iv_mpr_mode, iv_mpr_page, iv_geardown, iv_pda, iv_temp_readout,
             iv_fine_refresh, iv_crc_wr_latency, iv_read_format);

    o_rc = fapi2::FAPI2_RC_SUCCESS;
    return;

fapi_try_exit:
    o_rc = fapi2::current_err;
    FAPI_ERR("unable to get attributes for mrs0");
    return;
}

///
/// @brief Configure the ARR0 of the CCS instruction for mrs03
/// @param[in] i_target a fapi2::Target<TARGET_TYPE_DIMM>
/// @param[in,out] io_inst the instruction to fixup
/// @param[in] i_rank the rank in question
/// @return FAPI2_RC_SUCCESS iff OK
///
fapi2::ReturnCode mrs03(const fapi2::Target<TARGET_TYPE_DIMM>& i_target,
                        ccs::instruction_t<TARGET_TYPE_MCBIST>& io_inst,
                        const uint64_t i_rank)
{
    // Check to make sure our ctor worked ok
    mrs03_data l_data( i_target, fapi2::current_err );
    FAPI_TRY( fapi2::current_err, "Unable to construct MRS03 data from attributes");
    FAPI_TRY( mrs03(i_target, l_data, io_inst, i_rank) );

fapi_try_exit:
    return fapi2::current_err;
}

///
/// @brief Configure the ARR0 of the CCS instruction for mrs03, data object as input
/// @param[in] i_target a fapi2::Target<fapi2::TARGET_TYPE_DIMM>
/// @param[in] i_data an mrs00_data object, filled in
/// @param[in,out] io_inst the instruction to fixup
/// @param[in] i_rank the rank in question
/// @return FAPI2_RC_SUCCESS iff OK
///
fapi2::ReturnCode mrs03(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
                        const mrs03_data& i_data,
                        ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>& io_inst,
                        const uint64_t i_rank)
{
    constexpr uint64_t LOWEST_WL = 4;
    constexpr uint64_t WL_COUNT = 3;
    //                                                 4  5  6
    constexpr uint8_t crc_wr_latency_map[WL_COUNT] = { 1, 2, 3 };

    fapi2::buffer<uint8_t> l_crc_wr_latency_buffer;

    FAPI_ASSERT((i_data.iv_crc_wr_latency >= LOWEST_WL) && (i_data.iv_crc_wr_latency < (LOWEST_WL + WL_COUNT)),
                fapi2::MSS_BAD_MR_PARAMETER()
                .set_MR_NUMBER(3)
                .set_PARAMETER(WRITE_CMD_LATENCY)
                .set_PARAMETER_VALUE(i_data.iv_crc_wr_latency)
                .set_DIMM_IN_ERROR(i_target),
                "Bad value for Write CMD Latency: %d (%s)", i_data.iv_crc_wr_latency, mss::c_str(i_target));

    l_crc_wr_latency_buffer = crc_wr_latency_map[i_data.iv_crc_wr_latency - LOWEST_WL];

    mss::swizzle<A0, 2, 7>(fapi2::buffer<uint8_t>(i_data.iv_mpr_mode), io_inst.arr0);
    io_inst.arr0.writeBit<A2>(i_data.iv_mpr_page);
    io_inst.arr0.writeBit<A3>(i_data.iv_geardown);
    io_inst.arr0.writeBit<A4>(i_data.iv_pda);
    io_inst.arr0.writeBit<A5>(i_data.iv_temp_readout);

    mss::swizzle<A6 , 3, 7>(fapi2::buffer<uint8_t>(i_data.iv_fine_refresh), io_inst.arr0);
    mss::swizzle<A9 , 2, 7>(l_crc_wr_latency_buffer, io_inst.arr0);
    mss::swizzle<A11, 2, 7>(fapi2::buffer<uint8_t>(i_data.iv_read_format), io_inst.arr0);

    FAPI_INF("MR3: 0x%016llx", uint64_t(io_inst.arr0));

    return fapi2::FAPI2_RC_SUCCESS;

fapi_try_exit:
    return fapi2::current_err;
}

///
/// @brief Given a CCS instruction which contains address bits with an encoded MRS3,
/// decode and trace the contents
/// @param[in] i_inst the CCS instruction
/// @param[in] i_rank ths rank in question
/// @return void
///
fapi2::ReturnCode mrs03_decode(const ccs::instruction_t<TARGET_TYPE_MCBIST>& i_inst,
                               const uint64_t i_rank)
{
    fapi2::buffer<uint8_t> l_mpr_mode;

    fapi2::buffer<uint8_t> l_fine_refresh;
    fapi2::buffer<uint8_t> l_crc_wr_latency_buffer;
    fapi2::buffer<uint8_t> l_read_format;

    uint8_t l_mpr_page = i_inst.arr0.getBit<A2>();
    uint8_t l_geardown = i_inst.arr0.getBit<A3>();
    uint8_t l_pda = i_inst.arr0.getBit<A4>();
    uint8_t l_temp_readout = i_inst.arr0.getBit<A5>();

    mss::swizzle<6, 2, A1>(i_inst.arr0, l_mpr_mode);
    mss::swizzle<5, 3, A7>(i_inst.arr0, l_fine_refresh);
    mss::swizzle<6, 2, A10>(i_inst.arr0, l_crc_wr_latency_buffer);
    mss::swizzle<6, 2, A12>(i_inst.arr0, l_read_format);

    FAPI_INF("MR3 rank %d decode: MPR_MODE: 0x%x, MPR_PAGE: 0x%x, GD: 0x%x, PDA: 0x%x, "
             "TEMP: 0x%x FR: 0x%x, CRC_WL: 0x%x, RF: 0x%x", i_rank,
             uint8_t(l_mpr_mode), l_mpr_page, l_geardown, l_pda, uint8_t(l_temp_readout),
             uint8_t(l_fine_refresh), uint8_t(l_crc_wr_latency_buffer), uint8_t(l_read_format));

    return FAPI2_RC_SUCCESS;
}

fapi2::ReturnCode (*mrs03_data::make_ccs_instruction)(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
        const mrs03_data& i_data,
        ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>& io_inst,
        const uint64_t i_rank) = &mrs03;

fapi2::ReturnCode (*mrs03_data::decode)(const ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>& i_inst,
                                        const uint64_t i_rank) = &mrs03_decode;

} // ns ddr4
} // ns mss
<commit_msg>Updated MR3 attributes in effective config<commit_after>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs03.C $ */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2016,2019                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* 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.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */

///
/// @file mrs03.C
/// @brief Run and manage the DDR4 DDR4 loading
///
// *HWP HWP Owner: Brian Silver <bsilver@us.ibm.com>
// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com>
// *HWP Team: Memory
// *HWP Level: 1
// *HWP Consumed by: FSP:HB

#include <fapi2.H>

#include <mss.H>
#include <lib/dimm/ddr4/mrs_load_ddr4.H>

using fapi2::TARGET_TYPE_MCBIST;
using fapi2::TARGET_TYPE_DIMM;

using fapi2::FAPI2_RC_SUCCESS;

namespace mss
{

namespace ddr4
{

///
/// @brief mrs03_data ctor
/// @param[in] a fapi2::TARGET_TYPE_DIMM target
/// @param[out] fapi2::ReturnCode FAPI2_RC_SUCCESS iff ok
///
mrs03_data::mrs03_data( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, fapi2::ReturnCode& o_rc ):
    iv_mpr_mode(fapi2::ENUM_ATTR_EFF_MPR_MODE_DISABLE),
    iv_mpr_page(fapi2::ENUM_ATTR_EFF_MPR_PAGE_PG0),
    iv_geardown(0),
    iv_pda(fapi2::ENUM_ATTR_EFF_PER_DRAM_ACCESS_DISABLE),
    iv_crc_wr_latency(0),
    iv_temp_readout(fapi2::ENUM_ATTR_EFF_TEMP_READOUT_DISABLE),
    iv_fine_refresh(0),
    iv_read_format(fapi2::ENUM_ATTR_EFF_MPR_RD_FORMAT_SERIAL)
{
    FAPI_TRY( mss::eff_mpr_mode(i_target, iv_mpr_mode) );
    FAPI_TRY( mss::eff_mpr_page(i_target, iv_mpr_page) );
    FAPI_TRY( mss::eff_geardown_mode(i_target, iv_geardown) );
    FAPI_TRY( mss::eff_per_dram_access(i_target, iv_pda) );
    FAPI_TRY( mss::eff_temp_readout(i_target, iv_temp_readout) );
    FAPI_TRY( mss::mrw_fine_refresh_mode(iv_fine_refresh) );
    FAPI_TRY( mss::eff_crc_wr_latency(i_target, iv_crc_wr_latency) );
    FAPI_TRY( mss::eff_mpr_rd_format(i_target, iv_read_format) );

    FAPI_INF("MR3 attributes: MPR_MODE: 0x%x, MPR_PAGE: 0x%x, GD: 0x%x, PDA: 0x%x, "
             "TEMP: 0x%x FR: 0x%x, CRC_WL: 0x%x, RF: 0x%x",
             iv_mpr_mode, iv_mpr_page, iv_geardown, iv_pda, iv_temp_readout,
             iv_fine_refresh, iv_crc_wr_latency, iv_read_format);

    o_rc = fapi2::FAPI2_RC_SUCCESS;
    return;

fapi_try_exit:
    o_rc = fapi2::current_err;
    FAPI_ERR("unable to get attributes for mrs0");
    return;
}

///
/// @brief Configure the ARR0 of the CCS instruction for mrs03
/// @param[in] i_target a fapi2::Target<TARGET_TYPE_DIMM>
/// @param[in,out] io_inst the instruction to fixup
/// @param[in] i_rank the rank in question
/// @return FAPI2_RC_SUCCESS iff OK
///
fapi2::ReturnCode mrs03(const fapi2::Target<TARGET_TYPE_DIMM>& i_target,
                        ccs::instruction_t<TARGET_TYPE_MCBIST>& io_inst,
                        const uint64_t i_rank)
{
    // Check to make sure our ctor worked ok
    mrs03_data l_data( i_target, fapi2::current_err );
    FAPI_TRY( fapi2::current_err, "Unable to construct MRS03 data from attributes");
    FAPI_TRY( mrs03(i_target, l_data, io_inst, i_rank) );

fapi_try_exit:
    return fapi2::current_err;
}

///
/// @brief Configure the ARR0 of the CCS instruction for mrs03, data object as input
/// @param[in] i_target a fapi2::Target<fapi2::TARGET_TYPE_DIMM>
/// @param[in] i_data an mrs00_data object, filled in
/// @param[in,out] io_inst the instruction to fixup
/// @param[in] i_rank the rank in question
/// @return FAPI2_RC_SUCCESS iff OK
///
fapi2::ReturnCode mrs03(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
                        const mrs03_data& i_data,
                        ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>& io_inst,
                        const uint64_t i_rank)
{
    constexpr uint64_t LOWEST_WL = 4;
    constexpr uint64_t WL_COUNT = 3;
    //                                                 4  5  6
    constexpr uint8_t crc_wr_latency_map[WL_COUNT] = { 0, 1, 2 };

    fapi2::buffer<uint8_t> l_crc_wr_latency_buffer;

    FAPI_ASSERT((i_data.iv_crc_wr_latency >= LOWEST_WL) && (i_data.iv_crc_wr_latency < (LOWEST_WL + WL_COUNT)),
                fapi2::MSS_BAD_MR_PARAMETER()
                .set_MR_NUMBER(3)
                .set_PARAMETER(WRITE_CMD_LATENCY)
                .set_PARAMETER_VALUE(i_data.iv_crc_wr_latency)
                .set_DIMM_IN_ERROR(i_target),
                "Bad value for Write CMD Latency: %d (%s)", i_data.iv_crc_wr_latency, mss::c_str(i_target));

    l_crc_wr_latency_buffer = crc_wr_latency_map[i_data.iv_crc_wr_latency - LOWEST_WL];

    mss::swizzle<A0, 2, 7>(fapi2::buffer<uint8_t>(i_data.iv_mpr_mode), io_inst.arr0);
    io_inst.arr0.writeBit<A2>(i_data.iv_mpr_page);
    io_inst.arr0.writeBit<A3>(i_data.iv_geardown);
    io_inst.arr0.writeBit<A4>(i_data.iv_pda);
    io_inst.arr0.writeBit<A5>(i_data.iv_temp_readout);

    mss::swizzle<A6 , 3, 7>(fapi2::buffer<uint8_t>(i_data.iv_fine_refresh), io_inst.arr0);
    mss::swizzle<A9 , 2, 7>(l_crc_wr_latency_buffer, io_inst.arr0);
    mss::swizzle<A11, 2, 7>(fapi2::buffer<uint8_t>(i_data.iv_read_format), io_inst.arr0);

    FAPI_INF("MR3: 0x%016llx", uint64_t(io_inst.arr0));

    return fapi2::FAPI2_RC_SUCCESS;

fapi_try_exit:
    return fapi2::current_err;
}

///
/// @brief Given a CCS instruction which contains address bits with an encoded MRS3,
/// decode and trace the contents
/// @param[in] i_inst the CCS instruction
/// @param[in] i_rank ths rank in question
/// @return void
///
fapi2::ReturnCode mrs03_decode(const ccs::instruction_t<TARGET_TYPE_MCBIST>& i_inst,
                               const uint64_t i_rank)
{
    fapi2::buffer<uint8_t> l_mpr_mode;

    fapi2::buffer<uint8_t> l_fine_refresh;
    fapi2::buffer<uint8_t> l_crc_wr_latency_buffer;
    fapi2::buffer<uint8_t> l_read_format;

    uint8_t l_mpr_page = i_inst.arr0.getBit<A2>();
    uint8_t l_geardown = i_inst.arr0.getBit<A3>();
    uint8_t l_pda = i_inst.arr0.getBit<A4>();
    uint8_t l_temp_readout = i_inst.arr0.getBit<A5>();

    mss::swizzle<6, 2, A1>(i_inst.arr0, l_mpr_mode);
    mss::swizzle<5, 3, A7>(i_inst.arr0, l_fine_refresh);
    mss::swizzle<6, 2, A10>(i_inst.arr0, l_crc_wr_latency_buffer);
    mss::swizzle<6, 2, A12>(i_inst.arr0, l_read_format);

    FAPI_INF("MR3 rank %d decode: MPR_MODE: 0x%x, MPR_PAGE: 0x%x, GD: 0x%x, PDA: 0x%x, "
             "TEMP: 0x%x FR: 0x%x, CRC_WL: 0x%x, RF: 0x%x", i_rank,
             uint8_t(l_mpr_mode), l_mpr_page, l_geardown, l_pda, uint8_t(l_temp_readout),
             uint8_t(l_fine_refresh), uint8_t(l_crc_wr_latency_buffer), uint8_t(l_read_format));

    return FAPI2_RC_SUCCESS;
}

fapi2::ReturnCode (*mrs03_data::make_ccs_instruction)(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
        const mrs03_data& i_data,
        ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>& io_inst,
        const uint64_t i_rank) = &mrs03;

fapi2::ReturnCode (*mrs03_data::decode)(const ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>& i_inst,
                                        const uint64_t i_rank) = &mrs03_decode;

} // ns ddr4
} // ns mss
<|endoftext|>


<commit_before>// Copyright (c) 2009 libmv authors.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.

#include "libmv/correspondence/feature.h"
#include "libmv/descriptor/descriptor.h"
#include "libmv/descriptor/vector_descriptor.h"
#include "libmv/image/convolve.h"
#include "libmv/image/image.h"
#include "libmv/image/integral_image.h"
#include "libmv/logging/logging.h"
#include "libmv/numeric/numeric.h"

namespace libmv {
namespace descriptor {

template<typename TImage>
float HarrX(const TImage &integral_image, int row, int col, int scale) {
  // Ignore the center strip for odd scales.
  int HW = scale / 2, W = scale;
  int C = W % 2;
  return float(BoxIntegral(integral_image, row - HW, col + C,  W, HW))
       - float(BoxIntegral(integral_image, row - HW, col - HW, W, HW));
}

template<typename TImage>
float HarrY(const TImage &integral_image, int row, int col, int scale) {
  // Ignore the center strip for odd scales.
  int HW = scale / 2, W = scale;
  int C = W % 2;
  return float(BoxIntegral(integral_image, row + C,  col - HW,  W, HW))
       - float(BoxIntegral(integral_image, row - HW, col - HW,  W, HW));
}

// TODO(keir): Concievably, these template parameters could be exposed to
// experiment with SURF parameters. Try that!
// descriptor must be sized to 4 * blocks *blocks
template<int blocks, int samples_per_block,
         typename TImage, typename TPointFeature>
void USURFDescriptor(const TImage &integral_image,
                     const TPointFeature &feature,
                     Vecf *descriptor) {
  float x = feature.x();
  float y = feature.y();
  float scale = feature.scale;
  const int int_scale = lround(2*scale);
  const int half_region = blocks*samples_per_block/2;

  // Since the Gaussian is a separable filter, precompute it.
  Matrix<float, 2*half_region, 1> gaussian;
  for (int i = -half_region; i < half_region; ++i) {
    gaussian(i + half_region) = Gaussian(i, 3.3*scale);
  }

  int done_dims = 0;
  for (int row = -half_region; row < half_region; row += samples_per_block) {
    for (int col = -half_region; col < half_region; col += samples_per_block) {
      Vec4f components(0,0,0,0);
      for (int r = row; r < row + samples_per_block; ++r) {
        for (int c = col; c < col + samples_per_block; ++c) {
          int sample_row = lround(y + scale*r);
          int sample_col = lround(x + scale*c);
          float weight = gaussian(r + half_region) * gaussian(c + half_region);
          Vec2f dxy;
          dxy << HarrX(integral_image, sample_row, sample_col, int_scale),
                 HarrY(integral_image, sample_row, sample_col, int_scale);
          dxy *= weight;
          components.start<2>() += dxy;
          components.end<2>() += dxy.cwise().abs();
        }
      }
      (*descriptor).segment<4>(done_dims) = components;
      done_dims += 4;
    }
  }
  descriptor->normalize();
}

class SurfDescriber : public Describer {
 public:
  virtual void Describe(const vector<Feature *> &features,
                        const Image &image,
                        const detector::DetectorData *detector_data,
                        vector<Descriptor *> *descriptors) {
    // TODO(keir): Make the descriptor data the SURF detector integral image.
    (void) detector_data;

    Matu integral_image;
    IntegralImage(*(image.AsArray3Du()), &integral_image);

    descriptors->resize(features.size());
    for (int i = 0; i < features.size(); ++i) {
      PointFeature *point = dynamic_cast<PointFeature *>(features[i]);
      VecfDescriptor *descriptor = NULL;
      if (point) {
        descriptor = new VecfDescriptor(64);
        USURFDescriptor<4, 5>(integral_image, *point, &descriptor->coords);
      }
      (*descriptors)[i] = descriptor;
    }
  }
};

Describer *CreateSurfDescriber() {
  return new SurfDescriber;
}

}  // namespace descriptor
}  // namespace libmv
<commit_msg>Add the MSURFDescriptor. A Surf descriptor with overlapping of sampling boxes and two pass weighting scheme. This descriptor support rotation.<commit_after>// Copyright (c) 2009 libmv authors.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.

#include "libmv/correspondence/feature.h"
#include "libmv/descriptor/descriptor.h"
#include "libmv/descriptor/vector_descriptor.h"
#include "libmv/image/convolve.h"
#include "libmv/image/image.h"
#include "libmv/image/integral_image.h"
#include "libmv/logging/logging.h"
#include "libmv/numeric/numeric.h"

namespace libmv {
namespace descriptor {

template<typename TImage>
float HarrX(const TImage &integral_image, int row, int col, int scale) {
  // Ignore the center strip for odd scales.
  int HW = scale / 2, W = scale;
  int C = W % 2;
  return float(BoxIntegral(integral_image, row - HW, col + C,  W, HW))
       - float(BoxIntegral(integral_image, row - HW, col - HW, W, HW));
}

template<typename TImage>
float HarrY(const TImage &integral_image, int row, int col, int scale) {
  // Ignore the center strip for odd scales.
  int HW = scale / 2, W = scale;
  int C = W % 2;
  return float(BoxIntegral(integral_image, row + C,  col - HW,  W, HW))
       - float(BoxIntegral(integral_image, row - HW, col - HW,  W, HW));
}

// TODO(keir): Concievably, these template parameters could be exposed to
// experiment with SURF parameters. Try that!
// descriptor must be sized to 4 * blocks *blocks
template<int blocks, int samples_per_block,
         typename TImage, typename TPointFeature>
void USURFDescriptor(const TImage &integral_image,
                     const TPointFeature &feature,
                     Vecf *descriptor) {
  float x = feature.x();
  float y = feature.y();
  float scale = feature.scale;
  const int int_scale = lround(2*scale);
  const int half_region = blocks*samples_per_block/2;

  // Since the Gaussian is a separable filter, precompute it.
  Matrix<float, 2*half_region, 1> gaussian;
  for (int i = -half_region; i < half_region; ++i) {
    gaussian(i + half_region) = Gaussian(i, 3.3*scale);
  }

  int done_dims = 0;
  for (int row = -half_region; row < half_region; row += samples_per_block) {
    for (int col = -half_region; col < half_region; col += samples_per_block) {
      Vec4f components(0,0,0,0);
      for (int r = row; r < row + samples_per_block; ++r) {
        for (int c = col; c < col + samples_per_block; ++c) {
          int sample_row = lround(y + scale*r);
          int sample_col = lround(x + scale*c);
          float weight = gaussian(r + half_region) * gaussian(c + half_region);
          Vec2f dxy;
          dxy << HarrX(integral_image, sample_row, sample_col, int_scale),
                 HarrY(integral_image, sample_row, sample_col, int_scale);
          dxy *= weight;
          components.start<2>() += dxy;
          components.end<2>() += dxy.cwise().abs();
        }
      }
      (*descriptor).segment<4>(done_dims) = components;
      done_dims += 4;
    }
  }
  descriptor->normalize();
}

// descriptor must be sized to 4 * blocks *blocks
template<int blocks, int samples_per_block,
         typename TImage, typename TPointFeature>
void MSURFDescriptor(const TImage &integral_image,
                     const TPointFeature &feature,
                     Vecf *descriptor) {
  float x = feature.x();
  float y = feature.y();
  float scale = feature.scale;
  const int int_scale = lround(2*scale);
  // Allow overlap between blocks
  const int half_region = blocks* (samples_per_block-(blocks-1))/2;

  // Since the Gaussian is a separable filter, precompute it.
  Matrix<float, 2*half_region, 1> gaussian;
  for (int i = -half_region; i < half_region; ++i) {
    gaussian(i + half_region) = Gaussian(i, 2*scale);
  }

  float co = 1.0f, si = 0.0f; // Suppose Upright descriptor
  bool bUpright = false; //Todo(pmoulon) set this variable as parameter
  if (!bUpright)
  {
    co = cos(feature.orientation);
    si = sin(feature.orientation);
  }

  int done_dims = 0;
  for (int row = -half_region; row < half_region - blocks;
        row += (samples_per_block - blocks)) {
    for (int col = -half_region; col < half_region - blocks;
        col += (samples_per_block - blocks)) {
      Vec4f components(0.0f,0.0f,0.0f,0.0f);
      for (int r = row; r < row + samples_per_block; ++r) {
        for (int c = col; c < col + samples_per_block; ++c) {

          //Get coords of sample point on the rotated axis
          int sample_col = lround(x + (-r*scale*si + c*scale*co));
          int sample_row = lround(y + ( r*scale*co + c*scale*si));

          float weight = gaussian(r + half_region) * gaussian(c + half_region);
          //Compute Harr response on rotated axis
          float rrx = HarrX(integral_image, sample_row, sample_col, int_scale);
          float rry = HarrY(integral_image, sample_row, sample_col, int_scale);

          Vec2f dxy;
          dxy << (co*rry - si*rrx),
                 (si*rry + co*rrx);
          dxy *= weight;
          components.start<2>() += dxy;
          components.end<2>() += dxy.cwise().abs();
        }
      }
      float gauss_BigBox = Gaussian2D(row/half_region,col/half_region,1.0f);
      (*descriptor).segment<4>(done_dims) = components*gauss_BigBox;
      done_dims += 4;
    }
  }
  descriptor->normalize();
}

class SurfDescriber : public Describer {
 public:
  virtual void Describe(const vector<Feature *> &features,
                        const Image &image,
                        const detector::DetectorData *detector_data,
                        vector<Descriptor *> *descriptors) {
    // TODO(keir): Make the descriptor data the SURF detector integral image.
    (void) detector_data;

    Matu integral_image;
    IntegralImage(*(image.AsArray3Du()), &integral_image);

    descriptors->resize(features.size());
    for (int i = 0; i < features.size(); ++i) {
      PointFeature *point = dynamic_cast<PointFeature *>(features[i]);
      VecfDescriptor *descriptor = NULL;
      if (point) {
        descriptor = new VecfDescriptor(64);
        MSURFDescriptor<4, 9>(integral_image, *point, &descriptor->coords);
      }
      (*descriptors)[i] = descriptor;
    }
  }
};

Describer *CreateSurfDescriber() {
  return new SurfDescriber;
}

}  // namespace descriptor
}  // namespace libmv
<|endoftext|>


<commit_before>/* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.

  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation; version 2 of the License.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software Foundation,
  51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */

/**
  @file storage/perfschema/ha_perfschema.cc
  Performance schema storage engine (implementation).
*/

#include "my_global.h"
#include "my_pthread.h"
#include "sql_plugin.h"
#include "mysql/plugin.h"
#include "ha_perfschema.h"
#include "pfs_engine_table.h"
#include "pfs_column_values.h"
#include "pfs_instr_class.h"
#include "pfs_instr.h"

handlerton *pfs_hton= NULL;

static handler* pfs_create_handler(handlerton *hton,
                                   TABLE_SHARE *table,
                                   MEM_ROOT *mem_root)
{
  return new (mem_root) ha_perfschema(hton, table);
}

static int compare_database_names(const char *name1, const char *name2)
{
  if (lower_case_table_names)
    return strcasecmp(name1, name2);
  return strcmp(name1, name2);
}

static const PFS_engine_table_share*
find_table_share(const char *db, const char *name)
{
  DBUG_ENTER("find_table_share");

  if (compare_database_names(db, PERFORMANCE_SCHEMA_str.str) != 0)
    DBUG_RETURN(NULL);

  const PFS_engine_table_share* result;
  result= PFS_engine_table::find_engine_table_share(name);
  DBUG_RETURN(result);
}

static int pfs_init_func(void *p)
{
  DBUG_ENTER("pfs_init_func");

  pfs_hton= reinterpret_cast<handlerton *> (p);

  pfs_hton->state= SHOW_OPTION_YES;
  pfs_hton->create= pfs_create_handler;
  pfs_hton->show_status= pfs_show_status;
  pfs_hton->flags= HTON_ALTER_NOT_SUPPORTED |
    HTON_TEMPORARY_NOT_SUPPORTED |
    HTON_NO_PARTITION;

  /*
    As long as the server implementation keeps using legacy_db_type,
    as for example in mysql_truncate(),
    we can not rely on the fact that different mysqld process will assign
    consistently the same legacy_db_type for a given storage engine name.
    In particular, using different --loose-skip-xxx options between
    ./mysqld --bootstrap
    ./mysqld
    creates bogus .frm forms when bootstrapping the performance schema,
    if we rely on ha_initialize_handlerton to assign a really dynamic value.
    To fix this, a dedicated DB_TYPE is officially assigned to
    the performance schema. See Bug#43039.
  */
  pfs_hton->db_type= DB_TYPE_PERFORMANCE_SCHEMA;

  PFS_engine_table_share::init_all_locks();

  DBUG_RETURN(0);
}

static int pfs_done_func(void *p)
{
  DBUG_ENTER("pfs_done_func");

  pfs_hton= NULL;

  PFS_engine_table_share::delete_all_locks();

  DBUG_RETURN(0);
}

static struct st_mysql_show_var pfs_status_vars[]=
{
  {"Performance_schema_mutex_classes_lost",
    (char*) &mutex_class_lost, SHOW_LONG_NOFLUSH},
  {"Performance_schema_rwlock_classes_lost",
    (char*) &rwlock_class_lost, SHOW_LONG_NOFLUSH},
  {"Performance_schema_cond_classes_lost",
    (char*) &cond_class_lost, SHOW_LONG_NOFLUSH},
  {"Performance_schema_thread_classes_lost",
    (char*) &thread_class_lost, SHOW_LONG_NOFLUSH},
  {"Performance_schema_file_classes_lost",
    (char*) &file_class_lost, SHOW_LONG_NOFLUSH},
  {"Performance_schema_mutex_instances_lost",
    (char*) &mutex_lost, SHOW_LONG},
  {"Performance_schema_rwlock_instances_lost",
    (char*) &rwlock_lost, SHOW_LONG},
  {"Performance_schema_cond_instances_lost",
    (char*) &cond_lost, SHOW_LONG},
  {"Performance_schema_thread_instances_lost",
    (char*) &thread_lost, SHOW_LONG},
  {"Performance_schema_file_instances_lost",
    (char*) &file_lost, SHOW_LONG},
  {"Performance_schema_file_handles_lost",
    (char*) &file_handle_lost, SHOW_LONG},
  {"Performance_schema_locker_lost",
    (char*) &locker_lost, SHOW_LONG},
  /* table shares, can be flushed */
  {"Performance_schema_table_instances_lost",
    (char*) &table_share_lost, SHOW_LONG},
  /* table handles, can be flushed */
  {"Performance_schema_table_handles_lost",
    (char*) &table_lost, SHOW_LONG},
  {NullS, NullS, SHOW_LONG}
};

struct st_mysql_storage_engine pfs_storage_engine=
{ MYSQL_HANDLERTON_INTERFACE_VERSION };

const char* pfs_engine_name= "PERFORMANCE_SCHEMA";

mysql_declare_plugin(perfschema)
{
  MYSQL_STORAGE_ENGINE_PLUGIN,
  &pfs_storage_engine,
  pfs_engine_name,
  "Marc Alff, Oracle", /* Formerly Sun Microsystems, formerly MySQL */
  "Performance Schema",
  PLUGIN_LICENSE_GPL,
  pfs_init_func,                                /* Plugin Init */
  pfs_done_func,                                /* Plugin Deinit */
  0x0001 /* 0.1 */,
  pfs_status_vars,                              /* status variables */
  NULL,                                         /* system variables */
  NULL                                          /* config options */
}
mysql_declare_plugin_end;

ha_perfschema::ha_perfschema(handlerton *hton, TABLE_SHARE *share)
  : handler(hton, share), m_table_share(NULL), m_table(NULL)
{}

ha_perfschema::~ha_perfschema()
{}

static const char *ha_pfs_exts[]= {
  NullS
};

const char **ha_perfschema::bas_ext() const
{
  return ha_pfs_exts;
}

int ha_perfschema::open(const char *name, int mode, uint test_if_locked)
{
  DBUG_ENTER("ha_perfschema::open");

  m_table_share= find_table_share(table_share->db.str,
                                  table_share->table_name.str);
  if (! m_table_share)
    DBUG_RETURN(HA_ERR_NO_SUCH_TABLE);

  thr_lock_data_init(m_table_share->m_thr_lock_ptr, &m_thr_lock, NULL);
  ref_length= m_table_share->m_ref_length;

  psi_open();

  DBUG_RETURN(0);
}

int ha_perfschema::close(void)
{
  DBUG_ENTER("ha_perfschema::close");
  m_table_share= NULL;
  delete m_table;
  m_table= NULL;

  psi_close();

  DBUG_RETURN(0);
}

int ha_perfschema::write_row(uchar *buf)
{
  int result;

  DBUG_ENTER("ha_perfschema::write_row");

  ha_statistic_increment(&SSV::ha_write_count);
  DBUG_ASSERT(m_table_share);

  if (m_table_share->m_write_row)
    result= m_table_share->m_write_row(table, buf, table->field);
  else
  {
    my_error(ER_WRONG_PERFSCHEMA_USAGE, MYF(0));
    result= HA_ERR_WRONG_COMMAND;
  }

  DBUG_RETURN(result);
}

void ha_perfschema::use_hidden_primary_key(void)
{
  /*
    This is also called in case of row based replication,
    see TABLE::mark_columns_needed_for_update().
    Add all columns to the read set, but do not touch the write set,
    as some columns in the SETUP_ tables are not writable.
  */
  table->column_bitmaps_set_no_signal(&table->s->all_set, table->write_set);
}

int ha_perfschema::update_row(const uchar *old_data, uchar *new_data)
{
  DBUG_ENTER("ha_perfschema::update_row");

  DBUG_ASSERT(m_table);
  int result= m_table->update_row(table, old_data, new_data, table->field);
  DBUG_RETURN(result);
}

int ha_perfschema::rnd_init(bool scan)
{
  int result;
  DBUG_ENTER("ha_perfschema::rnd_init");

  DBUG_ASSERT(m_table_share);
  DBUG_ASSERT(m_table_share->m_open_table != NULL);

  stats.records= 0;
  if (m_table == NULL)
    m_table= m_table_share->m_open_table();
  else
    m_table->reset_position();

  result= m_table ? 0 : HA_ERR_OUT_OF_MEM;
  DBUG_RETURN(result);
}

int ha_perfschema::rnd_end(void)
{
  DBUG_ENTER("ha_perfschema::rnd_end");
  DBUG_ASSERT(m_table);
  delete m_table;
  m_table= NULL;
  DBUG_RETURN(0);
}

int ha_perfschema::rnd_next(uchar *buf)
{
  DBUG_ENTER("ha_perfschema::rnd_next");

  DBUG_ASSERT(m_table);
  int result= m_table->rnd_next();
  if (result == 0)
  {
    result= m_table->read_row(table, buf, table->field);
    if (result == 0)
      stats.records++;
  }
  DBUG_RETURN(result);
}

void ha_perfschema::position(const uchar *record)
{
  DBUG_ENTER("ha_perfschema::position");

  DBUG_ASSERT(m_table);
  m_table->get_position(ref);
  DBUG_VOID_RETURN;
}

int ha_perfschema::rnd_pos(uchar *buf, uchar *pos)
{
  DBUG_ENTER("ha_perfschema::rnd_pos");

  DBUG_ASSERT(m_table);
  int result= m_table->rnd_pos(pos);
  if (result == 0)
    result= m_table->read_row(table, buf, table->field);
  DBUG_RETURN(result);
}

int ha_perfschema::info(uint flag)
{
  DBUG_ENTER("ha_perfschema::info");
  DBUG_ASSERT(m_table_share);
  if (flag & HA_STATUS_VARIABLE)
    stats.records= m_table_share->m_records;
  if (flag & HA_STATUS_CONST)
    ref_length= m_table_share->m_ref_length;
  DBUG_RETURN(0);
}

int ha_perfschema::delete_all_rows(void)
{
  int result;

  DBUG_ENTER("ha_perfschema::delete_all_rows");

  DBUG_ASSERT(m_table_share);
  if (m_table_share->m_delete_all_rows)
    result= m_table_share->m_delete_all_rows();
  else
  {
    my_error(ER_WRONG_PERFSCHEMA_USAGE, MYF(0));
    result= HA_ERR_WRONG_COMMAND;
  }
  DBUG_RETURN(result);
}

THR_LOCK_DATA **ha_perfschema::store_lock(THD *thd,
                                       THR_LOCK_DATA **to,
                                       enum thr_lock_type lock_type)
{
  if (lock_type != TL_IGNORE && m_thr_lock.type == TL_UNLOCK)
    m_thr_lock.type= lock_type;
  *to++= &m_thr_lock;
  m_thr_lock.m_psi= m_psi;
  return to;
}

int ha_perfschema::delete_table(const char *name)
{
  DBUG_ENTER("ha_perfschema::delete_table");
  DBUG_RETURN(0);
}

int ha_perfschema::rename_table(const char * from, const char * to)
{
  DBUG_ENTER("ha_perfschema::rename_table ");
  my_error(ER_WRONG_PERFSCHEMA_USAGE, MYF(0));
  DBUG_RETURN(HA_ERR_WRONG_COMMAND);
}

int ha_perfschema::create(const char *name, TABLE *table_arg,
                          HA_CREATE_INFO *create_info)
{
  DBUG_ENTER("ha_perfschema::create");
  DBUG_ASSERT(table_arg);
  DBUG_ASSERT(table_arg->s);
  if (find_table_share(table_arg->s->db.str,
                       table_arg->s->table_name.str))
  {
    /*
      Attempting to create a known performance schema table.
      Allowing the create, to create .FRM files,
      for the initial database install, and mysql_upgrade.
      This should fail once .FRM are removed.
    */
    DBUG_RETURN(0);
  }
  /*
    This is not a general purpose engine.
    Failure to CREATE TABLE is the expected result.
  */
  my_error(ER_WRONG_PERFSCHEMA_USAGE, MYF(0));
  DBUG_RETURN(HA_ERR_WRONG_COMMAND);
}

<commit_msg>Selective transfer of a bugfix patch into 5.5.6-rc.<commit_after>/* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.

  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation; version 2 of the License.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software Foundation,
  51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */

/**
  @file storage/perfschema/ha_perfschema.cc
  Performance schema storage engine (implementation).
*/

#include "my_global.h"
#include "my_pthread.h"
#include "my_atomic.h"
#include "sql_plugin.h"
#include "mysql/plugin.h"
#include "ha_perfschema.h"
#include "pfs_engine_table.h"
#include "pfs_column_values.h"
#include "pfs_instr_class.h"
#include "pfs_instr.h"

#ifdef MY_ATOMIC_MODE_DUMMY
/*
  The performance schema can can not function with MY_ATOMIC_MODE_DUMMY,
  a fully functional implementation of MY_ATOMIC should be used instead.
  If the build fails with this error message:
  - either use a different ./configure --with-atomic-ops option
  - or do not build with the performance schema.
*/
#error "The performance schema needs a functional MY_ATOMIC implementation."
#endif

handlerton *pfs_hton= NULL;

static handler* pfs_create_handler(handlerton *hton,
                                   TABLE_SHARE *table,
                                   MEM_ROOT *mem_root)
{
  return new (mem_root) ha_perfschema(hton, table);
}

static int compare_database_names(const char *name1, const char *name2)
{
  if (lower_case_table_names)
    return strcasecmp(name1, name2);
  return strcmp(name1, name2);
}

static const PFS_engine_table_share*
find_table_share(const char *db, const char *name)
{
  DBUG_ENTER("find_table_share");

  if (compare_database_names(db, PERFORMANCE_SCHEMA_str.str) != 0)
    DBUG_RETURN(NULL);

  const PFS_engine_table_share* result;
  result= PFS_engine_table::find_engine_table_share(name);
  DBUG_RETURN(result);
}

static int pfs_init_func(void *p)
{
  DBUG_ENTER("pfs_init_func");

  pfs_hton= reinterpret_cast<handlerton *> (p);

  pfs_hton->state= SHOW_OPTION_YES;
  pfs_hton->create= pfs_create_handler;
  pfs_hton->show_status= pfs_show_status;
  pfs_hton->flags= HTON_ALTER_NOT_SUPPORTED |
    HTON_TEMPORARY_NOT_SUPPORTED |
    HTON_NO_PARTITION;

  /*
    As long as the server implementation keeps using legacy_db_type,
    as for example in mysql_truncate(),
    we can not rely on the fact that different mysqld process will assign
    consistently the same legacy_db_type for a given storage engine name.
    In particular, using different --loose-skip-xxx options between
    ./mysqld --bootstrap
    ./mysqld
    creates bogus .frm forms when bootstrapping the performance schema,
    if we rely on ha_initialize_handlerton to assign a really dynamic value.
    To fix this, a dedicated DB_TYPE is officially assigned to
    the performance schema. See Bug#43039.
  */
  pfs_hton->db_type= DB_TYPE_PERFORMANCE_SCHEMA;

  PFS_engine_table_share::init_all_locks();

  DBUG_RETURN(0);
}

static int pfs_done_func(void *p)
{
  DBUG_ENTER("pfs_done_func");

  pfs_hton= NULL;

  PFS_engine_table_share::delete_all_locks();

  DBUG_RETURN(0);
}

static struct st_mysql_show_var pfs_status_vars[]=
{
  {"Performance_schema_mutex_classes_lost",
    (char*) &mutex_class_lost, SHOW_LONG_NOFLUSH},
  {"Performance_schema_rwlock_classes_lost",
    (char*) &rwlock_class_lost, SHOW_LONG_NOFLUSH},
  {"Performance_schema_cond_classes_lost",
    (char*) &cond_class_lost, SHOW_LONG_NOFLUSH},
  {"Performance_schema_thread_classes_lost",
    (char*) &thread_class_lost, SHOW_LONG_NOFLUSH},
  {"Performance_schema_file_classes_lost",
    (char*) &file_class_lost, SHOW_LONG_NOFLUSH},
  {"Performance_schema_mutex_instances_lost",
    (char*) &mutex_lost, SHOW_LONG},
  {"Performance_schema_rwlock_instances_lost",
    (char*) &rwlock_lost, SHOW_LONG},
  {"Performance_schema_cond_instances_lost",
    (char*) &cond_lost, SHOW_LONG},
  {"Performance_schema_thread_instances_lost",
    (char*) &thread_lost, SHOW_LONG},
  {"Performance_schema_file_instances_lost",
    (char*) &file_lost, SHOW_LONG},
  {"Performance_schema_file_handles_lost",
    (char*) &file_handle_lost, SHOW_LONG},
  {"Performance_schema_locker_lost",
    (char*) &locker_lost, SHOW_LONG},
  /* table shares, can be flushed */
  {"Performance_schema_table_instances_lost",
    (char*) &table_share_lost, SHOW_LONG},
  /* table handles, can be flushed */
  {"Performance_schema_table_handles_lost",
    (char*) &table_lost, SHOW_LONG},
  {NullS, NullS, SHOW_LONG}
};

struct st_mysql_storage_engine pfs_storage_engine=
{ MYSQL_HANDLERTON_INTERFACE_VERSION };

const char* pfs_engine_name= "PERFORMANCE_SCHEMA";

mysql_declare_plugin(perfschema)
{
  MYSQL_STORAGE_ENGINE_PLUGIN,
  &pfs_storage_engine,
  pfs_engine_name,
  "Marc Alff, Oracle", /* Formerly Sun Microsystems, formerly MySQL */
  "Performance Schema",
  PLUGIN_LICENSE_GPL,
  pfs_init_func,                                /* Plugin Init */
  pfs_done_func,                                /* Plugin Deinit */
  0x0001 /* 0.1 */,
  pfs_status_vars,                              /* status variables */
  NULL,                                         /* system variables */
  NULL                                          /* config options */
}
mysql_declare_plugin_end;

ha_perfschema::ha_perfschema(handlerton *hton, TABLE_SHARE *share)
  : handler(hton, share), m_table_share(NULL), m_table(NULL)
{}

ha_perfschema::~ha_perfschema()
{}

static const char *ha_pfs_exts[]= {
  NullS
};

const char **ha_perfschema::bas_ext() const
{
  return ha_pfs_exts;
}

int ha_perfschema::open(const char *name, int mode, uint test_if_locked)
{
  DBUG_ENTER("ha_perfschema::open");

  m_table_share= find_table_share(table_share->db.str,
                                  table_share->table_name.str);
  if (! m_table_share)
    DBUG_RETURN(HA_ERR_NO_SUCH_TABLE);

  thr_lock_data_init(m_table_share->m_thr_lock_ptr, &m_thr_lock, NULL);
  ref_length= m_table_share->m_ref_length;

  psi_open();

  DBUG_RETURN(0);
}

int ha_perfschema::close(void)
{
  DBUG_ENTER("ha_perfschema::close");
  m_table_share= NULL;
  delete m_table;
  m_table= NULL;

  psi_close();

  DBUG_RETURN(0);
}

int ha_perfschema::write_row(uchar *buf)
{
  int result;

  DBUG_ENTER("ha_perfschema::write_row");

  ha_statistic_increment(&SSV::ha_write_count);
  DBUG_ASSERT(m_table_share);

  if (m_table_share->m_write_row)
    result= m_table_share->m_write_row(table, buf, table->field);
  else
  {
    my_error(ER_WRONG_PERFSCHEMA_USAGE, MYF(0));
    result= HA_ERR_WRONG_COMMAND;
  }

  DBUG_RETURN(result);
}

void ha_perfschema::use_hidden_primary_key(void)
{
  /*
    This is also called in case of row based replication,
    see TABLE::mark_columns_needed_for_update().
    Add all columns to the read set, but do not touch the write set,
    as some columns in the SETUP_ tables are not writable.
  */
  table->column_bitmaps_set_no_signal(&table->s->all_set, table->write_set);
}

int ha_perfschema::update_row(const uchar *old_data, uchar *new_data)
{
  DBUG_ENTER("ha_perfschema::update_row");

  DBUG_ASSERT(m_table);
  int result= m_table->update_row(table, old_data, new_data, table->field);
  DBUG_RETURN(result);
}

int ha_perfschema::rnd_init(bool scan)
{
  int result;
  DBUG_ENTER("ha_perfschema::rnd_init");

  DBUG_ASSERT(m_table_share);
  DBUG_ASSERT(m_table_share->m_open_table != NULL);

  stats.records= 0;
  if (m_table == NULL)
    m_table= m_table_share->m_open_table();
  else
    m_table->reset_position();

  result= m_table ? 0 : HA_ERR_OUT_OF_MEM;
  DBUG_RETURN(result);
}

int ha_perfschema::rnd_end(void)
{
  DBUG_ENTER("ha_perfschema::rnd_end");
  DBUG_ASSERT(m_table);
  delete m_table;
  m_table= NULL;
  DBUG_RETURN(0);
}

int ha_perfschema::rnd_next(uchar *buf)
{
  DBUG_ENTER("ha_perfschema::rnd_next");

  DBUG_ASSERT(m_table);
  int result= m_table->rnd_next();
  if (result == 0)
  {
    result= m_table->read_row(table, buf, table->field);
    if (result == 0)
      stats.records++;
  }
  DBUG_RETURN(result);
}

void ha_perfschema::position(const uchar *record)
{
  DBUG_ENTER("ha_perfschema::position");

  DBUG_ASSERT(m_table);
  m_table->get_position(ref);
  DBUG_VOID_RETURN;
}

int ha_perfschema::rnd_pos(uchar *buf, uchar *pos)
{
  DBUG_ENTER("ha_perfschema::rnd_pos");

  DBUG_ASSERT(m_table);
  int result= m_table->rnd_pos(pos);
  if (result == 0)
    result= m_table->read_row(table, buf, table->field);
  DBUG_RETURN(result);
}

int ha_perfschema::info(uint flag)
{
  DBUG_ENTER("ha_perfschema::info");
  DBUG_ASSERT(m_table_share);
  if (flag & HA_STATUS_VARIABLE)
    stats.records= m_table_share->m_records;
  if (flag & HA_STATUS_CONST)
    ref_length= m_table_share->m_ref_length;
  DBUG_RETURN(0);
}

int ha_perfschema::delete_all_rows(void)
{
  int result;

  DBUG_ENTER("ha_perfschema::delete_all_rows");

  DBUG_ASSERT(m_table_share);
  if (m_table_share->m_delete_all_rows)
    result= m_table_share->m_delete_all_rows();
  else
  {
    my_error(ER_WRONG_PERFSCHEMA_USAGE, MYF(0));
    result= HA_ERR_WRONG_COMMAND;
  }
  DBUG_RETURN(result);
}

THR_LOCK_DATA **ha_perfschema::store_lock(THD *thd,
                                       THR_LOCK_DATA **to,
                                       enum thr_lock_type lock_type)
{
  if (lock_type != TL_IGNORE && m_thr_lock.type == TL_UNLOCK)
    m_thr_lock.type= lock_type;
  *to++= &m_thr_lock;
  m_thr_lock.m_psi= m_psi;
  return to;
}

int ha_perfschema::delete_table(const char *name)
{
  DBUG_ENTER("ha_perfschema::delete_table");
  DBUG_RETURN(0);
}

int ha_perfschema::rename_table(const char * from, const char * to)
{
  DBUG_ENTER("ha_perfschema::rename_table ");
  my_error(ER_WRONG_PERFSCHEMA_USAGE, MYF(0));
  DBUG_RETURN(HA_ERR_WRONG_COMMAND);
}

int ha_perfschema::create(const char *name, TABLE *table_arg,
                          HA_CREATE_INFO *create_info)
{
  DBUG_ENTER("ha_perfschema::create");
  DBUG_ASSERT(table_arg);
  DBUG_ASSERT(table_arg->s);
  if (find_table_share(table_arg->s->db.str,
                       table_arg->s->table_name.str))
  {
    /*
      Attempting to create a known performance schema table.
      Allowing the create, to create .FRM files,
      for the initial database install, and mysql_upgrade.
      This should fail once .FRM are removed.
    */
    DBUG_RETURN(0);
  }
  /*
    This is not a general purpose engine.
    Failure to CREATE TABLE is the expected result.
  */
  my_error(ER_WRONG_PERFSCHEMA_USAGE, MYF(0));
  DBUG_RETURN(HA_ERR_WRONG_COMMAND);
}

<|endoftext|>


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

  Program:   Visualization Toolkit
  Module:    TestDelimitedTextReader.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

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

=========================================================================*/
/*----------------------------------------------------------------------------
 Copyright (c) Sandia Corporation
 See Copyright.txt or http://www.paraview.org/HTML/Copyright.html for details.
----------------------------------------------------------------------------*/

#include <vtkDelimitedTextReader.h>
#include <vtkStringArray.h>
#include <vtkTable.h>
#include <vtkVariant.h>
#include <vtkVariantArray.h>
#include <vtkTestUtilities.h>
#include <vtkIOStream.h>

int
TestDelimitedTextReader(int argc, char *argv[])
{

  char *filename = vtkTestUtilities::ExpandDataFileName(argc, argv,
                                                        "Data/delimited.txt");

  cout << "Filename: " << filename << endl;

  vtkDelimitedTextReader *reader = vtkDelimitedTextReader::New();
  reader->SetFieldDelimiter(':');
  reader->SetStringDelimiter('"');
  reader->SetUseStringDelimiter(true);
  reader->SetFileName(filename);
  reader->SetHaveHeaders(false);
  reader->Update();

  cout << "Printing reader info..." << endl;
  reader->Print(cout);

  vtkTable *table = reader->GetOutput();

  cout << "Delimited text file has " << table->GetNumberOfRows()
       << " rows" << endl;
  cout << "Delimited text file has " << table->GetNumberOfColumns()
       << " columns" << endl;

  cout << "Table contents:" << endl;

  for (vtkIdType i = 0; i < table->GetNumberOfRows(); ++i)
    {
    vtkVariantArray *row = table->GetRow(i);

    for (vtkIdType j = 0; j < row->GetNumberOfTuples(); ++j)
      {
      cout << "Row " << i << " column " << j << ": ";

      vtkVariant value = row->GetValue(j);
      if (! value.IsValid())
        {
        cout << "invalid value" << endl;
        }
      else
        {
        cout << "type " << value.GetTypeAsString() << " value "
             << value.ToString() << endl;
        }
      }
    }

  reader->Delete();

  return 0;
}

<commit_msg>BUG: Fix a memory leak.  I didn't know that the vtkVariantArray returned by vtkTable::GetRow is allocated afresh every time you call the method.<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    TestDelimitedTextReader.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

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

=========================================================================*/
/*----------------------------------------------------------------------------
 Copyright (c) Sandia Corporation
 See Copyright.txt or http://www.paraview.org/HTML/Copyright.html for details.
----------------------------------------------------------------------------*/

#include <vtkDelimitedTextReader.h>
#include <vtkStringArray.h>
#include <vtkTable.h>
#include <vtkVariant.h>
#include <vtkVariantArray.h>
#include <vtkTestUtilities.h>
#include <vtkIOStream.h>

int
TestDelimitedTextReader(int argc, char *argv[])
{

  char *filename = vtkTestUtilities::ExpandDataFileName(argc, argv,
                                                        "Data/delimited.txt");

  cout << "Filename: " << filename << endl;

  vtkDelimitedTextReader *reader = vtkDelimitedTextReader::New();
  reader->SetFieldDelimiter(':');
  reader->SetStringDelimiter('"');
  reader->SetUseStringDelimiter(true);
  reader->SetFileName(filename);
  reader->SetHaveHeaders(false);
  reader->Update();

  cout << "Printing reader info..." << endl;
  reader->Print(cout);

  vtkTable *table = reader->GetOutput();

  cout << "Delimited text file has " << table->GetNumberOfRows()
       << " rows" << endl;
  cout << "Delimited text file has " << table->GetNumberOfColumns()
       << " columns" << endl;

  cout << "Table contents:" << endl;

  for (vtkIdType i = 0; i < table->GetNumberOfRows(); ++i)
    {
    vtkVariantArray *row = table->GetRow(i);

    for (vtkIdType j = 0; j < row->GetNumberOfTuples(); ++j)
      {
      cout << "Row " << i << " column " << j << ": ";

      vtkVariant value = row->GetValue(j);
      if (! value.IsValid())
        {
        cout << "invalid value" << endl;
        }
      else
        {
        cout << "type " << value.GetTypeAsString() << " value "
             << value.ToString() << endl;
        }
      }

    row->Delete();

    }

  reader->Delete();

  return 0;
}

<|endoftext|>