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

/* Author: Ioan Sucan */

#include <moveit/constraint_samplers/union_constraint_sampler.h>
#include <moveit/constraint_samplers/default_constraint_samplers.h>
#include <algorithm>

namespace constraint_samplers
{
struct OrderSamplers
{
  bool operator()(const ConstraintSamplerPtr &a, const ConstraintSamplerPtr &b) const
  {
    const std::vector<std::string> &alinks = a->getJointModelGroup()->getUpdatedLinkModelNames();
    const std::vector<std::string> &blinks = b->getJointModelGroup()->getUpdatedLinkModelNames();
    std::set<std::string> a_updates(alinks.begin(), alinks.end());
    std::set<std::string> b_updates(blinks.begin(), blinks.end());

    bool a_contains_b = std::includes(a_updates.begin(), a_updates.end(), b_updates.begin(), b_updates.end());

    bool b_contains_a = std::includes(b_updates.begin(), b_updates.end(), a_updates.begin(), a_updates.end());

    // a contains b and sets are not equal
    if (a_contains_b && !b_contains_a)
      return true;
    if (b_contains_a && !a_contains_b)
      return false;

    // sets are equal or disjoint
    bool a_depends_on_b = false;
    bool b_depends_on_a = false;
    const std::vector<std::string> &fda = a->getFrameDependency();
    const std::vector<std::string> &fdb = b->getFrameDependency();
    for (std::size_t i = 0; i < fda.size() && !a_depends_on_b; ++i)
      for (std::size_t j = 0; j < blinks.size(); ++j)
        if (blinks[j] == fda[i])
        {
          a_depends_on_b = true;
          break;
        }
    for (std::size_t i = 0; i < fdb.size() && !b_depends_on_a; ++i)
      for (std::size_t j = 0; j < alinks.size(); ++j)
        if (alinks[j] == fdb[i])
        {
          b_depends_on_a = true;
          break;
        }
    if (b_depends_on_a && a_depends_on_b)
    {
      logWarn("Circular frame dependency! Sampling will likely produce invalid results (sampling for groups '%s' and "
              "'%s')",
              a->getJointModelGroup()->getName().c_str(), b->getJointModelGroup()->getName().c_str());
      return true;
    }
    if (b_depends_on_a && !a_depends_on_b)
      return true;
    if (a_depends_on_b && !b_depends_on_a)
      return false;

    // prefer sampling JointConstraints first
    JointConstraintSampler *ja = dynamic_cast<JointConstraintSampler *>(a.get());
    JointConstraintSampler *jb = dynamic_cast<JointConstraintSampler *>(b.get());
    if (ja && jb == NULL)
      return true;
    if (jb && ja == NULL)
      return false;

    // neither depends on either, so break ties based on group name
    return (a->getJointModelGroup()->getName() < b->getJointModelGroup()->getName());
  }
};
}

constraint_samplers::UnionConstraintSampler::UnionConstraintSampler(const planning_scene::PlanningSceneConstPtr &scene,
                                                                    const std::string &group_name,
                                                                    const std::vector<ConstraintSamplerPtr> &samplers)
  : ConstraintSampler(scene, group_name), samplers_(samplers)
{
  // using stable sort to preserve order of equivalents
  std::stable_sort(samplers_.begin(), samplers_.end(), OrderSamplers());

  for (std::size_t i = 0; i < samplers_.size(); ++i)
  {
    const std::vector<std::string> &fd = samplers_[i]->getFrameDependency();
    for (std::size_t j = 0; j < fd.size(); ++j)
      frame_depends_.push_back(fd[j]);

    logDebug("Union sampler for group '%s' includes sampler for group '%s'", jmg_->getName().c_str(),
             samplers_[i]->getJointModelGroup()->getName().c_str());
  }
}

bool constraint_samplers::UnionConstraintSampler::sample(robot_state::RobotState &state,
                                                         const robot_state::RobotState &reference_state,
                                                         unsigned int max_attempts)
{
  state = reference_state;
  state.setToRandomPositions(jmg_);

  if (samplers_.size() >= 1)
  {
    if (!samplers_[0]->sample(state, reference_state, max_attempts))
      return false;
  }

  for (std::size_t i = 1; i < samplers_.size(); ++i)
  {
    // ConstraintSampler::sample returns states with dirty link transforms (because it only writes values)
    // but requires a state with clean link transforms as input. This means that we need to clean the link
    // transforms between calls to ConstraintSampler::sample.
    state.updateLinkTransforms();
    if (!samplers_[i]->sample(state, state, max_attempts))
      return false;
  }
  return true;
}

bool constraint_samplers::UnionConstraintSampler::project(robot_state::RobotState &state, unsigned int max_attempts)
{
  for (std::size_t i = 0; i < samplers_.size(); ++i)
    if (!samplers_[i]->project(state, max_attempts))
      return false;
  return true;
}
<commit_msg>update link transforms in UnionConstraintSampler::project (#384)<commit_after>/*********************************************************************
 * Software License Agreement (BSD License)
 *
 *  Copyright (c) 2011, Willow Garage, Inc.
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above
 *     copyright notice, this list of conditions and the following
 *     disclaimer in the documentation and/or other materials provided
 *     with the distribution.
 *   * Neither the name of Willow Garage nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *  POSSIBILITY OF SUCH DAMAGE.
 *********************************************************************/

/* Author: Ioan Sucan */

#include <moveit/constraint_samplers/union_constraint_sampler.h>
#include <moveit/constraint_samplers/default_constraint_samplers.h>
#include <algorithm>

namespace constraint_samplers
{
struct OrderSamplers
{
  bool operator()(const ConstraintSamplerPtr &a, const ConstraintSamplerPtr &b) const
  {
    const std::vector<std::string> &alinks = a->getJointModelGroup()->getUpdatedLinkModelNames();
    const std::vector<std::string> &blinks = b->getJointModelGroup()->getUpdatedLinkModelNames();
    std::set<std::string> a_updates(alinks.begin(), alinks.end());
    std::set<std::string> b_updates(blinks.begin(), blinks.end());

    bool a_contains_b = std::includes(a_updates.begin(), a_updates.end(), b_updates.begin(), b_updates.end());

    bool b_contains_a = std::includes(b_updates.begin(), b_updates.end(), a_updates.begin(), a_updates.end());

    // a contains b and sets are not equal
    if (a_contains_b && !b_contains_a)
      return true;
    if (b_contains_a && !a_contains_b)
      return false;

    // sets are equal or disjoint
    bool a_depends_on_b = false;
    bool b_depends_on_a = false;
    const std::vector<std::string> &fda = a->getFrameDependency();
    const std::vector<std::string> &fdb = b->getFrameDependency();
    for (std::size_t i = 0; i < fda.size() && !a_depends_on_b; ++i)
      for (std::size_t j = 0; j < blinks.size(); ++j)
        if (blinks[j] == fda[i])
        {
          a_depends_on_b = true;
          break;
        }
    for (std::size_t i = 0; i < fdb.size() && !b_depends_on_a; ++i)
      for (std::size_t j = 0; j < alinks.size(); ++j)
        if (alinks[j] == fdb[i])
        {
          b_depends_on_a = true;
          break;
        }
    if (b_depends_on_a && a_depends_on_b)
    {
      logWarn("Circular frame dependency! Sampling will likely produce invalid results (sampling for groups '%s' and "
              "'%s')",
              a->getJointModelGroup()->getName().c_str(), b->getJointModelGroup()->getName().c_str());
      return true;
    }
    if (b_depends_on_a && !a_depends_on_b)
      return true;
    if (a_depends_on_b && !b_depends_on_a)
      return false;

    // prefer sampling JointConstraints first
    JointConstraintSampler *ja = dynamic_cast<JointConstraintSampler *>(a.get());
    JointConstraintSampler *jb = dynamic_cast<JointConstraintSampler *>(b.get());
    if (ja && jb == NULL)
      return true;
    if (jb && ja == NULL)
      return false;

    // neither depends on either, so break ties based on group name
    return (a->getJointModelGroup()->getName() < b->getJointModelGroup()->getName());
  }
};
}

constraint_samplers::UnionConstraintSampler::UnionConstraintSampler(const planning_scene::PlanningSceneConstPtr &scene,
                                                                    const std::string &group_name,
                                                                    const std::vector<ConstraintSamplerPtr> &samplers)
  : ConstraintSampler(scene, group_name), samplers_(samplers)
{
  // using stable sort to preserve order of equivalents
  std::stable_sort(samplers_.begin(), samplers_.end(), OrderSamplers());

  for (std::size_t i = 0; i < samplers_.size(); ++i)
  {
    const std::vector<std::string> &fd = samplers_[i]->getFrameDependency();
    for (std::size_t j = 0; j < fd.size(); ++j)
      frame_depends_.push_back(fd[j]);

    logDebug("Union sampler for group '%s' includes sampler for group '%s'", jmg_->getName().c_str(),
             samplers_[i]->getJointModelGroup()->getName().c_str());
  }
}

bool constraint_samplers::UnionConstraintSampler::sample(robot_state::RobotState &state,
                                                         const robot_state::RobotState &reference_state,
                                                         unsigned int max_attempts)
{
  state = reference_state;
  state.setToRandomPositions(jmg_);

  if (samplers_.size() >= 1)
  {
    if (!samplers_[0]->sample(state, reference_state, max_attempts))
      return false;
  }

  for (std::size_t i = 1; i < samplers_.size(); ++i)
  {
    // ConstraintSampler::sample returns states with dirty link transforms (because it only writes values)
    // but requires a state with clean link transforms as input. This means that we need to clean the link
    // transforms between calls to ConstraintSampler::sample.
    state.updateLinkTransforms();
    if (!samplers_[i]->sample(state, state, max_attempts))
      return false;
  }
  return true;
}

bool constraint_samplers::UnionConstraintSampler::project(robot_state::RobotState &state, unsigned int max_attempts)
{
  for (std::size_t i = 0; i < samplers_.size(); ++i)
  {
    // ConstraintSampler::project returns states with dirty link transforms (because it only writes values)
    // but requires a state with clean link transforms as input. This means that we need to clean the link
    // transforms between calls to ConstraintSampler::sample.
    state.updateLinkTransforms();
    if (!samplers_[i]->project(state, max_attempts))
      return false;
  }
  return true;
}
<|endoftext|>


<commit_before>#include "orz/file_reader.h"
#include "orz/logger.h"
#include "registry.h"
#include "w32_assure_folder.h"
#include "reg_color_translator.h"
#include "reg_filter_mode_translator.h"
#include "reg_keyboard_binding_translator.h"
#include "reg_language_translator.h"
#include "reg_mouse_action_translator.h"
#include "reg_resize_behavior_translator.h"
#include "reg_resize_position_method_translator.h"
#include "reg_zoom_mode_translator.h"
#include <boost/algorithm/string.hpp>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/ini_parser.hpp>
#include <windows.h>

namespace Reg {
	Settings Load(const std::string& name) {
		Reg::Settings cfg;
		auto full_name = assure_folder(name);

		boost::property_tree::ptree pt;

		// Scope ensures that file is closed
		{
			IO::FileReader r(full_name);
			if (r.Open()) {
				auto sz = r.Size();
				std::string data;
				data.resize(sz);
				r.ReadFull(&data[0], sz);

				std::stringstream ss(data);

				try {
					boost::property_tree::ini_parser::read_ini(ss, pt);
				}
				catch (std::exception const& ex) {
					Log << "(Reg::Load) Failed parsing configuration file: " << ex.what() << "\n";
				}
			}
		}

		cfg.Cache.DoAutoMemoryLimit = pt.get<bool>("Settings.AutoMemoryLimit", true);
		cfg.Cache.ManualMemoryLimit = pt.get<size_t>("Settings.ManualMemoryLimit", 0);

		//cfg.Mouse.
		cfg.Mouse.OnMouseLeft = pt.get<App::MouseAction>("Settings.OnMouseLeft", App::MouseAction::MousePan);
		cfg.Mouse.OnMouseLeftDbl = pt.get<App::MouseAction>("Settings.OnMouseLeftDbl", App::MouseAction::MouseFullscreen);
		cfg.Mouse.OnMouseMiddle = pt.get<App::MouseAction>("Settings.OnMouseMioddle", App::MouseAction::MouseToggleFullSizeDefaultZoom);
		cfg.Mouse.OnMouseMiddleDbl = pt.get<App::MouseAction>("Settings.OnMouseMiddleDbl", App::MouseAction::MouseDisable);
		cfg.Mouse.OnMouseRight = pt.get<App::MouseAction>("Settings.OnMouseRight", App::MouseAction::MouseContext);
		cfg.Mouse.OnMouseRightDbl = pt.get<App::MouseAction>("Settings.OnMouseRightDbl", App::MouseAction::MouseDisable);
		cfg.Mouse.OnMouseWheelDown = pt.get<App::MouseAction>("Settings.OnMouseWheelDown", App::MouseAction::MouseNextImage);
		cfg.Mouse.OnMouseWheelUp = pt.get<App::MouseAction>("Settings.OnMouseWheelUp", App::MouseAction::MousePrevImage);
		cfg.Mouse.OnMouseExtra1 = pt.get<App::MouseAction>("Settings.OnMouseExtra1", App::MouseAction::MousePrevImage);
		cfg.Mouse.OnMouseExtra2 = pt.get<App::MouseAction>("Settings.OnMouseExtra2", App::MouseAction::MouseNextImage);
		cfg.Mouse.OnMouseExtra1Dbl = pt.get<App::MouseAction>("Settings.OnMouseExtra1Dbl", App::MouseAction::MouseUndefined);
		cfg.Mouse.OnMouseExtra2Dbl = pt.get<App::MouseAction>("Settings.OnMouseExtra2Dbl", App::MouseAction::MouseUndefined);

		cfg.Mouse.OnMouseRight = pt.get<App::MouseAction>("Settings.OnMouseRight", App::MouseAction::MouseContext);

		cfg.Render.BackgroundColor = pt.get<Img::Color>("Settings.BackgroundColor", { 0, 0xcc, 0xcc, 0xff });
		cfg.Render.MagFilter = pt.get<Filter::Mode>("Settings.MagFilter", Filter::Mode::Bilinear);
		cfg.Render.MinFilter = pt.get<Filter::Mode>("Settings.MinFilter", Filter::Mode::Bilinear);

		// cfg.View.
		cfg.View.AlwaysOnTop = pt.get<bool>("Settings.AlwaysOnTop", false);
		cfg.View.BrowseWrapAround = pt.get<bool>("Settings.BrowseWrapAround", false);
		cfg.View.DefaultZoomMode = pt.get<App::ZoomMode>("Settings.DefaultZoom", App::ZoomFitImage);
		cfg.View.Language = pt.get<Intl::Language>("Settings.Language", Intl::Language::English);
		cfg.View.Maximized = pt.get<bool>("Settings.Maximized", false);
		cfg.View.MultipleInstances = pt.get<bool>("Settings.MultipleInstances", false);
		cfg.View.ResetPan = pt.get<bool>("Settings.ResetPan", true);
		cfg.View.ResetZoom = pt.get<bool>("Settings.ResetZoom", true);
		cfg.View.ResizeBehaviour = pt.get<App::ResizeBehaviour>("Settings.ResizeBehaviour", App::ResizeBehaviour::ResizeReduceOnly);
		cfg.View.ResizePositionMethod = pt.get<App::ResizePositionMethod>("Settings.ResizePositionMethod", App::ResizePositionMethod::PositionNothing);
		cfg.View.ResizeWindow = pt.get<bool>("Settings.ResizeWindow", true);
		cfg.View.ShowStatusBar = pt.get<bool>("Settings.ShowStatusBar", true);
		cfg.View.WindowAnchorCenterX = pt.get("Settings.CAnchorX", 100);
		cfg.View.WindowAnchorCenterY = pt.get("Settings.CAnchorY", 100);
		cfg.View.WindowAnchorTLX = pt.get("Settings.TLAnchorX", 100);
		cfg.View.WindowAnchorTLY = pt.get("Settings.TLAnchorY", 100);
		cfg.View.WindowPosX = pt.get("Settings.PosX", 100);
		cfg.View.WindowPosY = pt.get("Settings.PosY", 100);
		cfg.View.WindowSizeWidth = pt.get("Settings.WindowWidth", 640);
		cfg.View.WindowSizeHeight = pt.get("Settings.WindowHeight", 480);

		// cfg.Keyboard.
		int index = 0;
		for (;;) {
			std::stringstream ss;
			ss << "Keyboard." << index++;
			auto inBinding = pt.get_optional<KeyboardBinding>(ss.str());
			if (!inBinding) break;

			cfg.Keyboard.Bindings.push_back(inBinding.get());
		}
		if (cfg.Keyboard.Bindings.empty()) {
			using App::KeyAction;
			cfg.Keyboard.Bindings = {
				// Alt, shift, control
				{ { VK_F2, false, false, false }, KeyAction::RenameFile },
				{ { VK_ESCAPE, false, false, false }, KeyAction::CloseApplication },
				{ { VK_OEM_PLUS, false, false, false }, KeyAction::ZoomIn },
				{ { VK_ADD, false, false, false }, KeyAction::ZoomIn },
				{ { VK_NUMPAD0, false, false, false }, KeyAction::ZoomIn },

				{ { VK_OEM_MINUS, false, false, false }, KeyAction::ZoomOut },
				{ { VK_SUBTRACT, false, false, false }, KeyAction::ZoomOut },
				{ { VK_NUMPAD1, false, false, false }, KeyAction::ZoomOut },

				{ { L'0', false, false, false }, KeyAction::ZoomDefault },
				{ { L'1', false, false, false }, KeyAction::ZoomFull },
				{ { VK_MULTIPLY, false, false, false }, KeyAction::ZoomFree },

				{ { VK_UP, false, false, false }, KeyAction::PanUp },
				{ { VK_DOWN, false, false, false }, KeyAction::PanDown },
				{ { VK_LEFT, false, false, false }, KeyAction::PanLeft },
				{ { VK_RIGHT, false, false, false }, KeyAction::PanRight },

				{ { VK_HOME, false, false, false }, KeyAction::FirstImage },
				{ { VK_END, false, false, false }, KeyAction::LastImage },

				{ { VK_SPACE, false, false, false }, KeyAction::NextImage },
				{ { VK_NEXT, false, false, false }, KeyAction::NextImage },

				{ { VK_SPACE, false, true, false }, KeyAction::NextSkipImage },
				{ { VK_NEXT, false, true, false }, KeyAction::NextSkipImage },
				{ { VK_RIGHT, true, false, false }, KeyAction::NextSkipImage },

				{ { VK_BACK, false, false, false }, KeyAction::PreviousImage },
				{ { VK_PRIOR, false, false, false }, KeyAction::PreviousImage },

				{ { VK_BACK, false, true, false }, KeyAction::PreviousSkipImage },
				{ { VK_PRIOR, false, true, false }, KeyAction::PreviousSkipImage },
				{ { VK_LEFT, true, false, false }, KeyAction::PreviousSkipImage },

				{ { VK_DELETE, false, false, false }, KeyAction::RecycleCurrentFile },
				{ { VK_DELETE, false, true, false }, KeyAction::DeleteCurrentFile },
				{ { VK_DELETE, false, false, true }, KeyAction::RemoveCurrentImage },

				{ { L'R', false, false, false }, KeyAction::RandomImage },
				{ { L'O', false, false, false }, KeyAction::OpenSettings },
				{ { VK_RETURN, true, false, false }, KeyAction::ToggleFullscreen },
				{ { L'C', false, false, true}, KeyAction::CopyImage }
			};
		}

		return cfg;
	}

	void Save(const std::string& name, const Settings& settings) {
		auto full_name = assure_folder(name);
		std::stringstream ss;
		//ss << (char)0xef << (char)0xbb << (char)(0xbf);
		boost::property_tree::ptree pt;

		pt.put("Settings.AutoMemoryLimit", settings.Cache.DoAutoMemoryLimit);
		pt.put("Settings.ManualMemoryLimit", settings.Cache.ManualMemoryLimit);

		//cfg.Mouse.
		pt.put("Settings.OnMouseLeft", settings.Mouse.OnMouseLeft);
		pt.put("Settings.OnMouseLeftDbl", settings.Mouse.OnMouseLeftDbl);
		pt.put("Settings.OnMouseMioddle", settings.Mouse.OnMouseMiddle);
		pt.put("Settings.OnMouseMiddleDbl", settings.Mouse.OnMouseMiddleDbl);
		pt.put("Settings.OnMouseRight", settings.Mouse.OnMouseRight);
		pt.put("Settings.OnMouseRightDbl", settings.Mouse.OnMouseRightDbl);
		pt.put("Settings.OnMouseWheelDown", settings.Mouse.OnMouseWheelDown);
		pt.put("Settings.OnMouseWheelUp", settings.Mouse.OnMouseWheelUp);
		pt.put("Settings.OnMouseExtra1", settings.Mouse.OnMouseExtra1);
		pt.put("Settings.OnMouseExtra2", settings.Mouse.OnMouseExtra2);
		pt.put("Settings.OnMouseExtra1Dbl", settings.Mouse.OnMouseExtra1Dbl);
		pt.put("Settings.OnMouseExtra2Dbl", settings.Mouse.OnMouseExtra2Dbl);

		pt.put("Settings.BackgroundColor", settings.Render.BackgroundColor);
		pt.put("Settings.MagFilter", settings.Render.MagFilter);
		pt.put("Settings.MinFilter", settings.Render.MinFilter);

		// cfg.View.
		pt.put("Settings.AlwaysOnTop", settings.View.AlwaysOnTop);
		pt.put("Settings.BrowseWrapAround", settings.View.BrowseWrapAround);
		pt.put("Settings.DefaultZoom", settings.View.DefaultZoomMode);
		pt.put("Settings.Language", settings.View.Language);
		pt.put("Settings.Maximized", settings.View.Maximized);
		pt.put("Settings.MultipleInstances", settings.View.MultipleInstances);
		pt.put("Settings.ResetPan", settings.View.ResetPan);
		pt.put("Settings.ResetZoom", settings.View.ResetZoom);
		pt.put("Settings.ResizeBehaviour", settings.View.ResizeBehaviour);
		pt.put("Settings.ResizePositionMethod", settings.View.ResizePositionMethod);
		pt.put("Settings.ResizeWindow", settings.View.ResizeWindow);
		pt.put("Settings.ShowStatusBar", settings.View.ShowStatusBar);
		pt.put("Settings.CAnchorX", settings.View.WindowAnchorCenterX);
		pt.put("Settings.CAnchorY", settings.View.WindowAnchorCenterY);
		pt.put("Settings.TLAnchorX", settings.View.WindowAnchorTLX);
		pt.put("Settings.TLAnchorY", settings.View.WindowAnchorTLY);
		pt.put("Settings.PosX", settings.View.WindowPosX);
		pt.put("Settings.PosY", settings.View.WindowPosY);
		pt.put("Settings.WindowWidth", settings.View.WindowSizeWidth);
		pt.put("Settings.WindowHeight", settings.View.WindowSizeHeight);

		int index = 0;
		for (auto binding : settings.Keyboard.Bindings) {
			std::stringstream ss;
			ss << "Keyboard." << index++;
			pt.put(ss.str(), binding);
		}

		boost::property_tree::ini_parser::write_ini(ss, pt);
		IO::FileWriter wrt;
		if (wrt.Open(full_name)) {
			auto str = ss.str();

			// Although technically valid, the implementation of write_ini doesn't produce good old \r\n linefeeds that
			// notepad and other shoddy programs expect. Therefore we'll convert the linefeeds to that format.
			boost::replace_all(str, "\n", "\r\n");
			wrt.Write(str.c_str(), sizeof(char), str.size());
		}
	}
}
<commit_msg>Use MouseDisable rather than MouseUndefined for no action<commit_after>#include "orz/file_reader.h"
#include "orz/logger.h"
#include "registry.h"
#include "w32_assure_folder.h"
#include "reg_color_translator.h"
#include "reg_filter_mode_translator.h"
#include "reg_keyboard_binding_translator.h"
#include "reg_language_translator.h"
#include "reg_mouse_action_translator.h"
#include "reg_resize_behavior_translator.h"
#include "reg_resize_position_method_translator.h"
#include "reg_zoom_mode_translator.h"
#include <boost/algorithm/string.hpp>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/ini_parser.hpp>
#include <windows.h>

namespace Reg {
	Settings Load(const std::string& name) {
		Reg::Settings cfg;
		auto full_name = assure_folder(name);

		boost::property_tree::ptree pt;

		// Scope ensures that file is closed
		{
			IO::FileReader r(full_name);
			if (r.Open()) {
				auto sz = r.Size();
				std::string data;
				data.resize(sz);
				r.ReadFull(&data[0], sz);

				std::stringstream ss(data);

				try {
					boost::property_tree::ini_parser::read_ini(ss, pt);
				}
				catch (std::exception const& ex) {
					Log << "(Reg::Load) Failed parsing configuration file: " << ex.what() << "\n";
				}
			}
		}

		cfg.Cache.DoAutoMemoryLimit = pt.get<bool>("Settings.AutoMemoryLimit", true);
		cfg.Cache.ManualMemoryLimit = pt.get<size_t>("Settings.ManualMemoryLimit", 0);

		//cfg.Mouse.
		cfg.Mouse.OnMouseLeft = pt.get<App::MouseAction>("Settings.OnMouseLeft", App::MouseAction::MousePan);
		cfg.Mouse.OnMouseLeftDbl = pt.get<App::MouseAction>("Settings.OnMouseLeftDbl", App::MouseAction::MouseFullscreen);
		cfg.Mouse.OnMouseMiddle = pt.get<App::MouseAction>("Settings.OnMouseMioddle", App::MouseAction::MouseToggleFullSizeDefaultZoom);
		cfg.Mouse.OnMouseMiddleDbl = pt.get<App::MouseAction>("Settings.OnMouseMiddleDbl", App::MouseAction::MouseDisable);
		cfg.Mouse.OnMouseRight = pt.get<App::MouseAction>("Settings.OnMouseRight", App::MouseAction::MouseContext);
		cfg.Mouse.OnMouseRightDbl = pt.get<App::MouseAction>("Settings.OnMouseRightDbl", App::MouseAction::MouseDisable);
		cfg.Mouse.OnMouseWheelDown = pt.get<App::MouseAction>("Settings.OnMouseWheelDown", App::MouseAction::MouseNextImage);
		cfg.Mouse.OnMouseWheelUp = pt.get<App::MouseAction>("Settings.OnMouseWheelUp", App::MouseAction::MousePrevImage);
		cfg.Mouse.OnMouseExtra1 = pt.get<App::MouseAction>("Settings.OnMouseExtra1", App::MouseAction::MousePrevImage);
		cfg.Mouse.OnMouseExtra2 = pt.get<App::MouseAction>("Settings.OnMouseExtra2", App::MouseAction::MouseNextImage);
		cfg.Mouse.OnMouseExtra1Dbl = pt.get<App::MouseAction>("Settings.OnMouseExtra1Dbl", App::MouseAction::MouseDisable);
		cfg.Mouse.OnMouseExtra2Dbl = pt.get<App::MouseAction>("Settings.OnMouseExtra2Dbl", App::MouseAction::MouseDisable);

		cfg.Mouse.OnMouseRight = pt.get<App::MouseAction>("Settings.OnMouseRight", App::MouseAction::MouseContext);

		cfg.Render.BackgroundColor = pt.get<Img::Color>("Settings.BackgroundColor", { 0, 0xcc, 0xcc, 0xff });
		cfg.Render.MagFilter = pt.get<Filter::Mode>("Settings.MagFilter", Filter::Mode::Bilinear);
		cfg.Render.MinFilter = pt.get<Filter::Mode>("Settings.MinFilter", Filter::Mode::Bilinear);

		// cfg.View.
		cfg.View.AlwaysOnTop = pt.get<bool>("Settings.AlwaysOnTop", false);
		cfg.View.BrowseWrapAround = pt.get<bool>("Settings.BrowseWrapAround", false);
		cfg.View.DefaultZoomMode = pt.get<App::ZoomMode>("Settings.DefaultZoom", App::ZoomFitImage);
		cfg.View.Language = pt.get<Intl::Language>("Settings.Language", Intl::Language::English);
		cfg.View.Maximized = pt.get<bool>("Settings.Maximized", false);
		cfg.View.MultipleInstances = pt.get<bool>("Settings.MultipleInstances", false);
		cfg.View.ResetPan = pt.get<bool>("Settings.ResetPan", true);
		cfg.View.ResetZoom = pt.get<bool>("Settings.ResetZoom", true);
		cfg.View.ResizeBehaviour = pt.get<App::ResizeBehaviour>("Settings.ResizeBehaviour", App::ResizeBehaviour::ResizeReduceOnly);
		cfg.View.ResizePositionMethod = pt.get<App::ResizePositionMethod>("Settings.ResizePositionMethod", App::ResizePositionMethod::PositionNothing);
		cfg.View.ResizeWindow = pt.get<bool>("Settings.ResizeWindow", true);
		cfg.View.ShowStatusBar = pt.get<bool>("Settings.ShowStatusBar", true);
		cfg.View.WindowAnchorCenterX = pt.get("Settings.CAnchorX", 100);
		cfg.View.WindowAnchorCenterY = pt.get("Settings.CAnchorY", 100);
		cfg.View.WindowAnchorTLX = pt.get("Settings.TLAnchorX", 100);
		cfg.View.WindowAnchorTLY = pt.get("Settings.TLAnchorY", 100);
		cfg.View.WindowPosX = pt.get("Settings.PosX", 100);
		cfg.View.WindowPosY = pt.get("Settings.PosY", 100);
		cfg.View.WindowSizeWidth = pt.get("Settings.WindowWidth", 640);
		cfg.View.WindowSizeHeight = pt.get("Settings.WindowHeight", 480);

		// cfg.Keyboard.
		int index = 0;
		for (;;) {
			std::stringstream ss;
			ss << "Keyboard." << index++;
			auto inBinding = pt.get_optional<KeyboardBinding>(ss.str());
			if (!inBinding) break;

			cfg.Keyboard.Bindings.push_back(inBinding.get());
		}
		if (cfg.Keyboard.Bindings.empty()) {
			using App::KeyAction;
			cfg.Keyboard.Bindings = {
				// Alt, shift, control
				{ { VK_F2, false, false, false }, KeyAction::RenameFile },
				{ { VK_ESCAPE, false, false, false }, KeyAction::CloseApplication },
				{ { VK_OEM_PLUS, false, false, false }, KeyAction::ZoomIn },
				{ { VK_ADD, false, false, false }, KeyAction::ZoomIn },
				{ { VK_NUMPAD0, false, false, false }, KeyAction::ZoomIn },

				{ { VK_OEM_MINUS, false, false, false }, KeyAction::ZoomOut },
				{ { VK_SUBTRACT, false, false, false }, KeyAction::ZoomOut },
				{ { VK_NUMPAD1, false, false, false }, KeyAction::ZoomOut },

				{ { L'0', false, false, false }, KeyAction::ZoomDefault },
				{ { L'1', false, false, false }, KeyAction::ZoomFull },
				{ { VK_MULTIPLY, false, false, false }, KeyAction::ZoomFree },

				{ { VK_UP, false, false, false }, KeyAction::PanUp },
				{ { VK_DOWN, false, false, false }, KeyAction::PanDown },
				{ { VK_LEFT, false, false, false }, KeyAction::PanLeft },
				{ { VK_RIGHT, false, false, false }, KeyAction::PanRight },

				{ { VK_HOME, false, false, false }, KeyAction::FirstImage },
				{ { VK_END, false, false, false }, KeyAction::LastImage },

				{ { VK_SPACE, false, false, false }, KeyAction::NextImage },
				{ { VK_NEXT, false, false, false }, KeyAction::NextImage },

				{ { VK_SPACE, false, true, false }, KeyAction::NextSkipImage },
				{ { VK_NEXT, false, true, false }, KeyAction::NextSkipImage },
				{ { VK_RIGHT, true, false, false }, KeyAction::NextSkipImage },

				{ { VK_BACK, false, false, false }, KeyAction::PreviousImage },
				{ { VK_PRIOR, false, false, false }, KeyAction::PreviousImage },

				{ { VK_BACK, false, true, false }, KeyAction::PreviousSkipImage },
				{ { VK_PRIOR, false, true, false }, KeyAction::PreviousSkipImage },
				{ { VK_LEFT, true, false, false }, KeyAction::PreviousSkipImage },

				{ { VK_DELETE, false, false, false }, KeyAction::RecycleCurrentFile },
				{ { VK_DELETE, false, true, false }, KeyAction::DeleteCurrentFile },
				{ { VK_DELETE, false, false, true }, KeyAction::RemoveCurrentImage },

				{ { L'R', false, false, false }, KeyAction::RandomImage },
				{ { L'O', false, false, false }, KeyAction::OpenSettings },
				{ { VK_RETURN, true, false, false }, KeyAction::ToggleFullscreen },
				{ { L'C', false, false, true}, KeyAction::CopyImage }
			};
		}

		return cfg;
	}

	void Save(const std::string& name, const Settings& settings) {
		auto full_name = assure_folder(name);
		std::stringstream ss;
		//ss << (char)0xef << (char)0xbb << (char)(0xbf);
		boost::property_tree::ptree pt;

		pt.put("Settings.AutoMemoryLimit", settings.Cache.DoAutoMemoryLimit);
		pt.put("Settings.ManualMemoryLimit", settings.Cache.ManualMemoryLimit);

		//cfg.Mouse.
		pt.put("Settings.OnMouseLeft", settings.Mouse.OnMouseLeft);
		pt.put("Settings.OnMouseLeftDbl", settings.Mouse.OnMouseLeftDbl);
		pt.put("Settings.OnMouseMioddle", settings.Mouse.OnMouseMiddle);
		pt.put("Settings.OnMouseMiddleDbl", settings.Mouse.OnMouseMiddleDbl);
		pt.put("Settings.OnMouseRight", settings.Mouse.OnMouseRight);
		pt.put("Settings.OnMouseRightDbl", settings.Mouse.OnMouseRightDbl);
		pt.put("Settings.OnMouseWheelDown", settings.Mouse.OnMouseWheelDown);
		pt.put("Settings.OnMouseWheelUp", settings.Mouse.OnMouseWheelUp);
		pt.put("Settings.OnMouseExtra1", settings.Mouse.OnMouseExtra1);
		pt.put("Settings.OnMouseExtra2", settings.Mouse.OnMouseExtra2);
		pt.put("Settings.OnMouseExtra1Dbl", settings.Mouse.OnMouseExtra1Dbl);
		pt.put("Settings.OnMouseExtra2Dbl", settings.Mouse.OnMouseExtra2Dbl);

		pt.put("Settings.BackgroundColor", settings.Render.BackgroundColor);
		pt.put("Settings.MagFilter", settings.Render.MagFilter);
		pt.put("Settings.MinFilter", settings.Render.MinFilter);

		// cfg.View.
		pt.put("Settings.AlwaysOnTop", settings.View.AlwaysOnTop);
		pt.put("Settings.BrowseWrapAround", settings.View.BrowseWrapAround);
		pt.put("Settings.DefaultZoom", settings.View.DefaultZoomMode);
		pt.put("Settings.Language", settings.View.Language);
		pt.put("Settings.Maximized", settings.View.Maximized);
		pt.put("Settings.MultipleInstances", settings.View.MultipleInstances);
		pt.put("Settings.ResetPan", settings.View.ResetPan);
		pt.put("Settings.ResetZoom", settings.View.ResetZoom);
		pt.put("Settings.ResizeBehaviour", settings.View.ResizeBehaviour);
		pt.put("Settings.ResizePositionMethod", settings.View.ResizePositionMethod);
		pt.put("Settings.ResizeWindow", settings.View.ResizeWindow);
		pt.put("Settings.ShowStatusBar", settings.View.ShowStatusBar);
		pt.put("Settings.CAnchorX", settings.View.WindowAnchorCenterX);
		pt.put("Settings.CAnchorY", settings.View.WindowAnchorCenterY);
		pt.put("Settings.TLAnchorX", settings.View.WindowAnchorTLX);
		pt.put("Settings.TLAnchorY", settings.View.WindowAnchorTLY);
		pt.put("Settings.PosX", settings.View.WindowPosX);
		pt.put("Settings.PosY", settings.View.WindowPosY);
		pt.put("Settings.WindowWidth", settings.View.WindowSizeWidth);
		pt.put("Settings.WindowHeight", settings.View.WindowSizeHeight);

		int index = 0;
		for (auto binding : settings.Keyboard.Bindings) {
			std::stringstream ss;
			ss << "Keyboard." << index++;
			pt.put(ss.str(), binding);
		}

		boost::property_tree::ini_parser::write_ini(ss, pt);
		IO::FileWriter wrt;
		if (wrt.Open(full_name)) {
			auto str = ss.str();

			// Although technically valid, the implementation of write_ini doesn't produce good old \r\n linefeeds that
			// notepad and other shoddy programs expect. Therefore we'll convert the linefeeds to that format.
			boost::replace_all(str, "\n", "\r\n");
			wrt.Write(str.c_str(), sizeof(char), str.size());
		}
	}
}
<|endoftext|>


<commit_before>// $Id: DCDFile_test.C,v 1.4 2001/05/06 21:38:55 oliver Exp $
#include <BALL/CONCEPT/classTest.h>

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

// insert includes here
#include <BALL/FORMAT/DCDFile.h>

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

START_TEST(class_name, "$Id: DCDFile_test.C,v 1.4 2001/05/06 21:38:55 oliver Exp $")

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

using namespace BALL;

///  insert tests for each member function here

String dcd_test_file("data/DCD_test.dcd");

CHECK(DCDFile::DCDHeader::DCDHeader() throw())
  DCDFile::DCDHeader* p = new DCDFile::DCDHeader;
	TEST_NOT_EQUAL(p, 0)
RESULT

DCDFile* p = new DCDFile;

CHECK(DCDFile::DCDFile() throw())
  p = new DCDFile;
	TEST_NOT_EQUAL(p, 0)
RESULT

CHECK(DCDFile::~DCDFile() throw())
	delete p;
RESULT

CHECK(DCDFile::DCDFile(const DCDFile& file) throw())
  DCDFile first_file(dcd_test_file);
	DCDFile second_file(first_file);
	bool test = (first_file == second_file);
	TEST_EQUAL(test, true)
RESULT

CHECK(DCDFile::DCDFile(const String& name, File::OpenMode open_mode) throw())
  //BAUSTELLE
  DCDFile test_file(dcd_test_file, File::IN);
	TEST_EQUAL(test_file.isOpen(), true)
	TEST_EQUAL(test_file.getOpenMode(), File::IN)
	test_file.close();
	TEST_EQUAL(test_file.isOpen(), false)

	DCDFile test_file2("test.out.dcd", File::OUT);
	TEST_EQUAL(test_file2.isOpen(), true)
	TEST_EQUAL(test_file2.getOpenMode(), File::OUT)
	test_file2.close();
	TEST_EQUAL(test_file2.isOpen(), false)
RESULT

CHECK(DCDFile::DCDFile& operator = (const DCDFile& file) throw())
  DCDFile one(dcd_test_file, File::IN);
	DCDFile two;
	two = one;
	bool test = (one == two);
	TEST_EQUAL(test, true)
RESULT

CHECK(DCDFile::clear() throw())
	DCDFile file(dcd_test_file, File::IN);
	file.clear();
	DCDFile empty;
	bool test = (file == empty);
	TEST_EQUAL(test, true)
RESULT

CHECK(DCDFile::bool operator == (const DCDFile& file) throw())
  DCDFile one(dcd_test_file, File::IN);
  DCDFile two(dcd_test_file, File::IN);
	bool test = (one == two);
	TEST_EQUAL(test, true)
	DCDFile three;
	test = (one == three);
	TEST_EQUAL(test, false)
RESULT

// init() is called every time an object is constructed, so we won't have a
// dedicated test here. There is no reasonabel way to test it, anyway.

CHECK(DCDFile::readHeader() throw())
  DCDFile one(dcd_test_file, File::IN);
	bool test = one.readHeader();
	TEST_EQUAL(test, true)
	one.close();
	DCDFile two("data/INIFile_test.ini", File::IN);
	test = two.readHeader();
	TEST_EQUAL(test, false)
RESULT

CHECK(DCDFile::writeHeader() throw())
	// BAUSTELLE:
	// Oh, how did this temporary file thing work again?
	// DCDFile one(temporary, File::OUT);
	// one.writeHeader();
	// one.close();
	// DCDFile two(temporary, File::IN);
	// bool test = two.readHeader();
	// TEST_EQUAL(test, true);
RESULT

CHECK(DCDFile::append(const SnapShot& snapshot) throw())
  // BAUSTELLE
	// SnapShot snap;
	// DCDFile one(temporary, File::out);
	// one.append(snap);
	// one.close();
	// DCDFile two(temporary, File::IN);
	// SnapShot snap2;
	// two.readHeader();
	// two.read(snap2);
	// bool test = (snap == snap2);
	// TEST_EQUAL(test, true);
RESULT

CHECK(DCDFile::read(SnapShot& snapshot) throw())
  //BAUSTELLE
RESULT

CHECK(DCDFile::flushToDisk(const ::std::vector<SnapShot> buffer) throw())
  //BAUSTELLE
RESULT

/////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////
END_TEST
<commit_msg>fixed: readHeader() cannot return true on a new file<commit_after>// $Id: DCDFile_test.C,v 1.5 2001/05/15 09:40:41 anker Exp $
#include <BALL/CONCEPT/classTest.h>

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

// insert includes here
#include <BALL/FORMAT/DCDFile.h>

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

START_TEST(class_name, "$Id: DCDFile_test.C,v 1.5 2001/05/15 09:40:41 anker Exp $")

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

using namespace BALL;

///  insert tests for each member function here

String dcd_test_file("data/DCD_test.dcd");

CHECK(DCDFile::DCDHeader::DCDHeader() throw())
  DCDFile::DCDHeader* p = new DCDFile::DCDHeader;
	TEST_NOT_EQUAL(p, 0)
RESULT

DCDFile* p = new DCDFile;

CHECK(DCDFile::DCDFile() throw())
  p = new DCDFile;
	TEST_NOT_EQUAL(p, 0)
RESULT

CHECK(DCDFile::~DCDFile() throw())
	delete p;
RESULT

CHECK(DCDFile::DCDFile(const DCDFile& file) throw())
  DCDFile first_file(dcd_test_file);
	DCDFile second_file(first_file);
	bool test = (first_file == second_file);
	TEST_EQUAL(test, true)
RESULT

CHECK(DCDFile::DCDFile(const String& name, File::OpenMode open_mode) throw())
  //BAUSTELLE
  DCDFile test_file(dcd_test_file, File::IN);
	TEST_EQUAL(test_file.isOpen(), true)
	TEST_EQUAL(test_file.getOpenMode(), File::IN)
	test_file.close();
	TEST_EQUAL(test_file.isOpen(), false)

	DCDFile test_file2("test.out.dcd", File::OUT);
	TEST_EQUAL(test_file2.isOpen(), true)
	TEST_EQUAL(test_file2.getOpenMode(), File::OUT)
	test_file2.close();
	TEST_EQUAL(test_file2.isOpen(), false)
RESULT

CHECK(DCDFile::DCDFile& operator = (const DCDFile& file) throw())
  DCDFile one(dcd_test_file, File::IN);
	DCDFile two;
	two = one;
	bool test = (one == two);
	TEST_EQUAL(test, true)
RESULT

CHECK(DCDFile::clear() throw())
	DCDFile file(dcd_test_file, File::IN);
	file.clear();
	DCDFile empty;
	bool test = (file == empty);
	TEST_EQUAL(test, true)
RESULT

CHECK(DCDFile::bool operator == (const DCDFile& file) throw())
  DCDFile one(dcd_test_file, File::IN);
  DCDFile two(dcd_test_file, File::IN);
	bool test = (one == two);
	TEST_EQUAL(test, true)
	DCDFile three;
	test = (one == three);
	TEST_EQUAL(test, false)
RESULT

// init() is called every time an object is constructed, so we won't have a
// dedicated test here. There is no reasonable way to test it, anyway.

CHECK(DCDFile::readHeader() throw())
  DCDFile one(dcd_test_file, File::IN);
	bool test = one.readHeader();
	TEST_EQUAL(test, false)
	one.close();
	DCDFile two("data/INIFile_test.ini", File::IN);
	test = two.readHeader();
	TEST_EQUAL(test, false)
RESULT

CHECK(DCDFile::writeHeader() throw())
	// BAUSTELLE:
	// Oh, how did this temporary file thing work again?
	// DCDFile one(temporary, File::OUT);
	// one.writeHeader();
	// one.close();
	// DCDFile two(temporary, File::IN);
	// bool test = two.readHeader();
	// TEST_EQUAL(test, true);
RESULT

CHECK(DCDFile::append(const SnapShot& snapshot) throw())
  // BAUSTELLE
	// SnapShot snap;
	// DCDFile one(temporary, File::out);
	// one.append(snap);
	// one.close();
	// DCDFile two(temporary, File::IN);
	// SnapShot snap2;
	// two.readHeader();
	// two.read(snap2);
	// bool test = (snap == snap2);
	// TEST_EQUAL(test, true);
RESULT

CHECK(DCDFile::read(SnapShot& snapshot) throw())
  //BAUSTELLE
RESULT

CHECK(DCDFile::flushToDisk(const ::std::vector<SnapShot> buffer) throw())
  //BAUSTELLE
RESULT

/////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////
END_TEST
<|endoftext|>


<commit_before>#ifndef window_hh_INCLUDED
#define window_hh_INCLUDED

#include <functional>

#include "line_and_column.hh"

#include "buffer.hh"
#include "display_buffer.hh"

namespace Kakoune
{

struct WindowCoord : LineAndColumn<WindowCoord>
{
    WindowCoord(int line = 0, int column = 0)
        : LineAndColumn(line, column) {}
};

struct Selection
{
    Selection(const BufferIterator& begin, const BufferIterator& end)
        : m_begin(begin), m_end(end) {}

    const BufferIterator& begin() const { return m_begin; }
    const BufferIterator& end() const   { return m_end; }

    void canonicalize()
    {
        if (m_end < m_begin)
            std::swap(m_begin, m_end);
    }

    void offset(int offset)
    {
        m_begin += offset;
        m_end += offset;
    }

private:
    BufferIterator m_begin;
    BufferIterator m_end;
};

typedef std::vector<Selection> SelectionList;

class IncrementalInserter;

class Window
{
public:
    typedef BufferString String;
    typedef std::function<Selection (const BufferIterator&)> Selector;

    void erase();
    void insert(const String& string);
    void append(const String& string);

    const BufferCoord& position() const { return m_position; }
    const WindowCoord& cursor_position() const { return m_cursor; }

    Buffer& buffer() const { return m_buffer; }

    BufferCoord window_to_buffer(const WindowCoord& window_pos) const;
    WindowCoord buffer_to_window(const BufferCoord& buffer_pos) const;

    BufferIterator iterator_at(const WindowCoord& window_pos) const;
    WindowCoord    line_and_column_at(const BufferIterator& iterator) const;

    void move_cursor(const WindowCoord& offset);

    void empty_selections();
    void select(bool append, const Selector& selector);

    void set_dimensions(const WindowCoord& dimensions);

    const DisplayBuffer& display_buffer() const { return m_display_buffer; }

    void update_display_buffer();

    bool undo();
    bool redo();

private:
    friend class Buffer;

    Window(Buffer& buffer);
    Window(const Window&) = delete;

    void scroll_to_keep_cursor_visible_ifn();

    friend class IncrementalInserter;
    IncrementalInserter* m_current_inserter;

    Buffer&       m_buffer;
    BufferCoord   m_position;
    WindowCoord   m_cursor;
    WindowCoord   m_dimensions;
    SelectionList m_selections;
    DisplayBuffer m_display_buffer;
};

class IncrementalInserter
{
public:
    typedef std::vector<WindowCoord> CursorList;

    IncrementalInserter(Window& window, bool append = false);
    ~IncrementalInserter();

    void insert(const Window::String& string);
    void erase();
    void move_cursor(const WindowCoord& offset);

    const CursorList& cursors() const { return m_cursors; }

private:
    Window&                     m_window;
    std::vector<WindowCoord>    m_cursors;
};

}

#endif // window_hh_INCLUDED
<commit_msg>Selection: fix canonicalize<commit_after>#ifndef window_hh_INCLUDED
#define window_hh_INCLUDED

#include <functional>

#include "line_and_column.hh"

#include "buffer.hh"
#include "display_buffer.hh"

namespace Kakoune
{

struct WindowCoord : LineAndColumn<WindowCoord>
{
    WindowCoord(int line = 0, int column = 0)
        : LineAndColumn(line, column) {}
};

struct Selection
{
    Selection(const BufferIterator& begin, const BufferIterator& end)
        : m_begin(begin), m_end(end) {}

    const BufferIterator& begin() const { return m_begin; }
    const BufferIterator& end() const   { return m_end; }

    void canonicalize()
    {
        if (m_end < m_begin)
            std::swap(++m_begin, ++m_end);
    }

    void offset(int offset)
    {
        m_begin += offset;
        m_end += offset;
    }

private:
    BufferIterator m_begin;
    BufferIterator m_end;
};

typedef std::vector<Selection> SelectionList;

class IncrementalInserter;

class Window
{
public:
    typedef BufferString String;
    typedef std::function<Selection (const BufferIterator&)> Selector;

    void erase();
    void insert(const String& string);
    void append(const String& string);

    const BufferCoord& position() const { return m_position; }
    const WindowCoord& cursor_position() const { return m_cursor; }

    Buffer& buffer() const { return m_buffer; }

    BufferCoord window_to_buffer(const WindowCoord& window_pos) const;
    WindowCoord buffer_to_window(const BufferCoord& buffer_pos) const;

    BufferIterator iterator_at(const WindowCoord& window_pos) const;
    WindowCoord    line_and_column_at(const BufferIterator& iterator) const;

    void move_cursor(const WindowCoord& offset);

    void empty_selections();
    void select(bool append, const Selector& selector);

    void set_dimensions(const WindowCoord& dimensions);

    const DisplayBuffer& display_buffer() const { return m_display_buffer; }

    void update_display_buffer();

    bool undo();
    bool redo();

private:
    friend class Buffer;

    Window(Buffer& buffer);
    Window(const Window&) = delete;

    void scroll_to_keep_cursor_visible_ifn();

    friend class IncrementalInserter;
    IncrementalInserter* m_current_inserter;

    Buffer&       m_buffer;
    BufferCoord   m_position;
    WindowCoord   m_cursor;
    WindowCoord   m_dimensions;
    SelectionList m_selections;
    DisplayBuffer m_display_buffer;
};

class IncrementalInserter
{
public:
    typedef std::vector<WindowCoord> CursorList;

    IncrementalInserter(Window& window, bool append = false);
    ~IncrementalInserter();

    void insert(const Window::String& string);
    void erase();
    void move_cursor(const WindowCoord& offset);

    const CursorList& cursors() const { return m_cursors; }

private:
    Window&                     m_window;
    std::vector<WindowCoord>    m_cursors;
};

}

#endif // window_hh_INCLUDED
<|endoftext|>


<commit_before>// Copyright (c) 2021 The Orbit Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <absl/base/casts.h>
#include <absl/strings/match.h>
#include <absl/strings/str_format.h>
#include <dlfcn.h>
#include <gtest/gtest.h>
#include <sys/wait.h>

#include <chrono>
#include <csignal>
#include <string>
#include <thread>

#include "AllocateInTracee.h"
#include "ExecuteMachineCode.h"
#include "GetTestLibLibraryPath.h"
#include "MachineCode.h"
#include "OrbitBase/ExecutablePath.h"
#include "OrbitBase/Logging.h"
#include "OrbitBase/ReadFileToString.h"
#include "OrbitBase/Result.h"
#include "TestUtils/TestUtils.h"
#include "UserSpaceInstrumentation/Attach.h"
#include "UserSpaceInstrumentation/InjectLibraryInTracee.h"

namespace orbit_user_space_instrumentation {

namespace {

using orbit_test_utils::HasError;
using orbit_test_utils::HasNoError;

void OpenUseAndCloseLibrary(pid_t pid) {
  // Stop the child process using our tooling.
  CHECK(!AttachAndStopProcess(pid).has_error());

  auto library_path_or_error = GetTestLibLibraryPath();
  ASSERT_THAT(library_path_or_error, HasNoError());
  std::filesystem::path library_path = std::move(library_path_or_error.value());

  // Tracee does not have the dynamic lib loaded, obviously.
  auto maps_before = orbit_base::ReadFileToString(absl::StrFormat("/proc/%d/maps", pid));
  CHECK(maps_before.has_value());
  EXPECT_FALSE(absl::StrContains(maps_before.value(), library_path.filename().string()));

  auto library_handle_or_error = DlopenInTracee(pid, library_path, RTLD_NOW);
  ASSERT_TRUE(library_handle_or_error.has_value());

  // Tracee now does have the dynamic lib loaded.
  auto maps_after_open = orbit_base::ReadFileToString(absl::StrFormat("/proc/%d/maps", pid));
  CHECK(maps_after_open.has_value());
  EXPECT_TRUE(absl::StrContains(maps_after_open.value(), library_path.filename().string()));

  // Look up symbol for "TrivialFunction" in the dynamic lib.
  auto dlsym_or_error = DlsymInTracee(pid, library_handle_or_error.value(), "TrivialFunction");
  ASSERT_TRUE(dlsym_or_error.has_value());
  const uint64_t function_address = absl::bit_cast<uint64_t>(dlsym_or_error.value());

  {
    // Write machine code to call "TrivialFunction" from the dynamic lib.
    constexpr uint64_t kScratchPadSize = 1024;
    auto memory_or_error = AutomaticMemoryInTracee::Create(pid, 0, kScratchPadSize);
    ASSERT_TRUE(memory_or_error.has_value());
    // Move function's address to rax, do the call, and hit a breakpoint:
    // movabs rax, function_address     48 b8 function_address
    // call rax                         ff d0
    // int3                             cc
    MachineCode code;
    code.AppendBytes({0x48, 0xb8})
        .AppendImmediate64(function_address)
        .AppendBytes({0xff, 0xd0})
        .AppendBytes({0xcc});

    auto result_or_error = ExecuteMachineCode(*memory_or_error.value(), code);
    ASSERT_THAT(result_or_error, HasNoError());
    EXPECT_EQ(42, result_or_error.value());
  }

  // Close the library.
  auto result_dlclose = DlcloseInTracee(pid, library_handle_or_error.value());
  ASSERT_THAT(result_dlclose, HasNoError());

  // Now, again, the lib is absent from the tracee.
  auto maps_after_close = orbit_base::ReadFileToString(absl::StrFormat("/proc/%d/maps", pid));
  CHECK(maps_after_close.has_value());
  EXPECT_FALSE(absl::StrContains(maps_after_close.value(), library_path.filename().string()));

  CHECK(!DetachAndContinueProcess(pid).has_error());
}

}  // namespace

TEST(InjectLibraryInTraceeTest, OpenUseAndCloseLibraryInUserCode) {
  pid_t pid = fork();
  CHECK(pid != -1);
  if (pid == 0) {
    volatile uint64_t counter = 0;
    while (true) {
      // Endless loops without side effects are UB and recent versions of clang optimize it away.
      ++counter;
    }
  }

  OpenUseAndCloseLibrary(pid);

  // End child process.
  kill(pid, SIGKILL);
  waitpid(pid, nullptr, 0);
}

TEST(InjectLibraryInTraceeTest, OpenUseAndCloseLibraryInSyscall) {
  pid_t pid = fork();
  CHECK(pid != -1);
  if (pid == 0) {
    while (true) {
      // Child will be stuck in syscall sys_clock_nanosleep.
      std::this_thread::sleep_for(std::chrono::hours(1000000000));
    }
  }

  OpenUseAndCloseLibrary(pid);

  // End child process.
  kill(pid, SIGKILL);
  waitpid(pid, nullptr, 0);
}

TEST(InjectLibraryInTraceeTest, NonExistingLibrary) {
  pid_t pid = fork();
  CHECK(pid != -1);
  if (pid == 0) {
    while (true) {
      // Child will be stuck in syscall sys_clock_nanosleep.
      std::this_thread::sleep_for(std::chrono::hours(1000000000));
    }
  }

  // Stop the child process using our tooling.
  CHECK(!AttachAndStopProcess(pid).has_error());

  // Try to load non existing dynamic lib into tracee.
  const std::string kNonExistingLibName = "libNotFound.so";
  auto library_handle_or_error = DlopenInTracee(pid, kNonExistingLibName, RTLD_NOW);
  ASSERT_THAT(library_handle_or_error, HasError("Library does not exist at"));

  // Continue child process.
  CHECK(!DetachAndContinueProcess(pid).has_error());

  // End child process.
  kill(pid, SIGKILL);
  waitpid(pid, nullptr, 0);
}

}  // namespace orbit_user_space_instrumentation
<commit_msg>Compare inodes instead of file paths in tests (#2868)<commit_after>// Copyright (c) 2021 The Orbit Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <absl/base/casts.h>
#include <absl/strings/match.h>
#include <absl/strings/str_format.h>
#include <absl/strings/str_split.h>
#include <dlfcn.h>
#include <gtest/gtest.h>
#include <sys/sysmacros.h>
#include <sys/wait.h>

#include <charconv>
#include <chrono>
#include <csignal>
#include <string>
#include <string_view>
#include <system_error>
#include <thread>

#include "AllocateInTracee.h"
#include "ExecuteMachineCode.h"
#include "GetTestLibLibraryPath.h"
#include "MachineCode.h"
#include "OrbitBase/ExecutablePath.h"
#include "OrbitBase/Logging.h"
#include "OrbitBase/ReadFileToString.h"
#include "OrbitBase/Result.h"
#include "TestUtils/TestUtils.h"
#include "UserSpaceInstrumentation/Attach.h"
#include "UserSpaceInstrumentation/InjectLibraryInTracee.h"

namespace orbit_user_space_instrumentation {

namespace {

using orbit_test_utils::HasError;
using orbit_test_utils::HasNoError;
using testing::Eq;

// The device ID and the inode ID together uniquely identify a file on a single machine.
// Ref: https://www.gnu.org/software/libc/manual/html_node/Attribute-Meanings.html
struct DeviceInodePair {
  dev_t device;
  ino_t inode;
};

ErrorMessageOr<bool> IsDeviceInodePairInMapsFile(DeviceInodePair device_inode, pid_t pid) {
  OUTCOME_TRY(auto&& maps_contents,
              orbit_base::ReadFileToString(absl::StrFormat("/proc/%d/maps", pid)));

  std::vector<std::string_view> lines = absl::StrSplit(maps_contents, '\n');

  for (const auto& line : lines) {
    std::vector<std::string_view> fields = absl::StrSplit(line, ' ', absl::SkipEmpty{});
    constexpr int kInodeFieldIndex = 4;
    if (fields.size() <= kInodeFieldIndex) continue;

    ino_t current_inode{};
    if (!absl::SimpleAtoi(fields[kInodeFieldIndex], &current_inode)) continue;
    if (current_inode != device_inode.inode) continue;

    // The device field is formatted as `AA:BB` where `AA` is a single hex byte representing the
    // major number and `BB` being a single hex byte representing the minor number. Both numbers
    // are always two digits wide.
    constexpr int kDeviceFieldIndex = 3;
    std::vector<std::string_view> device_number_fields =
        absl::StrSplit(fields[kDeviceFieldIndex], ':');
    if (device_number_fields.size() != 2) continue;

    constexpr int kMajorFieldIndex = 0;
    if (device_number_fields[kMajorFieldIndex].size() != 2) continue;
    uint32_t major_number{};
    if (std::from_chars(device_number_fields[kMajorFieldIndex].begin(),
                        device_number_fields[kMajorFieldIndex].end(), major_number, 16)
            .ec != std::errc{}) {
      continue;
    }

    constexpr int kMinorFieldIndex = 1;
    if (device_number_fields[kMinorFieldIndex].size() != 2) continue;
    uint32_t minor_number{};
    if (std::from_chars(device_number_fields[kMinorFieldIndex].begin(),
                        device_number_fields[kMinorFieldIndex].end(), minor_number, 16)
            .ec != std::errc{}) {
      continue;
    }

    if (makedev(major_number, minor_number) == device_inode.device) return true;
  }

  return false;
}

ErrorMessageOr<DeviceInodePair> GetDeviceInodePairFromFilePath(const std::string& file_path) {
  struct stat stat_buf {};
  if (stat(file_path.c_str(), &stat_buf) != 0) {
    return ErrorMessage{absl::StrFormat("Failed to obtain inode of '%s'", file_path)};
  }
  return DeviceInodePair{stat_buf.st_dev, stat_buf.st_ino};
}

void OpenUseAndCloseLibrary(pid_t pid) {
  // Stop the child process using our tooling.
  CHECK(!AttachAndStopProcess(pid).has_error());

  auto library_path_or_error = GetTestLibLibraryPath();
  ASSERT_THAT(library_path_or_error, HasNoError());
  std::filesystem::path library_path = std::move(library_path_or_error.value());

  ErrorMessageOr<DeviceInodePair> device_inode_pair_of_library =
      GetDeviceInodePairFromFilePath(library_path);
  ASSERT_THAT(device_inode_pair_of_library, HasNoError());

  // Tracee does not have the dynamic lib loaded, obviously.
  EXPECT_THAT(IsDeviceInodePairInMapsFile(device_inode_pair_of_library.value(), pid),
              orbit_test_utils::HasValue(Eq(false)));

  auto library_handle_or_error = DlopenInTracee(pid, library_path, RTLD_NOW);
  ASSERT_TRUE(library_handle_or_error.has_value());

  // Tracee now does have the dynamic lib loaded.
  EXPECT_THAT(IsDeviceInodePairInMapsFile(device_inode_pair_of_library.value(), pid),
              orbit_test_utils::HasValue(Eq(true)));

  // Look up symbol for "TrivialFunction" in the dynamic lib.
  auto dlsym_or_error = DlsymInTracee(pid, library_handle_or_error.value(), "TrivialFunction");
  ASSERT_TRUE(dlsym_or_error.has_value());
  const uint64_t function_address = absl::bit_cast<uint64_t>(dlsym_or_error.value());

  {
    // Write machine code to call "TrivialFunction" from the dynamic lib.
    constexpr uint64_t kScratchPadSize = 1024;
    auto memory_or_error = AutomaticMemoryInTracee::Create(pid, 0, kScratchPadSize);
    ASSERT_TRUE(memory_or_error.has_value());
    // Move function's address to rax, do the call, and hit a breakpoint:
    // movabs rax, function_address     48 b8 function_address
    // call rax                         ff d0
    // int3                             cc
    MachineCode code;
    code.AppendBytes({0x48, 0xb8})
        .AppendImmediate64(function_address)
        .AppendBytes({0xff, 0xd0})
        .AppendBytes({0xcc});

    auto result_or_error = ExecuteMachineCode(*memory_or_error.value(), code);
    ASSERT_THAT(result_or_error, HasNoError());
    EXPECT_EQ(42, result_or_error.value());
  }

  // Close the library.
  auto result_dlclose = DlcloseInTracee(pid, library_handle_or_error.value());
  ASSERT_THAT(result_dlclose, HasNoError());

  // Now, again, the lib is absent from the tracee.
  EXPECT_THAT(IsDeviceInodePairInMapsFile(device_inode_pair_of_library.value(), pid),
              orbit_test_utils::HasValue(Eq(false)));

  CHECK(!DetachAndContinueProcess(pid).has_error());
}

}  // namespace

TEST(InjectLibraryInTraceeTest, OpenUseAndCloseLibraryInUserCode) {
  pid_t pid = fork();
  CHECK(pid != -1);
  if (pid == 0) {
    volatile uint64_t counter = 0;
    while (true) {
      // Endless loops without side effects are UB and recent versions of clang optimize it away.
      ++counter;
    }
  }

  OpenUseAndCloseLibrary(pid);

  // End child process.
  kill(pid, SIGKILL);
  waitpid(pid, nullptr, 0);
}

TEST(InjectLibraryInTraceeTest, OpenUseAndCloseLibraryInSyscall) {
  pid_t pid = fork();
  CHECK(pid != -1);
  if (pid == 0) {
    while (true) {
      // Child will be stuck in syscall sys_clock_nanosleep.
      std::this_thread::sleep_for(std::chrono::hours(1000000000));
    }
  }

  OpenUseAndCloseLibrary(pid);

  // End child process.
  kill(pid, SIGKILL);
  waitpid(pid, nullptr, 0);
}

TEST(InjectLibraryInTraceeTest, NonExistingLibrary) {
  pid_t pid = fork();
  CHECK(pid != -1);
  if (pid == 0) {
    while (true) {
      // Child will be stuck in syscall sys_clock_nanosleep.
      std::this_thread::sleep_for(std::chrono::hours(1000000000));
    }
  }

  // Stop the child process using our tooling.
  CHECK(!AttachAndStopProcess(pid).has_error());

  // Try to load non existing dynamic lib into tracee.
  const std::string kNonExistingLibName = "libNotFound.so";
  auto library_handle_or_error = DlopenInTracee(pid, kNonExistingLibName, RTLD_NOW);
  ASSERT_THAT(library_handle_or_error, HasError("Library does not exist at"));

  // Continue child process.
  CHECK(!DetachAndContinueProcess(pid).has_error());

  // End child process.
  kill(pid, SIGKILL);
  waitpid(pid, nullptr, 0);
}

}  // namespace orbit_user_space_instrumentation
<|endoftext|>


<commit_before>/*
 * Copyright 2014 University of Chicago and Argonne National Laboratory
 *
 * 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
 */

/*
 * Implementation of pure C functions.
 *
 * Created: Jun 18, 2014
 *    Author: Tim Armstrong
 */

#include "coasters.h"

#include <cassert>
#include <cstdlib>

#include "CoasterClient.h"
#include "CoasterError.h"
#include "CoasterLoop.h"

using std::malloc;
using std::free;

using std::string;

/*
  Struct just wraps the object
 */
struct coaster_client {
  CoasterLoop loop;
  CoasterClient client;

  /*
    Constructor: initialize loop then client
   */
  coaster_client(string serviceURL) :
        loop(), client(serviceURL, loop) {

  };
};

struct coaster_settings {
  Settings settings;

  coaster_settings() : settings() {};
};

struct coaster_job {
  Job job;

  coaster_job(const string &executable) : job(executable) {};
};

static coaster_rc coaster_error_rc(const CoasterError &err);
static coaster_rc exception_rc(const std::exception &ex);

// Check for error
// TODO: store error message somewhere instead of printing?
#define COASTER_CONDITION(cond, err_rc, err_msg) { \
  if (!(cond)) { fprintf(stderr, (err_msg)); return (err_rc); }}

coaster_rc
coaster_client_start(const char *service_url, size_t service_url_len,
                    coaster_client **client) COASTERS_THROWS_NOTHING {
  try {
    *client = new coaster_client(string(service_url, service_url_len));
    if (!(*client)) {
      return COASTER_ERROR_OOM;
    }

    (*client)->client.start();
    return COASTER_SUCCESS;
  } catch (const CoasterError& err) {
    return coaster_error_rc(err);
  } catch (const std::exception& ex) {
    return exception_rc(ex);
  }
}

coaster_rc coaster_client_stop(coaster_client *client)
                               COASTERS_THROWS_NOTHING {
  try {
    // TODO: stop things

    client->client.stop();
    client->loop.stop();

    delete client;
    return COASTER_SUCCESS;
  } catch (const CoasterError& err) {
    return coaster_error_rc(err);
  } catch (const std::exception& ex) {
    return exception_rc(ex);
  }
}

coaster_rc coaster_settings_create(coaster_settings **settings)
                                COASTERS_THROWS_NOTHING {
  try {
    *settings = new coaster_settings();
    if (!(*settings)) {
      return COASTER_ERROR_OOM;
    }

    return COASTER_SUCCESS;
  } catch (const CoasterError& err) {
    return coaster_error_rc(err);
  } catch (const std::exception& ex) {
    return exception_rc(ex);
  }
}

coaster_rc coaster_settings_parse(coaster_settings *settings,
                                  const char *str)
                                COASTERS_THROWS_NOTHING {

  // TODO: parsing using code currently in CoasterSwig
  return COASTER_ERROR_UNKNOWN;
}

coaster_rc
coaster_settings_set(coaster_settings *settings,
          const char *key, size_t key_len,
          const char *value, size_t value_len) COASTERS_THROWS_NOTHING {
  try {
    settings->settings.set(key, key_len, value, value_len);
    return COASTER_SUCCESS;
  } catch (const CoasterError& err) {
    return coaster_error_rc(err);
  } catch (const std::exception& ex) {
    return exception_rc(ex);
  }
}

coaster_rc
coaster_settings_get(coaster_settings *settings,
            const char *key, size_t key_len,
            const char **value, size_t *value_len) COASTERS_THROWS_NOTHING {
  try {
    std::map<string, string> &map = settings->settings.getSettings();
    std::string &str_value = map[string(key, key_len)];
    *value = str_value.c_str();
    *value_len = str_value.length();
    return COASTER_SUCCESS;
  } catch (const CoasterError& err) {
    return coaster_error_rc(err);
  } catch (const std::exception& ex) {
    return exception_rc(ex);
  }
}

coaster_rc
coaster_settings_keys(coaster_settings *settings,
              const char ***keys, size_t **key_lens, int *count)
                                COASTERS_THROWS_NOTHING {
  try {
    std::map<string, string> &map = settings->settings.getSettings();
    *count = map.size();

    // Use malloc so C client code can free
    *keys = (const char**)malloc(sizeof((*keys)[0]) * (*count));
    if (!(*keys)) {
      return COASTER_ERROR_OOM;
    }

    if (key_lens != NULL) {
      *key_lens = (size_t *)malloc(sizeof((*key_lens)[0]) * (*count));
      if (!(*key_lens)) {
        free(*keys);
        return COASTER_ERROR_OOM;
      }
    }

    int pos = 0;
    for(std::map<string, string>::iterator iter = map.begin();
        iter != map.end(); ++iter) {
      (*keys)[pos] = iter->first.c_str();
      if (key_lens != NULL) {
        (*key_lens)[pos] = iter->first.length();
      }
      pos++;
    }

    return COASTER_SUCCESS;
  } catch (const CoasterError& err) {
    return coaster_error_rc(err);
  } catch (const std::exception& ex) {
    return exception_rc(ex);
  }
}

void
coaster_settings_free(coaster_settings *settings)
                                COASTERS_THROWS_NOTHING {
  // Call destructor directly
  // Destructor shouldn't throw anything
  delete settings;
}

/*
 * Apply settings to started coasters client.
 */
coaster_rc
coaster_apply_settings(coaster_client *client,
                                  coaster_settings *settings)
                                  COASTERS_THROWS_NOTHING {
  try {
    client->client.setOptions(settings->settings);
    return COASTER_SUCCESS;
  } catch (const CoasterError& err) {
    return coaster_error_rc(err);
  } catch (const std::exception& ex) {
    return exception_rc(ex);
  }
}

coaster_rc
coaster_job_create(const char *executable, size_t executable_len,
                  int argc, const char **argv, const size_t *arg_lens,
                  const char *job_manager, size_t job_manager_len,
                  coaster_job **job) COASTERS_THROWS_NOTHING {
  try {
    assert(executable != NULL);
    coaster_job *j = new coaster_job(string(executable, executable_len));

    for (int i = 0; i < argc; i++)
    {
      assert(argv[i] != NULL);
      j->job.addArgument(argv[i], arg_lens[i]);
    }

    if (job_manager != NULL) {
      j->job.setJobManager(job_manager, job_manager_len);
    }

    *job = j;
    return COASTER_SUCCESS;
  } catch (const CoasterError& err) {
    return coaster_error_rc(err);
  } catch (const std::exception& ex) {
    return exception_rc(ex);
  }
}

coaster_rc
coaster_job_free(coaster_job *job) COASTERS_THROWS_NOTHING {
  // Destructor shouldn't throw anything
  delete job;
}

coaster_rc
coaster_job_set_redirects(coaster_job *job,
      const char *stdin_loc, size_t stdin_loc_len,
      const char *stdout_loc, size_t stdout_loc_len,
      const char *stderr_loc, size_t stderr_loc_len)
                  COASTERS_THROWS_NOTHING {
  if (job == NULL) {
    return COASTER_ERROR_INVALID;
  }

  try {
    // job expects to get ownership of references, so use new
    if (stdin_loc != NULL) {
      job->job.setStdinLocation(*new string(stdin_loc, stdin_loc_len));
    }

    if (stdout_loc != NULL) {
      job->job.setStdoutLocation(*new string(stdout_loc, stdout_loc_len));
    }

    if (stderr_loc != NULL) {
      job->job.setStderrLocation(*new string(stderr_loc, stderr_loc_len));
    }

    return COASTER_SUCCESS;
  } catch (const CoasterError& err) {
    return coaster_error_rc(err);
  } catch (const std::exception& ex) {
    return exception_rc(ex);
  }
}

coaster_rc
coaster_job_set_directory(coaster_job *job, const char *dir, size_t dir_len)
                  COASTERS_THROWS_NOTHING {
  if (job == NULL) {
    return COASTER_ERROR_INVALID;
  }

  try {
    if (dir != NULL) {
      job->job.setDirectory(*new string(dir, dir_len));
    }

    return COASTER_SUCCESS;
  } catch (const CoasterError& err) {
    return coaster_error_rc(err);
  } catch (const std::exception& ex) {
    return exception_rc(ex);
  }
}

coaster_rc
coaster_job_set_envs(coaster_job *job, int nvars,
      const char **names, size_t *name_lens,
      const char **values, size_t *value_lens) COASTERS_THROWS_NOTHING {
  if (job == NULL) {
    return COASTER_ERROR_INVALID;
  }

  try {
    for (int i = 0; i < nvars; i++)
    {
      const char *name = names[i];
      size_t name_len = name_lens[i];
      const char *value = values[i];
      size_t value_len = value_lens[i];
      COASTER_CONDITION(name != NULL && value != NULL,
            COASTER_ERROR_INVALID, "Env var name or value was NULL");
      job->job.setEnv(name, name_len, value, value_len);
    }

    return COASTER_SUCCESS;
  } catch (const CoasterError& err) {
    return coaster_error_rc(err);
  } catch (const std::exception& ex) {
    return exception_rc(ex);
  }
}

/*
 * Add attributes for the job.  Will overwrite any previous atrributes
 * if names match.
 */
coaster_rc
coaster_job_set_attrs(coaster_job *job, int nattrs,
        const char **names, size_t *name_lens,
        const char **values, size_t *value_lens) COASTERS_THROWS_NOTHING {

  if (job == NULL) {
    return COASTER_ERROR_INVALID;
  }

  try {
    for (int i = 0; i < nattrs; i++)
    {
      const char *name = names[i];
      size_t name_len = name_lens[i];
      const char *value = values[i];
      size_t value_len = value_lens[i];
      COASTER_CONDITION(name != NULL && value != NULL,
            COASTER_ERROR_INVALID, "Attribute name or value was NULL");
      job->job.setAttribute(name, name_len, value, value_len);
    }

    return COASTER_SUCCESS;
  } catch (const CoasterError& err) {
    return coaster_error_rc(err);
  } catch (const std::exception& ex) {
    return exception_rc(ex);
  }
}

coaster_rc
coaster_job_add_cleanups(coaster_job *job, int ncleanups,
        const char **cleanups, size_t *cleanup_lens)
        COASTERS_THROWS_NOTHING {

  if (job == NULL) {
    return COASTER_ERROR_INVALID;
  }

  try {
    for (int i = 0; i < ncleanups; i++)
    {
      const char *cleanup = cleanups[i];
      size_t cleanup_len = cleanup_lens[i];
      COASTER_CONDITION(cleanup != NULL,
            COASTER_ERROR_INVALID, "Cleanup was NULL");
      job->job.addCleanup(cleanup, cleanup_len);
    }

    return COASTER_SUCCESS;
  } catch (const CoasterError& err) {
    return coaster_error_rc(err);
  } catch (const std::exception& ex) {
    return exception_rc(ex);
  }
}

int64_t
coaster_job_get_id(coaster_job *job) COASTERS_THROWS_NOTHING {
  // Shouldn't throw anything from accessor method
  return job->job.getIdentity();
}

coaster_rc
coaster_job_status_code(coaster_job *job, coaster_job_status *code)
                                            COASTERS_THROWS_NOTHING {
  const JobStatus *status;
  if (job == NULL || (status = job->job.getStatus()) == NULL) {
    return COASTER_ERROR_INVALID;
  }

  *code = status->getStatusCode();
  return COASTER_SUCCESS;
}

coaster_rc
coaster_job_get_outstreams(coaster_job *job,
                const char **stdout_s, size_t *stdout_len,
                const char **stderr_s, size_t *stderr_len)
                COASTERS_THROWS_NOTHING {
  if (job == NULL) {
    return COASTER_ERROR_INVALID;
  }

  const string *out = job->job.getStdout();
  const string *err = job->job.getStderr();

  if (out != NULL) {
    *stderr_s = out->c_str();
    *stderr_len = out->length();
  } else {
    *stderr_s = NULL;
    *stderr_len = 0;
  }

  if (err != NULL) {
    *stderr_s = err->c_str();
    *stderr_len = err->length();
  } else {
    *stderr_s = NULL;
    *stderr_len = 0;
  }

  return COASTER_SUCCESS;
}

coaster_rc
coaster_submit(coaster_client *client, coaster_job *job)
                COASTERS_THROWS_NOTHING {
  try {
    client->client.submit(job->job);
  } catch (const CoasterError& err) {
    return coaster_error_rc(err);
  } catch (const std::exception& ex) {
    return exception_rc(ex);
  }
}

const char *coaster_rc_string(coaster_rc code)
{
  switch (code)
  {
    case COASTER_SUCCESS:
      return "COASTER_SUCCESS";
    case COASTER_ERROR_OOM:
      return "COASTER_ERROR_OOM";
    case COASTER_ERROR_NETWORK:
      return "COASTER_ERROR_NETWORK";
    case COASTER_ERROR_UNKNOWN:
      return "COASTER_ERROR_UNKNOWN";
    default:
      return (const char*)0;
  }
}

/*
 * Set error information and return appropriate code
 */
static coaster_rc coaster_error_rc(const CoasterError &err) {
  // TODO: store detailed error info
  // TODO: distinguish different cases?
  return COASTER_ERROR_UNKNOWN;
}

static coaster_rc exception_rc(const std::exception &ex) {
  // TODO: store error info?
  // TODO: handle specific types, e.g. bad_alloc
  return COASTER_ERROR_UNKNOWN;
}
<commit_msg>Use typedefed type<commit_after>/*
 * Copyright 2014 University of Chicago and Argonne National Laboratory
 *
 * 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
 */

/*
 * Implementation of pure C functions.
 *
 * Created: Jun 18, 2014
 *    Author: Tim Armstrong
 */

#include "coasters.h"

#include <cassert>
#include <cstdlib>

#include "CoasterClient.h"
#include "CoasterError.h"
#include "CoasterLoop.h"

using std::malloc;
using std::free;

using std::string;

/*
  Struct just wraps the object
 */
struct coaster_client {
  CoasterLoop loop;
  CoasterClient client;

  /*
    Constructor: initialize loop then client
   */
  coaster_client(string serviceURL) :
        loop(), client(serviceURL, loop) {

  };
};

struct coaster_settings {
  Settings settings;

  coaster_settings() : settings() {};
};

struct coaster_job {
  Job job;

  coaster_job(const string &executable) : job(executable) {};
};

static coaster_rc coaster_error_rc(const CoasterError &err);
static coaster_rc exception_rc(const std::exception &ex);

// Check for error
// TODO: store error message somewhere instead of printing?
#define COASTER_CONDITION(cond, err_rc, err_msg) { \
  if (!(cond)) { fprintf(stderr, (err_msg)); return (err_rc); }}

coaster_rc
coaster_client_start(const char *service_url, size_t service_url_len,
                    coaster_client **client) COASTERS_THROWS_NOTHING {
  try {
    *client = new coaster_client(string(service_url, service_url_len));
    if (!(*client)) {
      return COASTER_ERROR_OOM;
    }

    (*client)->client.start();
    return COASTER_SUCCESS;
  } catch (const CoasterError& err) {
    return coaster_error_rc(err);
  } catch (const std::exception& ex) {
    return exception_rc(ex);
  }
}

coaster_rc coaster_client_stop(coaster_client *client)
                               COASTERS_THROWS_NOTHING {
  try {
    // TODO: stop things

    client->client.stop();
    client->loop.stop();

    delete client;
    return COASTER_SUCCESS;
  } catch (const CoasterError& err) {
    return coaster_error_rc(err);
  } catch (const std::exception& ex) {
    return exception_rc(ex);
  }
}

coaster_rc coaster_settings_create(coaster_settings **settings)
                                COASTERS_THROWS_NOTHING {
  try {
    *settings = new coaster_settings();
    if (!(*settings)) {
      return COASTER_ERROR_OOM;
    }

    return COASTER_SUCCESS;
  } catch (const CoasterError& err) {
    return coaster_error_rc(err);
  } catch (const std::exception& ex) {
    return exception_rc(ex);
  }
}

coaster_rc coaster_settings_parse(coaster_settings *settings,
                                  const char *str)
                                COASTERS_THROWS_NOTHING {

  // TODO: parsing using code currently in CoasterSwig
  return COASTER_ERROR_UNKNOWN;
}

coaster_rc
coaster_settings_set(coaster_settings *settings,
          const char *key, size_t key_len,
          const char *value, size_t value_len) COASTERS_THROWS_NOTHING {
  try {
    settings->settings.set(key, key_len, value, value_len);
    return COASTER_SUCCESS;
  } catch (const CoasterError& err) {
    return coaster_error_rc(err);
  } catch (const std::exception& ex) {
    return exception_rc(ex);
  }
}

coaster_rc
coaster_settings_get(coaster_settings *settings,
            const char *key, size_t key_len,
            const char **value, size_t *value_len) COASTERS_THROWS_NOTHING {
  try {
    std::map<string, string> &map = settings->settings.getSettings();
    std::string &str_value = map[string(key, key_len)];
    *value = str_value.c_str();
    *value_len = str_value.length();
    return COASTER_SUCCESS;
  } catch (const CoasterError& err) {
    return coaster_error_rc(err);
  } catch (const std::exception& ex) {
    return exception_rc(ex);
  }
}

coaster_rc
coaster_settings_keys(coaster_settings *settings,
              const char ***keys, size_t **key_lens, int *count)
                                COASTERS_THROWS_NOTHING {
  try {
    std::map<string, string> &map = settings->settings.getSettings();
    *count = map.size();

    // Use malloc so C client code can free
    *keys = (const char**)malloc(sizeof((*keys)[0]) * (*count));
    if (!(*keys)) {
      return COASTER_ERROR_OOM;
    }

    if (key_lens != NULL) {
      *key_lens = (size_t *)malloc(sizeof((*key_lens)[0]) * (*count));
      if (!(*key_lens)) {
        free(*keys);
        return COASTER_ERROR_OOM;
      }
    }

    int pos = 0;
    for(std::map<string, string>::iterator iter = map.begin();
        iter != map.end(); ++iter) {
      (*keys)[pos] = iter->first.c_str();
      if (key_lens != NULL) {
        (*key_lens)[pos] = iter->first.length();
      }
      pos++;
    }

    return COASTER_SUCCESS;
  } catch (const CoasterError& err) {
    return coaster_error_rc(err);
  } catch (const std::exception& ex) {
    return exception_rc(ex);
  }
}

void
coaster_settings_free(coaster_settings *settings)
                                COASTERS_THROWS_NOTHING {
  // Call destructor directly
  // Destructor shouldn't throw anything
  delete settings;
}

/*
 * Apply settings to started coasters client.
 */
coaster_rc
coaster_apply_settings(coaster_client *client,
                                  coaster_settings *settings)
                                  COASTERS_THROWS_NOTHING {
  try {
    client->client.setOptions(settings->settings);
    return COASTER_SUCCESS;
  } catch (const CoasterError& err) {
    return coaster_error_rc(err);
  } catch (const std::exception& ex) {
    return exception_rc(ex);
  }
}

coaster_rc
coaster_job_create(const char *executable, size_t executable_len,
                  int argc, const char **argv, const size_t *arg_lens,
                  const char *job_manager, size_t job_manager_len,
                  coaster_job **job) COASTERS_THROWS_NOTHING {
  try {
    assert(executable != NULL);
    coaster_job *j = new coaster_job(string(executable, executable_len));

    for (int i = 0; i < argc; i++)
    {
      assert(argv[i] != NULL);
      j->job.addArgument(argv[i], arg_lens[i]);
    }

    if (job_manager != NULL) {
      j->job.setJobManager(job_manager, job_manager_len);
    }

    *job = j;
    return COASTER_SUCCESS;
  } catch (const CoasterError& err) {
    return coaster_error_rc(err);
  } catch (const std::exception& ex) {
    return exception_rc(ex);
  }
}

coaster_rc
coaster_job_free(coaster_job *job) COASTERS_THROWS_NOTHING {
  // Destructor shouldn't throw anything
  delete job;
}

coaster_rc
coaster_job_set_redirects(coaster_job *job,
      const char *stdin_loc, size_t stdin_loc_len,
      const char *stdout_loc, size_t stdout_loc_len,
      const char *stderr_loc, size_t stderr_loc_len)
                  COASTERS_THROWS_NOTHING {
  if (job == NULL) {
    return COASTER_ERROR_INVALID;
  }

  try {
    // job expects to get ownership of references, so use new
    if (stdin_loc != NULL) {
      job->job.setStdinLocation(*new string(stdin_loc, stdin_loc_len));
    }

    if (stdout_loc != NULL) {
      job->job.setStdoutLocation(*new string(stdout_loc, stdout_loc_len));
    }

    if (stderr_loc != NULL) {
      job->job.setStderrLocation(*new string(stderr_loc, stderr_loc_len));
    }

    return COASTER_SUCCESS;
  } catch (const CoasterError& err) {
    return coaster_error_rc(err);
  } catch (const std::exception& ex) {
    return exception_rc(ex);
  }
}

coaster_rc
coaster_job_set_directory(coaster_job *job, const char *dir, size_t dir_len)
                  COASTERS_THROWS_NOTHING {
  if (job == NULL) {
    return COASTER_ERROR_INVALID;
  }

  try {
    if (dir != NULL) {
      job->job.setDirectory(*new string(dir, dir_len));
    }

    return COASTER_SUCCESS;
  } catch (const CoasterError& err) {
    return coaster_error_rc(err);
  } catch (const std::exception& ex) {
    return exception_rc(ex);
  }
}

coaster_rc
coaster_job_set_envs(coaster_job *job, int nvars,
      const char **names, size_t *name_lens,
      const char **values, size_t *value_lens) COASTERS_THROWS_NOTHING {
  if (job == NULL) {
    return COASTER_ERROR_INVALID;
  }

  try {
    for (int i = 0; i < nvars; i++)
    {
      const char *name = names[i];
      size_t name_len = name_lens[i];
      const char *value = values[i];
      size_t value_len = value_lens[i];
      COASTER_CONDITION(name != NULL && value != NULL,
            COASTER_ERROR_INVALID, "Env var name or value was NULL");
      job->job.setEnv(name, name_len, value, value_len);
    }

    return COASTER_SUCCESS;
  } catch (const CoasterError& err) {
    return coaster_error_rc(err);
  } catch (const std::exception& ex) {
    return exception_rc(ex);
  }
}

/*
 * Add attributes for the job.  Will overwrite any previous atrributes
 * if names match.
 */
coaster_rc
coaster_job_set_attrs(coaster_job *job, int nattrs,
        const char **names, size_t *name_lens,
        const char **values, size_t *value_lens) COASTERS_THROWS_NOTHING {

  if (job == NULL) {
    return COASTER_ERROR_INVALID;
  }

  try {
    for (int i = 0; i < nattrs; i++)
    {
      const char *name = names[i];
      size_t name_len = name_lens[i];
      const char *value = values[i];
      size_t value_len = value_lens[i];
      COASTER_CONDITION(name != NULL && value != NULL,
            COASTER_ERROR_INVALID, "Attribute name or value was NULL");
      job->job.setAttribute(name, name_len, value, value_len);
    }

    return COASTER_SUCCESS;
  } catch (const CoasterError& err) {
    return coaster_error_rc(err);
  } catch (const std::exception& ex) {
    return exception_rc(ex);
  }
}

coaster_rc
coaster_job_add_cleanups(coaster_job *job, int ncleanups,
        const char **cleanups, size_t *cleanup_lens)
        COASTERS_THROWS_NOTHING {

  if (job == NULL) {
    return COASTER_ERROR_INVALID;
  }

  try {
    for (int i = 0; i < ncleanups; i++)
    {
      const char *cleanup = cleanups[i];
      size_t cleanup_len = cleanup_lens[i];
      COASTER_CONDITION(cleanup != NULL,
            COASTER_ERROR_INVALID, "Cleanup was NULL");
      job->job.addCleanup(cleanup, cleanup_len);
    }

    return COASTER_SUCCESS;
  } catch (const CoasterError& err) {
    return coaster_error_rc(err);
  } catch (const std::exception& ex) {
    return exception_rc(ex);
  }
}

job_id_t
coaster_job_get_id(coaster_job *job) COASTERS_THROWS_NOTHING {
  // Shouldn't throw anything from accessor method
  return job->job.getIdentity();
}

coaster_rc
coaster_job_status_code(coaster_job *job, coaster_job_status *code)
                                            COASTERS_THROWS_NOTHING {
  const JobStatus *status;
  if (job == NULL || (status = job->job.getStatus()) == NULL) {
    return COASTER_ERROR_INVALID;
  }

  *code = status->getStatusCode();
  return COASTER_SUCCESS;
}

coaster_rc
coaster_job_get_outstreams(coaster_job *job,
                const char **stdout_s, size_t *stdout_len,
                const char **stderr_s, size_t *stderr_len)
                COASTERS_THROWS_NOTHING {
  if (job == NULL) {
    return COASTER_ERROR_INVALID;
  }

  const string *out = job->job.getStdout();
  const string *err = job->job.getStderr();

  if (out != NULL) {
    *stderr_s = out->c_str();
    *stderr_len = out->length();
  } else {
    *stderr_s = NULL;
    *stderr_len = 0;
  }

  if (err != NULL) {
    *stderr_s = err->c_str();
    *stderr_len = err->length();
  } else {
    *stderr_s = NULL;
    *stderr_len = 0;
  }

  return COASTER_SUCCESS;
}

coaster_rc
coaster_submit(coaster_client *client, coaster_job *job)
                COASTERS_THROWS_NOTHING {
  try {
    client->client.submit(job->job);
  } catch (const CoasterError& err) {
    return coaster_error_rc(err);
  } catch (const std::exception& ex) {
    return exception_rc(ex);
  }
}

const char *coaster_rc_string(coaster_rc code)
{
  switch (code)
  {
    case COASTER_SUCCESS:
      return "COASTER_SUCCESS";
    case COASTER_ERROR_OOM:
      return "COASTER_ERROR_OOM";
    case COASTER_ERROR_NETWORK:
      return "COASTER_ERROR_NETWORK";
    case COASTER_ERROR_UNKNOWN:
      return "COASTER_ERROR_UNKNOWN";
    default:
      return (const char*)0;
  }
}

/*
 * Set error information and return appropriate code
 */
static coaster_rc coaster_error_rc(const CoasterError &err) {
  // TODO: store detailed error info
  // TODO: distinguish different cases?
  return COASTER_ERROR_UNKNOWN;
}

static coaster_rc exception_rc(const std::exception &ex) {
  // TODO: store error info?
  // TODO: handle specific types, e.g. bad_alloc
  return COASTER_ERROR_UNKNOWN;
}
<|endoftext|>


<commit_before>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p9/procedures/hwp/initfiles/p9_cxa_scom.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                                                     */
#include "p9_cxa_scom.H"
#include <stdint.h>
#include <stddef.h>
#include <fapi2.H>

using namespace fapi2;

constexpr auto literal_0x80031F98D8717 = 0x80031F98D8717;
constexpr auto literal_0x0B1C000104060 = 0x0B1C000104060;
constexpr auto literal_0x2B9C0001240E0 = 0x2B9C0001240E0;
constexpr auto literal_0b0000 = 0b0000;
constexpr auto literal_0b111 = 0b111;
constexpr auto literal_0b0010 = 0b0010;
constexpr auto literal_0b0001 = 0b0001;

fapi2::ReturnCode p9_cxa_scom(const fapi2::Target<fapi2::TARGET_TYPE_CAPP>& TGT0,
                              const fapi2::Target<fapi2::TARGET_TYPE_SYSTEM>& TGT1)
{
    {
        fapi2::ATTR_PROC_FABRIC_ADDR_BAR_MODE_Type l_TGT1_ATTR_PROC_FABRIC_ADDR_BAR_MODE;
        FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_PROC_FABRIC_ADDR_BAR_MODE, TGT1, l_TGT1_ATTR_PROC_FABRIC_ADDR_BAR_MODE));
        fapi2::ATTR_PROC_FABRIC_PUMP_MODE_Type l_TGT1_ATTR_PROC_FABRIC_PUMP_MODE;
        FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_PROC_FABRIC_PUMP_MODE, TGT1, l_TGT1_ATTR_PROC_FABRIC_PUMP_MODE));
        fapi2::buffer<uint64_t> l_scom_buffer;
        {
            FAPI_TRY(fapi2::getScom( TGT0, 0x2010803ull, l_scom_buffer ));

            l_scom_buffer.insert<uint64_t> (literal_0x80031F98D8717, 0, 52, 0 );
            FAPI_TRY(fapi2::putScom(TGT0, 0x2010803ull, l_scom_buffer));
        }
        {
            FAPI_TRY(fapi2::getScom( TGT0, 0x2010806ull, l_scom_buffer ));

            l_scom_buffer.insert<uint64_t> (literal_0x0B1C000104060, 0, 52, 12 );
            FAPI_TRY(fapi2::putScom(TGT0, 0x2010806ull, l_scom_buffer));
        }
        {
            FAPI_TRY(fapi2::getScom( TGT0, 0x2010807ull, l_scom_buffer ));

            l_scom_buffer.insert<uint64_t> (literal_0x2B9C0001240E0, 0, 52, 12 );
            FAPI_TRY(fapi2::putScom(TGT0, 0x2010807ull, l_scom_buffer));
        }
        {
            FAPI_TRY(fapi2::getScom( TGT0, 0x2010818ull, l_scom_buffer ));

            if ((l_TGT1_ATTR_PROC_FABRIC_ADDR_BAR_MODE == fapi2::ENUM_ATTR_PROC_FABRIC_ADDR_BAR_MODE_SMALL_SYSTEM))
            {
                constexpr auto l_CAPP0_CXA_TOP_CXA_APC0_APCCTL_ADR_BAR_MODE_ON = 0x1;
                l_scom_buffer.insert<uint64_t> (l_CAPP0_CXA_TOP_CXA_APC0_APCCTL_ADR_BAR_MODE_ON, 1, 1, 63 );
            }
            else if ((l_TGT1_ATTR_PROC_FABRIC_ADDR_BAR_MODE == fapi2::ENUM_ATTR_PROC_FABRIC_ADDR_BAR_MODE_LARGE_SYSTEM))
            {
                constexpr auto l_CAPP0_CXA_TOP_CXA_APC0_APCCTL_ADR_BAR_MODE_OFF = 0x0;
                l_scom_buffer.insert<uint64_t> (l_CAPP0_CXA_TOP_CXA_APC0_APCCTL_ADR_BAR_MODE_OFF, 1, 1, 63 );
            }

            if ((l_TGT1_ATTR_PROC_FABRIC_PUMP_MODE == fapi2::ENUM_ATTR_PROC_FABRIC_PUMP_MODE_CHIP_IS_GROUP))
            {
                constexpr auto l_CAPP0_CXA_TOP_CXA_APC0_APCCTL_SKIP_G_ON = 0x1;
                l_scom_buffer.insert<uint64_t> (l_CAPP0_CXA_TOP_CXA_APC0_APCCTL_SKIP_G_ON, 6, 1, 63 );
            }
            else if ((l_TGT1_ATTR_PROC_FABRIC_PUMP_MODE == fapi2::ENUM_ATTR_PROC_FABRIC_PUMP_MODE_CHIP_IS_NODE))
            {
                constexpr auto l_CAPP0_CXA_TOP_CXA_APC0_APCCTL_SKIP_G_OFF = 0x0;
                l_scom_buffer.insert<uint64_t> (l_CAPP0_CXA_TOP_CXA_APC0_APCCTL_SKIP_G_OFF, 6, 1, 63 );
            }

            FAPI_TRY(fapi2::putScom(TGT0, 0x2010818ull, l_scom_buffer));
        }
        {
            FAPI_TRY(fapi2::getScom( TGT0, 0x2010819ull, l_scom_buffer ));

            l_scom_buffer.insert<uint64_t> (literal_0b0000, 4, 4, 60 );
            FAPI_TRY(fapi2::putScom(TGT0, 0x2010819ull, l_scom_buffer));
        }
        {
            FAPI_TRY(fapi2::getScom( TGT0, 0x201081bull, l_scom_buffer ));

            l_scom_buffer.insert<uint64_t> (literal_0b111, 45, 3, 61 );
            l_scom_buffer.insert<uint64_t> (literal_0b0010, 48, 4, 60 );
            FAPI_TRY(fapi2::putScom(TGT0, 0x201081bull, l_scom_buffer));
        }
        {
            FAPI_TRY(fapi2::getScom( TGT0, 0x201081cull, l_scom_buffer ));

            l_scom_buffer.insert<uint64_t> (literal_0b0001, 18, 4, 60 );
            FAPI_TRY(fapi2::putScom(TGT0, 0x201081cull, l_scom_buffer));
        }

    };
fapi_try_exit:
    return fapi2::current_err;
}
<commit_msg>Modify initCompiler to use template version of buffer insert<commit_after>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p9/procedures/hwp/initfiles/p9_cxa_scom.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                                                     */
#include "p9_cxa_scom.H"
#include <stdint.h>
#include <stddef.h>
#include <fapi2.H>

using namespace fapi2;

constexpr uint64_t literal_0x80031F98D8717 = 0x80031F98D8717;
constexpr uint64_t literal_0x0B1C000104060 = 0x0B1C000104060;
constexpr uint64_t literal_0x2B9C0001240E0 = 0x2B9C0001240E0;
constexpr uint64_t literal_0b0000 = 0b0000;
constexpr uint64_t literal_0b111 = 0b111;
constexpr uint64_t literal_0b0010 = 0b0010;
constexpr uint64_t literal_0b0001 = 0b0001;

fapi2::ReturnCode p9_cxa_scom(const fapi2::Target<fapi2::TARGET_TYPE_CAPP>& TGT0,
                              const fapi2::Target<fapi2::TARGET_TYPE_SYSTEM>& TGT1)
{
    {
        fapi2::ATTR_PROC_FABRIC_ADDR_BAR_MODE_Type l_TGT1_ATTR_PROC_FABRIC_ADDR_BAR_MODE;
        FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_PROC_FABRIC_ADDR_BAR_MODE, TGT1, l_TGT1_ATTR_PROC_FABRIC_ADDR_BAR_MODE));
        fapi2::ATTR_PROC_FABRIC_PUMP_MODE_Type l_TGT1_ATTR_PROC_FABRIC_PUMP_MODE;
        FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_PROC_FABRIC_PUMP_MODE, TGT1, l_TGT1_ATTR_PROC_FABRIC_PUMP_MODE));
        fapi2::buffer<uint64_t> l_scom_buffer;
        {
            FAPI_TRY(fapi2::getScom( TGT0, 0x2010803ull, l_scom_buffer ));

            l_scom_buffer.insert<0, 52, 0, uint64_t>(literal_0x80031F98D8717 );
            FAPI_TRY(fapi2::putScom(TGT0, 0x2010803ull, l_scom_buffer));
        }
        {
            FAPI_TRY(fapi2::getScom( TGT0, 0x2010806ull, l_scom_buffer ));

            l_scom_buffer.insert<0, 52, 12, uint64_t>(literal_0x0B1C000104060 );
            FAPI_TRY(fapi2::putScom(TGT0, 0x2010806ull, l_scom_buffer));
        }
        {
            FAPI_TRY(fapi2::getScom( TGT0, 0x2010807ull, l_scom_buffer ));

            l_scom_buffer.insert<0, 52, 12, uint64_t>(literal_0x2B9C0001240E0 );
            FAPI_TRY(fapi2::putScom(TGT0, 0x2010807ull, l_scom_buffer));
        }
        {
            FAPI_TRY(fapi2::getScom( TGT0, 0x2010818ull, l_scom_buffer ));

            if ((l_TGT1_ATTR_PROC_FABRIC_ADDR_BAR_MODE == fapi2::ENUM_ATTR_PROC_FABRIC_ADDR_BAR_MODE_SMALL_SYSTEM))
            {
                constexpr auto l_CAPP0_CXA_TOP_CXA_APC0_APCCTL_ADR_BAR_MODE_ON = 0x1;
                l_scom_buffer.insert<1, 1, 63, uint64_t>(l_CAPP0_CXA_TOP_CXA_APC0_APCCTL_ADR_BAR_MODE_ON );
            }
            else if ((l_TGT1_ATTR_PROC_FABRIC_ADDR_BAR_MODE == fapi2::ENUM_ATTR_PROC_FABRIC_ADDR_BAR_MODE_LARGE_SYSTEM))
            {
                constexpr auto l_CAPP0_CXA_TOP_CXA_APC0_APCCTL_ADR_BAR_MODE_OFF = 0x0;
                l_scom_buffer.insert<1, 1, 63, uint64_t>(l_CAPP0_CXA_TOP_CXA_APC0_APCCTL_ADR_BAR_MODE_OFF );
            }

            if ((l_TGT1_ATTR_PROC_FABRIC_PUMP_MODE == fapi2::ENUM_ATTR_PROC_FABRIC_PUMP_MODE_CHIP_IS_GROUP))
            {
                constexpr auto l_CAPP0_CXA_TOP_CXA_APC0_APCCTL_SKIP_G_ON = 0x1;
                l_scom_buffer.insert<6, 1, 63, uint64_t>(l_CAPP0_CXA_TOP_CXA_APC0_APCCTL_SKIP_G_ON );
            }
            else if ((l_TGT1_ATTR_PROC_FABRIC_PUMP_MODE == fapi2::ENUM_ATTR_PROC_FABRIC_PUMP_MODE_CHIP_IS_NODE))
            {
                constexpr auto l_CAPP0_CXA_TOP_CXA_APC0_APCCTL_SKIP_G_OFF = 0x0;
                l_scom_buffer.insert<6, 1, 63, uint64_t>(l_CAPP0_CXA_TOP_CXA_APC0_APCCTL_SKIP_G_OFF );
            }

            FAPI_TRY(fapi2::putScom(TGT0, 0x2010818ull, l_scom_buffer));
        }
        {
            FAPI_TRY(fapi2::getScom( TGT0, 0x2010819ull, l_scom_buffer ));

            l_scom_buffer.insert<4, 4, 60, uint64_t>(literal_0b0000 );
            FAPI_TRY(fapi2::putScom(TGT0, 0x2010819ull, l_scom_buffer));
        }
        {
            FAPI_TRY(fapi2::getScom( TGT0, 0x201081bull, l_scom_buffer ));

            l_scom_buffer.insert<45, 3, 61, uint64_t>(literal_0b111 );
            l_scom_buffer.insert<48, 4, 60, uint64_t>(literal_0b0010 );
            FAPI_TRY(fapi2::putScom(TGT0, 0x201081bull, l_scom_buffer));
        }
        {
            FAPI_TRY(fapi2::getScom( TGT0, 0x201081cull, l_scom_buffer ));

            l_scom_buffer.insert<18, 4, 60, uint64_t>(literal_0b0001 );
            FAPI_TRY(fapi2::putScom(TGT0, 0x201081cull, l_scom_buffer));
        }

    };
fapi_try_exit:
    return fapi2::current_err;
}
<|endoftext|>