<commit_before>#include "PgfPlotsPlot.hpp"

#include <sstream>
#include <stdexcept>

PgfPlotsPlot::PgfPlotsPlot(const TH1* hist, const std::string &rootStyle,
                           const std::string &options)
	: obj_(hist), options_(options), rootStyle_(rootStyle)
{
	if (!hist) {
		throw std::runtime_error("ERROR: Null histogram pointer!");
	}
}

PgfPlotsPlot::PgfPlotsPlot(const TGraph* graph, const std::string &rootStyle,
	                        const std::string &options)
	: obj_(graph), options_(options), rootStyle_(rootStyle)
{
	if (!graph) {
		throw std::runtime_error("ERROR: Null histogram pointer!");
	}
}

void PgfPlotsPlot::AddNode(const std::string nodeLabel,
                           const std::string nodeOptions)
{
	nodes_.push_back(std::make_pair(nodeLabel, nodeOptions));
}

const TH1* PgfPlotsPlot::GetHist1d() {
	if (GetHist2d()) return nullptr;
	return dynamic_cast<const TH1*>(obj_);
}

/**
 * \param[in] hist Pointer to the histogram to be plotted.
 * \param[in] rootStyle The options to use when plotting the histogram. Currently
 *  supported:
 *    * ""   - Same as HIST below.
 *    * HIST - Draw just the histogram.
 * 	* E    - Draw error bars, show only the bars no markers or lines.
 * 	* E1   - Draw error bars with small lines at end and show markers.
 * \param[in] options Options to the pgfplots plot command.
 *
 * \return A string containing the pgfplots code to render the plot.
 */
std::string PgfPlotsPlot::PlotTH1(const TH1 *hist,
                                  const std::string &rootStyle,
                                  const std::string &options)
{
	//If this is a TH2 we want to call PlotTH2
	const TH2* h2 = dynamic_cast<const TH2*>(hist);
	if (h2) {
		return PlotTH2(h2, rootStyle, options);
	}

	bool includeErrors = false; //Include errors, shows only the error bars, no markers. ROOT option E.
	bool errorMarks = false; //Small lines are darwn at end of the error bars and markers are shown. ROOT option E1.
	if (rootStyle.find("E") != std::string::npos) includeErrors = true;
	if (rootStyle.find("E1") != std::string::npos) errorMarks = true;

	std::stringstream output;

	//Setup the plot style
	output << "\t\\addplot+[";

	//If th e error option was indicated
	if (includeErrors) {
		// exclude markers if not requested.
		if (!errorMarks) output << "scatter, mark=none, ";
		//Remove the line connecting the points.
		output << "only marks, ";
		//Setup the error bars.
		output << "error bars/.cd, y dir=both, y explicit, x dir=both, x explicit";
		//Remove the edges (marks) at the end of the error bars.
		if (!errorMarks) output << ", error mark = none";
	}
	//Otherwise we use a const plot iwth no marks to show bins.
	else output << "const plot, no marks";

	output << "]\n";

	//Begin the cooridnate list
	output << "\t\tcoordinates { ";

	//Add an initial coordinate to extend the left edge of the first bin to zero.
	if (!includeErrors) output << "(" << hist->GetBinLowEdge(1) << ",0) ";

	//Loop over every bin and add a corrdinate for it
	for (int xbin=1; xbin <= hist->GetNbinsX(); xbin++) {
		//Suppress the bins containing zero counts to speed up LaTeX rendering.
		if (errorMarks || (hist->GetBinContent(xbin) != 0 || hist->GetBinContent(xbin - 1) != 0)) {
			output << "(";
			if (includeErrors) output << hist->GetBinCenter(xbin);
			else output << hist->GetBinLowEdge(xbin);
			output << "," << hist->GetBinContent(xbin) << ") ";
			if (includeErrors) output << " +- (" << hist->GetBinWidth(xbin) / 2 <<
				"," << hist->GetBinError(xbin) << ") ";
		}
	}

	//Add a final coordinate to extend the right edge of the last bin to zero.
	if (!includeErrors && hist->GetBinContent(hist->GetNbinsX()) != 0) {
		output << "(" << hist->GetBinLowEdge(hist->GetNbinsX()) +
			hist->GetBinWidth(hist->GetNbinsX()) << "," << 0 << ") ";
	}

	//Coordinate list trailer.
	output << "};\n\n";

	return output.str();
}

/**
 * \param[in] graph Pointer to the graph to be plotted.
 * \param[in] rootStyle The options to use when plotting the graph. Currently
 *  supported:
 *    * "" - Default option is "PL".
 *    * P  - Draw points.
 *    * L  - Draw a connecting line.
 * \param[in] options Options to the pgfplots plot command.
 *
 * \return A string containing the pgfplots code to render the plot.
 */
std::string PgfPlotsPlot::PlotTGraph(const TGraph *graph,
                                     const std::string &rootStyle,
                                     const std::string &options)
{
	std::stringstream output;

	bool marks = false;
	bool lines = false;
	if (rootStyle == "") {
		marks = true;
		lines = true;
	}
	if (rootStyle.find("P") != std::string::npos) marks = true;
	if (rootStyle.find("L") != std::string::npos) lines = true;

	//Setup the plot style
	output << "\t\\addplot+[\n";
	if (!lines) output << "\t\t\tonly marks,\n";
	if (!marks) output << "\t\t\tmark=none,\n";
	output << options;

	output << "\t\t]\n";

	//Begin the cooridnate list
	output << "\t\tcoordinates { ";

	for (int point = 0; point < graph->GetN(); point++) {
		output << "(" << graph->GetX()[point] << ","
			<< graph->GetY()[point] << ") ";
	}

	//Coordinate list trailer.
	output << "};\n\n";

	return output.str();
}

/**By default creates a TikZ matrix plot which is typically used to plot values
 * in a matrix, but can be easily adapted to a two-dimensional histogram. A
 * matrix plot requires that all bins are defined, and thus the option
 * "restrict z to domain*" is used so that empty bins are set to the minimum
 * value. If the option "SURF" is provided a surface plot is created instead,
 * this type of plot requires data at the corners to be provided and thus plots
 * one less bin than is contained in the input histogram.
 *
 * \param[in] hist Pointer to the histogram to be plotted.
 * \param[in] rootStyle The options to use when plotting the histogram.
 * \param[in] options Options to the pgfplots plot command.
 */
std::string PgfPlotsPlot::PlotTH2(const TH2 *hist,
                                  const std::string &rootStyle,
                                  const std::string &options)
{
	bool surfPlot = false;
	if (rootStyle.find("SURF") != std::string::npos) {
		surfPlot = true;
	}

	std::stringstream output;

	output <<
		"\t\\addplot3[";
	if (surfPlot) output << "surf,";
	else output <<	"matrix plot*, \%Similar to `surf`.";
	output << "\n"
			"\t\tshader = flat corner, \n"
			"\t\topacity=ceil(\\pgfplotspointmetatransformed),\n"
			"\t\t\%Ordering of the coordinate data:\n"
			"\t\tmesh/cols=" << hist->GetNbinsX() << ", "
			"mesh/rows=" << hist->GetNbinsY() << ", "
			"mesh/ordering=rowwise]\n"
		"\t\tcoordinates {\n";

	for (int ybin=1; ybin<= hist->GetNbinsY(); ybin++) {
		output << "\t\t\t";
		double yvalue;
		if (surfPlot) yvalue = hist->GetYaxis()->GetBinLowEdge(ybin);
		else yvalue = hist->GetYaxis()->GetBinCenter(ybin);
		for (int xbin=1; xbin<= hist->GetNbinsX(); xbin++) {
			double xvalue;
			if (surfPlot) xvalue = hist->GetXaxis()->GetBinLowEdge(xbin);
			else xvalue = hist->GetXaxis()->GetBinCenter(xbin);
			double weight = hist->GetBinContent(xbin, ybin);
			output << "(" << xvalue << "," << yvalue << "," << weight << ") ";
		}
		output << "\n";
	}

	//Coordinate list trailer.
	output << "\t\t};\n";

	return output.str();
}
void PgfPlotsPlot::Write(std::streambuf *buf) {
	std::string plot_str;
	auto hist1d = GetHist1d();
	auto hist2d = GetHist2d();
	auto graph = GetGraph();
	if (hist1d) plot_str = PlotTH1(hist1d, rootStyle_, options_.GetString());
	else if (hist2d) plot_str = PlotTH2(hist2d, rootStyle_, options_.GetString());
	else if (graph) plot_str = PlotTGraph(graph, rootStyle_, options_.GetString());
	size_t loc = plot_str.find_last_of("}") + 1;
	for (auto nodeInfo : nodes_) {
		plot_str.insert(loc, "\n\t\t" + NodeString(nodeInfo.first, nodeInfo.second));
	}

	std::ostream output(buf);
	output << plot_str;
}

std::string PgfPlotsPlot::NodeString(std::string nodeLabel, std::string nodeOptions) {
	std::stringstream output;

	output << "node";
	if (nodeOptions != "") {
		output << "[" << nodeOptions << "]";
	}

	output << " {" << nodeLabel << "}";

	return output.str();
}
<commit_msg>Updated histogram plotting and options.<commit_after>#include "PgfPlotsPlot.hpp"

#include <sstream>
#include <stdexcept>

PgfPlotsPlot::PgfPlotsPlot(const TH1* hist, const std::string &rootStyle,
                           const std::string &options)
	: obj_(hist), options_(options), rootStyle_(rootStyle)
{
	if (!hist) {
		throw std::runtime_error("ERROR: Null histogram pointer!");
	}
}

PgfPlotsPlot::PgfPlotsPlot(const TGraph* graph, const std::string &rootStyle,
	                        const std::string &options)
	: obj_(graph), options_(options), rootStyle_(rootStyle)
{
	if (!graph) {
		throw std::runtime_error("ERROR: Null histogram pointer!");
	}
}

void PgfPlotsPlot::AddNode(const std::string nodeLabel,
                           const std::string nodeOptions)
{
	nodes_.push_back(std::make_pair(nodeLabel, nodeOptions));
}

const TH1* PgfPlotsPlot::GetHist1d() {
	if (GetHist2d()) return nullptr;
	return dynamic_cast<const TH1*>(obj_);
}

/**
 * \param[in] hist Pointer to the histogram to be plotted.
 * \param[in] rootStyle The options to use when plotting the histogram. Currently
 *  supported:
 *    * ""   - Same as HIST below.
 *    * HIST - Draw just the histogram.
 * 	* E    - Draw error bars, show only the bars no markers or lines.
 * 	* E1   - Draw error bars with small lines at end and show markers.
 * \param[in] options Options to the pgfplots plot command.
 *
 * \return A string containing the pgfplots code to render the plot.
 */
std::string PgfPlotsPlot::PlotTH1(const TH1 *hist,
                                  const std::string &rootStyle,
                                  const std::string &options)
{
	//If this is a TH2 we want to call PlotTH2
	const TH2* h2 = dynamic_cast<const TH2*>(hist);
	if (h2) {
		return PlotTH2(h2, rootStyle, options);
	}

	bool includeErrors = false; //Include errors, shows only the error bars, no markers. ROOT option E.
	bool errorMarks = false; //Small lines are darwn at end of the error bars and markers are shown. ROOT option E1.
	bool histPlot = true; //Connect the point with a line
	if (rootStyle.find("E") != std::string::npos) includeErrors = true;
	if (rootStyle.find("E1") != std::string::npos) errorMarks = true;
	if (rootStyle != "" && rootStyle.find("HIST") == std::string::npos) histPlot = false;

	std::stringstream output;

	//Setup the plot style
	output << "\t\\addplot+[";

	if (histPlot) output << "const plot, ";
	//If the error option was indicated
	if (includeErrors) {
		// exclude markers if not requested.
		if (!errorMarks) output << "scatter, mark=none, ";
		//Remove the line connecting the points.
		if (!histPlot) output << "only marks, ";
		//Setup the error bars.
		output << "error bars/.cd, y dir=both, y explicit, x dir=both, x explicit";
		//Remove the edges (marks) at the end of the error bars.
		if (!errorMarks) output << ", error mark = none";
	}
	//Otherwise we use a const plot with no marks to show bins.
	else output << "no marks,\n";
	output << options;

	output << "\t]\n";

	//Begin the cooridnate list
	output << "\t\tcoordinates { ";

	//Add an initial coordinate to extend the left edge of the first bin to zero.
	if (!includeErrors) output << "(" << hist->GetBinLowEdge(1) << ",0) ";

	//Loop over every bin and add a corrdinate for it
	for (int xbin=1; xbin <= hist->GetNbinsX(); xbin++) {
		//Suppress the bins containing zero counts to speed up LaTeX rendering.
		if (errorMarks || (hist->GetBinContent(xbin) != 0 || hist->GetBinContent(xbin - 1) != 0)) {
			output << "(";
			if (includeErrors) output << hist->GetBinCenter(xbin);
			else output << hist->GetBinLowEdge(xbin);
			output << "," << hist->GetBinContent(xbin) << ") ";
			if (includeErrors) output << " +- (" << hist->GetBinWidth(xbin) / 2 <<
				"," << hist->GetBinError(xbin) << ") ";
		}
	}

	//Add a final coordinate to extend the right edge of the last bin to zero.
	if (!includeErrors && hist->GetBinContent(hist->GetNbinsX()) != 0) {
		output << "(" << hist->GetBinLowEdge(hist->GetNbinsX()) +
			hist->GetBinWidth(hist->GetNbinsX()) << "," << hist->GetBinContent(hist->GetNbinsX()) << ") ";
		output << "(" << hist->GetBinLowEdge(hist->GetNbinsX()) +
			hist->GetBinWidth(hist->GetNbinsX()) << "," << 0 << ") ";
	}

	//Coordinate list trailer.
	output << "};\n\n";

	return output.str();
}

/**
 * \param[in] graph Pointer to the graph to be plotted.
 * \param[in] rootStyle The options to use when plotting the graph. Currently
 *  supported:
 *    * "" - Default option is "PL".
 *    * P  - Draw points.
 *    * L  - Draw a connecting line.
 * \param[in] options Options to the pgfplots plot command.
 *
 * \return A string containing the pgfplots code to render the plot.
 */
std::string PgfPlotsPlot::PlotTGraph(const TGraph *graph,
                                     const std::string &rootStyle,
                                     const std::string &options)
{
	std::stringstream output;

	bool marks = false;
	bool lines = false;
	if (rootStyle == "") {
		marks = true;
		lines = true;
	}
	if (rootStyle.find("P") != std::string::npos) marks = true;
	if (rootStyle.find("L") != std::string::npos) lines = true;

	//Setup the plot style
	output << "\t\\addplot+[\n";
	if (!lines) output << "\t\t\tonly marks,\n";
	if (!marks) output << "\t\t\tmark=none,\n";
	output << options;

	output << "\t]\n";

	//Begin the cooridnate list
	output << "\t\tcoordinates { ";

	for (int point = 0; point < graph->GetN(); point++) {
		output << "(" << graph->GetX()[point] << ","
			<< graph->GetY()[point] << ") ";
	}

	//Coordinate list trailer.
	output << "};\n\n";

	return output.str();
}

/**By default creates a TikZ matrix plot which is typically used to plot values
 * in a matrix, but can be easily adapted to a two-dimensional histogram. A
 * matrix plot requires that all bins are defined, and thus the option
 * "restrict z to domain*" is used so that empty bins are set to the minimum
 * value. If the option "SURF" is provided a surface plot is created instead,
 * this type of plot requires data at the corners to be provided and thus plots
 * one less bin than is contained in the input histogram.
 *
 * \param[in] hist Pointer to the histogram to be plotted.
 * \param[in] rootStyle The options to use when plotting the histogram.
 * \param[in] options Options to the pgfplots plot command.
 */
std::string PgfPlotsPlot::PlotTH2(const TH2 *hist,
                                  const std::string &rootStyle,
                                  const std::string &options)
{
	bool surfPlot = false;
	if (rootStyle.find("SURF") != std::string::npos) {
		surfPlot = true;
	}

	std::stringstream output;

	output <<
		"\t\\addplot3[";
	if (surfPlot) output << "surf,";
	else output <<	"matrix plot*, \%Similar to `surf`.";
	output << "\n"
			"\t\tshader = flat corner, \n"
			"\t\topacity=ceil(\\pgfplotspointmetatransformed),\n"
			"\t\t\%Ordering of the coordinate data:\n"
			"\t\tmesh/cols=" << hist->GetNbinsX() << ", "
			"mesh/rows=" << hist->GetNbinsY() << ", "
			"mesh/ordering=rowwise,";
	output << options;
	output << "\t]\n"
		"\t\tcoordinates {\n";

	for (int ybin=1; ybin<= hist->GetNbinsY(); ybin++) {
		output << "\t\t\t";
		double yvalue;
		if (surfPlot) yvalue = hist->GetYaxis()->GetBinLowEdge(ybin);
		else yvalue = hist->GetYaxis()->GetBinCenter(ybin);
		for (int xbin=1; xbin<= hist->GetNbinsX(); xbin++) {
			double xvalue;
			if (surfPlot) xvalue = hist->GetXaxis()->GetBinLowEdge(xbin);
			else xvalue = hist->GetXaxis()->GetBinCenter(xbin);
			double weight = hist->GetBinContent(xbin, ybin);
			output << "(" << xvalue << "," << yvalue << "," << weight << ") ";
		}
		output << "\n";
	}

	//Coordinate list trailer.
	output << "\t\t};\n";

	return output.str();
}
void PgfPlotsPlot::Write(std::streambuf *buf) {
	std::string plot_str;
	auto hist1d = GetHist1d();
	auto hist2d = GetHist2d();
	auto graph = GetGraph();
	if (hist1d) plot_str = PlotTH1(hist1d, rootStyle_, options_.GetString());
	else if (hist2d) plot_str = PlotTH2(hist2d, rootStyle_, options_.GetString());
	else if (graph) plot_str = PlotTGraph(graph, rootStyle_, options_.GetString());
	size_t loc = plot_str.find_last_of("}") + 1;
	for (auto nodeInfo : nodes_) {
		plot_str.insert(loc, "\n\t\t" + NodeString(nodeInfo.first, nodeInfo.second));
	}

	std::ostream output(buf);
	output << plot_str;
}

std::string PgfPlotsPlot::NodeString(std::string nodeLabel, std::string nodeOptions) {
	std::stringstream output;

	output << "node";
	if (nodeOptions != "") {
		output << "[" << nodeOptions << "]";
	}

	output << " {" << nodeLabel << "}";

	return output.str();
}
<|endoftext|>


<commit_before>/*
* Curve25519
* (C) 2014 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/

#include <botan/curve25519.h>
#include <botan/internal/pk_ops_impl.h>
#include <botan/ber_dec.h>
#include <botan/der_enc.h>

namespace Botan {

void curve25519_basepoint(uint8_t mypublic[32], const uint8_t secret[32])
   {
   const uint8_t basepoint[32] = { 9 };
   curve25519_donna(mypublic, secret, basepoint);
   }

namespace {

void size_check(size_t size, const char* thing)
   {
   if(size != 32)
      throw Decoding_Error("Invalid size " + std::to_string(size) + " for Curve25519 " + thing);
   }

secure_vector<uint8_t> curve25519(const secure_vector<uint8_t>& secret,
                               const uint8_t pubval[32])
   {
   secure_vector<uint8_t> out(32);
   curve25519_donna(out.data(), secret.data(), pubval);
   return out;
   }

}

AlgorithmIdentifier Curve25519_PublicKey::algorithm_identifier() const
   {
   return AlgorithmIdentifier(get_oid(), AlgorithmIdentifier::USE_NULL_PARAM);
   }

bool Curve25519_PublicKey::check_key(RandomNumberGenerator&, bool) const
   {
   return true; // no tests possible?
   }

Curve25519_PublicKey::Curve25519_PublicKey(const AlgorithmIdentifier&,
                                           const std::vector<uint8_t>& key_bits)
   {
   BER_Decoder(key_bits)
      .start_cons(SEQUENCE)
      .decode(m_public, OCTET_STRING)
   .end_cons();

   size_check(m_public.size(), "public key");
   }

std::vector<uint8_t> Curve25519_PublicKey::public_key_bits() const
   {
   return DER_Encoder()
      .start_cons(SEQUENCE)
        .encode(m_public, OCTET_STRING)
      .end_cons()
      .get_contents_unlocked();
   }

Curve25519_PrivateKey::Curve25519_PrivateKey(RandomNumberGenerator& rng)
   {
   m_private = rng.random_vec(32);
   m_public.resize(32);
   curve25519_basepoint(m_public.data(), m_private.data());
   }

Curve25519_PrivateKey::Curve25519_PrivateKey(const AlgorithmIdentifier&,
                                             const secure_vector<uint8_t>& key_bits)
   {
   BER_Decoder(key_bits)
      .start_cons(SEQUENCE)
      .decode(m_public, OCTET_STRING)
      .decode(m_private, OCTET_STRING)
   .end_cons();

   size_check(m_public.size(), "public key");
   size_check(m_private.size(), "private key");
   }

secure_vector<uint8_t> Curve25519_PrivateKey::private_key_bits() const
   {
   return DER_Encoder()
      .start_cons(SEQUENCE)
        .encode(m_public, OCTET_STRING)
        .encode(m_private, OCTET_STRING)
      .end_cons()
      .get_contents();
   }

bool Curve25519_PrivateKey::check_key(RandomNumberGenerator&, bool) const
   {
   std::vector<uint8_t> public_point(32);
   curve25519_basepoint(public_point.data(), m_private.data());
   return public_point == m_public;
   }

secure_vector<uint8_t> Curve25519_PrivateKey::agree(const uint8_t w[], size_t w_len) const
   {
   size_check(w_len, "public value");
   return curve25519(m_private, w);
   }

namespace {

/**
* Curve25519 operation
*/
class Curve25519_KA_Operation : public PK_Ops::Key_Agreement_with_KDF
   {
   public:

      Curve25519_KA_Operation(const Curve25519_PrivateKey& key, const std::string& kdf) :
         PK_Ops::Key_Agreement_with_KDF(kdf),
         m_key(key) {}

      secure_vector<uint8_t> raw_agree(const uint8_t w[], size_t w_len) override
         {
         return m_key.agree(w, w_len);
         }
   private:
      const Curve25519_PrivateKey& m_key;
   };

}

std::unique_ptr<PK_Ops::Key_Agreement>
Curve25519_PrivateKey::create_key_agreement_op(RandomNumberGenerator& /*rng*/,
                                               const std::string& params,
                                               const std::string& provider) const
   {
   if(provider == "base" || provider.empty())
      return std::unique_ptr<PK_Ops::Key_Agreement>(new Curve25519_KA_Operation(*this, params));
   throw Provider_Not_Found(algo_name(), provider);
   }

}
<commit_msg>Added Curve25519_PrivateKey constructor from secret_key<commit_after>/*
* Curve25519
* (C) 2014 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/

#include <botan/curve25519.h>
#include <botan/internal/pk_ops_impl.h>
#include <botan/ber_dec.h>
#include <botan/der_enc.h>

namespace Botan {

void curve25519_basepoint(uint8_t mypublic[32], const uint8_t secret[32])
   {
   const uint8_t basepoint[32] = { 9 };
   curve25519_donna(mypublic, secret, basepoint);
   }

namespace {

void size_check(size_t size, const char* thing)
   {
   if(size != 32)
      throw Decoding_Error("Invalid size " + std::to_string(size) + " for Curve25519 " + thing);
   }

secure_vector<uint8_t> curve25519(const secure_vector<uint8_t>& secret,
                               const uint8_t pubval[32])
   {
   secure_vector<uint8_t> out(32);
   curve25519_donna(out.data(), secret.data(), pubval);
   return out;
   }

}

AlgorithmIdentifier Curve25519_PublicKey::algorithm_identifier() const
   {
   return AlgorithmIdentifier(get_oid(), AlgorithmIdentifier::USE_NULL_PARAM);
   }

bool Curve25519_PublicKey::check_key(RandomNumberGenerator&, bool) const
   {
   return true; // no tests possible?
   }

Curve25519_PublicKey::Curve25519_PublicKey(const AlgorithmIdentifier&,
                                           const std::vector<uint8_t>& key_bits)
   {
   BER_Decoder(key_bits)
      .start_cons(SEQUENCE)
      .decode(m_public, OCTET_STRING)
   .end_cons();

   size_check(m_public.size(), "public key");
   }

std::vector<uint8_t> Curve25519_PublicKey::public_key_bits() const
   {
   return DER_Encoder()
      .start_cons(SEQUENCE)
        .encode(m_public, OCTET_STRING)
      .end_cons()
      .get_contents_unlocked();
   }

Curve25519_PrivateKey::Curve25519_PrivateKey(const secure_vector<uint8_t>& secret_key)
   {
   if(secret_key.size() == 32)
      {
      m_public.resize(32);
      m_private = secret_key;
      curve25519_basepoint(m_public.data(), m_private.data());
      }
   else
     throw Decoding_Error("Invalid size for Curve25519 private key");
   }

Curve25519_PrivateKey::Curve25519_PrivateKey(RandomNumberGenerator& rng)
   {
   m_private = rng.random_vec(32);
   m_public.resize(32);
   curve25519_basepoint(m_public.data(), m_private.data());
   }

Curve25519_PrivateKey::Curve25519_PrivateKey(const AlgorithmIdentifier&,
                                             const secure_vector<uint8_t>& key_bits)
   {
   BER_Decoder(key_bits)
      .start_cons(SEQUENCE)
      .decode(m_public, OCTET_STRING)
      .decode(m_private, OCTET_STRING)
   .end_cons();

   size_check(m_public.size(), "public key");
   size_check(m_private.size(), "private key");
   }

secure_vector<uint8_t> Curve25519_PrivateKey::private_key_bits() const
   {
   return DER_Encoder()
      .start_cons(SEQUENCE)
        .encode(m_public, OCTET_STRING)
        .encode(m_private, OCTET_STRING)
      .end_cons()
      .get_contents();
   }

bool Curve25519_PrivateKey::check_key(RandomNumberGenerator&, bool) const
   {
   std::vector<uint8_t> public_point(32);
   curve25519_basepoint(public_point.data(), m_private.data());
   return public_point == m_public;
   }

secure_vector<uint8_t> Curve25519_PrivateKey::agree(const uint8_t w[], size_t w_len) const
   {
   size_check(w_len, "public value");
   return curve25519(m_private, w);
   }

namespace {

/**
* Curve25519 operation
*/
class Curve25519_KA_Operation : public PK_Ops::Key_Agreement_with_KDF
   {
   public:

      Curve25519_KA_Operation(const Curve25519_PrivateKey& key, const std::string& kdf) :
         PK_Ops::Key_Agreement_with_KDF(kdf),
         m_key(key) {}

      secure_vector<uint8_t> raw_agree(const uint8_t w[], size_t w_len) override
         {
         return m_key.agree(w, w_len);
         }
   private:
      const Curve25519_PrivateKey& m_key;
   };

}

std::unique_ptr<PK_Ops::Key_Agreement>
Curve25519_PrivateKey::create_key_agreement_op(RandomNumberGenerator& /*rng*/,
                                               const std::string& params,
                                               const std::string& provider) const
   {
   if(provider == "base" || provider.empty())
      return std::unique_ptr<PK_Ops::Key_Agreement>(new Curve25519_KA_Operation(*this, params));
   throw Provider_Not_Found(algo_name(), provider);
   }

}
<|endoftext|>


<commit_before>#include <stdlib.h>

#define BOOST_TEST_MODULE watcher::Message.LabelMessage test
#include <boost/test/unit_test.hpp>

#include <boost/archive/polymorphic_text_iarchive.hpp>
#include <boost/archive/polymorphic_text_oarchive.hpp>
#include <boost/archive/polymorphic_binary_iarchive.hpp>
#include <boost/archive/polymorphic_binary_oarchive.hpp>

#include <boost/serialization/shared_ptr.hpp>  // Need this to serialize shared_ptrs.

#include <libwatcher/labelMessage.h>
#include "logger.h"

using namespace std;
using namespace boost;
using namespace watcher;
using namespace watcher::event;
using namespace boost::unit_test_framework;

BOOST_AUTO_TEST_CASE( ctor_test )
{
    LOAD_LOG_PROPS("log.properties");

    LabelMessage lm1;
    lm1.label="Hello world";
    lm1.fontSize=60;
    lm1.address=asio::ip::address_v4((0x7f000001));   // 127.0.0.1
    lm1.foreground=Color::black;
    lm1.background=Color::white;
    lm1.expiration=10;
    lm1.addLabel=true;

    LOG_INFO("Testing operator=()...");
    LabelMessage lm2;
    lm2=lm1;
    LOG_DEBUG("lm1 :" << lm1);
    LOG_DEBUG("lm2 :" << lm2);
    BOOST_CHECK_EQUAL(lm1,lm2);

    LOG_INFO("Testing copy constructor...");
    LabelMessage lm3(lm1);
    LOG_DEBUG("lm1 :" << lm1);
    LOG_DEBUG("lm3 :" << lm3);
    BOOST_CHECK_EQUAL(lm1,lm3);

    LabelMessage withGPS("This label is floating in space!", 0.123, 0.123, 0.123);
    LabelMessage copy(withGPS);
    LOG_DEBUG("gps :" << withGPS);
    LOG_DEBUG("cpy :" << copy);
    BOOST_CHECK_EQUAL(withGPS, copy);

}

BOOST_AUTO_TEST_CASE( archive_test )
{
    LOG_INFO("Testing LabelMessage archiving...");

    LabelMessage lmOut;;

    lmOut.label="Hello world";
    lmOut.fontSize=60;
    lmOut.address=asio::ip::address::from_string("127.0.0.1");
    lmOut.foreground=Color::black;
    lmOut.background=Color::white;
    lmOut.expiration=10;
    lmOut.addLabel=false;       // Normally you would not mix address, and (lat,lng, alt), but
    lmOut.lat=1.23456789;       // for testing it's ok.
    lmOut.lng=1.23456789;
    lmOut.alt=1.23456789;

    LOG_INFO("Serializing: " << lmOut);
    ostringstream os1;
    archive::polymorphic_text_oarchive oa1(os1);
    oa1 << lmOut;

    LOG_INFO("Serialized lmOut: " << os1.str());

    LabelMessage lmIn;
    istringstream is1(os1.str());
    archive::polymorphic_text_iarchive ia1(is1);
    ia1 >> lmIn;

    LOG_INFO( "Checking text archiving..." );
    LOG_DEBUG("Comparing these two messages:");
    LOG_DEBUG("lmOut :" << lmOut);
    LOG_DEBUG("lmIn :" << lmIn);

    BOOST_CHECK_EQUAL( lmOut, lmIn );

    ostringstream os2;
    archive::polymorphic_binary_oarchive oa2(os2);
    oa2 << lmOut;

    istringstream is2(os2.str());
    archive::polymorphic_binary_iarchive ia2(is2);
    ia2 >> lmIn;

    LOG_INFO( "Checking binary archiving..." );
    BOOST_CHECK_EQUAL( lmOut, lmIn );
}

BOOST_AUTO_TEST_CASE( output_test )
{
    LOG_INFO("Testing LabelMessage archiving...");

    LabelMessagePtr lmp1 = LabelMessagePtr(new LabelMessage);

    lmp1->label="Hello world";
    lmp1->fontSize=60;
    lmp1->address=boost::asio::ip::address::from_string("127.0.0.1");
    lmp1->foreground=Color::black;
    lmp1->background=Color::white;
    lmp1->expiration=10;

    LOG_DEBUG("*lmp1 :" << *lmp1);

    LabelMessage lm1 = *lmp1;

    LOG_FATAL("To do: finish writing output unit test");
    // Althought testing against the timestamp string will be tricky.

}

<commit_msg>testLabelMessage: test archiving via shared_ptrs. (it works)<commit_after>#include <stdlib.h>

#define BOOST_TEST_MODULE watcher::Message.LabelMessage test
#include <boost/test/unit_test.hpp>

#include <boost/archive/polymorphic_text_iarchive.hpp>
#include <boost/archive/polymorphic_text_oarchive.hpp>
#include <boost/archive/polymorphic_binary_iarchive.hpp>
#include <boost/archive/polymorphic_binary_oarchive.hpp>

#include <boost/serialization/shared_ptr.hpp>  // Need this to serialize shared_ptrs.

#include <libwatcher/labelMessage.h>
#include "logger.h"

using namespace std;
using namespace boost;
using namespace watcher;
using namespace watcher::event;
using namespace boost::unit_test_framework;

BOOST_AUTO_TEST_CASE( ctor_test )
{
    LOAD_LOG_PROPS("log.properties");

    LabelMessage lm1;
    lm1.label="Hello world";
    lm1.fontSize=60;
    lm1.address=asio::ip::address_v4((0x7f000001));   // 127.0.0.1
    lm1.foreground=Color::black;
    lm1.background=Color::white;
    lm1.expiration=10;
    lm1.addLabel=true;

    LOG_INFO("Testing operator=()...");
    LabelMessage lm2;
    lm2=lm1;
    LOG_DEBUG("lm1 :" << lm1);
    LOG_DEBUG("lm2 :" << lm2);
    BOOST_CHECK_EQUAL(lm1,lm2);

    LOG_INFO("Testing copy constructor...");
    LabelMessage lm3(lm1);
    LOG_DEBUG("lm1 :" << lm1);
    LOG_DEBUG("lm3 :" << lm3);
    BOOST_CHECK_EQUAL(lm1,lm3);

    LabelMessage withGPS("This label is floating in space!", 0.123, 0.123, 0.123);
    LabelMessage copy(withGPS);
    LOG_DEBUG("gps :" << withGPS);
    LOG_DEBUG("cpy :" << copy);
    BOOST_CHECK_EQUAL(withGPS, copy);

}

BOOST_AUTO_TEST_CASE( archive_test )
{
    LOG_INFO("Testing LabelMessage archiving...");

    LabelMessage lmOut;;

    lmOut.label="Hello world";
    lmOut.fontSize=60;
    lmOut.address=asio::ip::address::from_string("127.0.0.1");
    lmOut.foreground=Color::black;
    lmOut.background=Color::white;
    lmOut.expiration=10;
    lmOut.addLabel=false;       // Normally you would not mix address, and (lat,lng, alt), but
    lmOut.lat=1.23456789;       // for testing it's ok.
    lmOut.lng=1.23456789;
    lmOut.alt=1.23456789;

    LOG_INFO("Serializing: " << lmOut);
    ostringstream os1;
    archive::polymorphic_text_oarchive oa1(os1);
    oa1 << lmOut;

    LOG_INFO("Serialized lmOut: " << os1.str());

    LabelMessage lmIn;
    istringstream is1(os1.str());
    archive::polymorphic_text_iarchive ia1(is1);
    ia1 >> lmIn;

    LOG_INFO( "Checking text archiving..." );
    LOG_DEBUG("Comparing these two messages:");
    LOG_DEBUG("lmOut :" << lmOut);
    LOG_DEBUG("lmIn :" << lmIn);

    BOOST_CHECK_EQUAL( lmOut, lmIn );

    ostringstream os2;
    archive::polymorphic_binary_oarchive oa2(os2);
    oa2 << lmOut;

    istringstream is2(os2.str());
    archive::polymorphic_binary_iarchive ia2(is2);
    ia2 >> lmIn;

    LOG_INFO( "Checking binary archiving..." );
    BOOST_CHECK_EQUAL( lmOut, lmIn );

    LOG_INFO("Checking shared_ptr archiving");

    LabelMessagePtr lmp(new LabelMessage("THis is a shared_ptr labelMessage"));
    ostringstream os3;
    archive::polymorphic_binary_oarchive oa3(os3);
    oa3 << lmp;

    LabelMessagePtr lmp2;
    istringstream is3(os3.str());
    archive::polymorphic_binary_iarchive ia3(is3);
    ia3 >> lmp2;

    LOG_INFO("Checking equality of archived data via shared_ptrs...");
    LOG_DEBUG("*lmp: " << *lmp);
    LOG_DEBUG("*lmp2: " << *lmp2);
    BOOST_CHECK_EQUAL( *lmp, *lmp2 );
}

BOOST_AUTO_TEST_CASE( output_test )
{
    LOG_INFO("Testing LabelMessage archiving...");

    LabelMessagePtr lmp1 = LabelMessagePtr(new LabelMessage);

    lmp1->label="Hello world";
    lmp1->fontSize=60;
    lmp1->address=boost::asio::ip::address::from_string("127.0.0.1");
    lmp1->foreground=Color::black;
    lmp1->background=Color::white;
    lmp1->expiration=10;

    LOG_DEBUG("*lmp1 :" << *lmp1);

    LabelMessage lm1 = *lmp1;

    LOG_FATAL("To do: finish writing output unit test");
    // Althought testing against the timestamp string will be tricky.

}

<|endoftext|>


<commit_before>/*
 * Copyright (c) 2012 Stanford University
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR(S) DISCLAIM ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL AUTHORS BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#define _POSIX_C_SOURCE 200809

#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <time.h>

#include <unistd.h>
#include <sys/param.h>
#include <sys/types.h>
#include <sys/time.h>

#ifdef __MACH__
#include <mach/mach.h>
#include <mach/clock.h>
#endif

#include <string>

using namespace std;

#include "debug.h"
#include "repo.h"

/********************************************************************
 *
 *
 * Command Infrastructure
 *
 *
 ********************************************************************/

typedef struct Cmd {
    const char *name;
    const char *desc;
    int (*cmd)(int argc, const char *argv[]);
    void (*usage)(void);
} Cmd;

// repo.cc
int cmd_init(int argc, const char *argv[]);
int cmd_show(int argc, const char *argv[]);
int cmd_clone(int argc, const char *argv[]);
void usage_commit(void);
int cmd_commit(int argc, const char *argv[]);
int cmd_checkout(int argc, const char *argv[]);
int cmd_pull(int argc, const char *argv[]);
int cmd_status(int argc, const char *argv[]);
int cmd_log(int argc, const char *argv[]);
int cmd_verify(int argc, const char *argv[]);
int cmd_catobj(int argc, const char *argv[]); // Debug
int cmd_listobj(int argc, const char *argv[]); // Debug
int cmd_refcount(int argc, const char *argv[]); // Debug
int cmd_purgeobj(int argc, const char *argv[]); // Debug
void usage_graft(void);
int cmd_graft(int argc, const char *argv[]);
// local
static int cmd_help(int argc, const char *argv[]);
static int cmd_selftest(int argc, const char *argv[]);

static Cmd commands[] = {
    {
        "init",
        "Initialize the repository",
        cmd_init,
        NULL,
    },
    {
        "show",
        "Show repository information",
        cmd_show,
        NULL,
    },
    {
        "status",
        "Scan for changes since last commit",
        cmd_status,
        NULL,
    },
    {
	"clone",
	"Clone a repository into the local directory",
	cmd_clone,
	NULL,
    },
    {
	"commit",
	"Commit changes into the repository",
	cmd_commit,
	usage_commit,
    },
    {
	"checkout",
	"Checkout a revision of the repository",
	cmd_checkout,
	NULL,
    },
    {
	"pull",
	"Pull changes from a repository",
	cmd_pull,
	NULL,
    },
    {
	"log",
	"Display a log of commits to the repository",
	cmd_log,
	NULL,
    },
    {
	"verify",
	"Verify the repository",
	cmd_verify,
	NULL,
    },
    {
	"graft",
	"Graft a subtree from a repository into the local repository",
	cmd_graft,
	usage_graft,
    },
    /* Debugging */
    {
	"catobj",
	"Print an object from the repository (DEBUG)",
	cmd_catobj,
	NULL,
    },
    {
	"listobj",
	"List objects (DEBUG)",
	cmd_listobj,
	NULL,
    },
    {
	"refcount",
	"Print the reference count for all objects (DEBUG)",
	cmd_refcount,
	NULL,
    },
    {
	"purgeobj",
	"Purge object (DEBUG)",
	cmd_purgeobj,
	NULL,
    },
    {
        "help",
        "Show help for a given topic",
        cmd_help,
        NULL
    },
    {
        "selftest",
        "Built-in unit tests (DEBUG)",
        cmd_selftest,
        NULL
    },
    { NULL, NULL, NULL, NULL }
};

static int
lookupcmd(const char *cmd)
{
    int i;

    for (i = 0; commands[i].name != NULL; i++)
    {
        if (strcmp(commands[i].name, cmd) == 0)
            return i;
    }

    return -1;
}

/********************************************************************
 *
 *
 * Logging
 *
 *
 ********************************************************************/

static int logfd = -1;

void
get_timespec(struct timespec *ts)
{
#ifdef __MACH__
    clock_serv_t clk;
    mach_timespec_t mts;
    host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &clk);
    clock_get_time(clk, &mts);
    mach_port_deallocate(mach_task_self(), clk);
    ts->tv_sec = mts.tv_sec;
    ts->tv_nsec = mts.tv_nsec;
#else
    clock_gettime(CLOCK_REALTIME, ts);
#endif
}

void
ori_log(const char *fmt, ...)
{
    va_list ap;
    struct timespec ts;
    char buf[32];

    if (logfd == -1)
        return;

    get_timespec(&ts);
    strftime(buf, 32, "%Y-%m-%d %H:%M:%S ", localtime(&ts.tv_sec));
    dprintf(logfd, "%s", buf);

    va_start(ap, fmt);
    vdprintf(logfd, fmt, ap);
    va_end(ap);

    // XXX: May cause performance issues disable on release builds
    fsync(logfd);
}

int util_selftest(void);

static int
cmd_selftest(int argc, const char *argv[])
{
    util_selftest();

    return 0;
}

static int
cmd_help(int argc, const char *argv[])
{
    int i = 0;

    if (argc >= 2) {
        i = lookupcmd(argv[1]);
        if (i != -1 && commands[i].usage != NULL) {
            commands[i].usage();
            return 0;
        }
        if (i == -1) {
            printf("Unknown command '%s'\n", argv[1]);
        } else {
            printf("No help for command '%s'\n", argv[1]);
            return 0;
        }
    }

    for (i = 0; commands[i].name != NULL; i++)
    {
        if (commands[i].desc != NULL)
            printf("%-20s %s\n", commands[i].name, commands[i].desc);
    }

    return 0;
}

int
main(int argc, char *argv[])
{
    int idx;
    string logPath = Repo::getLogPath();

    if (logPath.compare("") != 0) {
        logfd = open(logPath.c_str(), O_CREAT|O_WRONLY|O_APPEND, 0660);
        if (logfd == -1) {
            perror("open");
            return 1;
        }
    } else {
        logfd = -1;
    }

    if (argc == 1) {
        return cmd_help(0, NULL);
    }

    // Open the repository for all command except the following
    if (strcmp(argv[1], "clone") != 0 &&
        strcmp(argv[1], "help") != 0 &&
        strcmp(argv[1], "init") != 0 &&
        strcmp(argv[1], "selftest") != 0 &&
        strcmp(argv[1], "sshserver"))
    {
        if (!repository.open()) {
            printf("No repository found!\n");
            exit(1);
        }
    }

    idx = lookupcmd(argv[1]);
    if (idx == -1) {
        printf("Unknown command '%s'\n", argv[1]);
        cmd_help(0, NULL);
        return 1;
    }

    LOG("Executing '%s'", argv[1]);
    commands[idx].cmd(argc-1, (const char **)argv+1);

    return 0;
}

<commit_msg>Reorder help message.<commit_after>/*
 * Copyright (c) 2012 Stanford University
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR(S) DISCLAIM ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL AUTHORS BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#define _POSIX_C_SOURCE 200809

#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <time.h>

#include <unistd.h>
#include <sys/param.h>
#include <sys/types.h>
#include <sys/time.h>

#ifdef __MACH__
#include <mach/mach.h>
#include <mach/clock.h>
#endif

#include <string>

using namespace std;

#include "debug.h"
#include "repo.h"

/********************************************************************
 *
 *
 * Command Infrastructure
 *
 *
 ********************************************************************/

typedef struct Cmd {
    const char *name;
    const char *desc;
    int (*cmd)(int argc, const char *argv[]);
    void (*usage)(void);
} Cmd;

// repo.cc
int cmd_init(int argc, const char *argv[]);
int cmd_show(int argc, const char *argv[]);
int cmd_clone(int argc, const char *argv[]);
void usage_commit(void);
int cmd_commit(int argc, const char *argv[]);
int cmd_checkout(int argc, const char *argv[]);
int cmd_pull(int argc, const char *argv[]);
int cmd_status(int argc, const char *argv[]);
int cmd_log(int argc, const char *argv[]);
int cmd_verify(int argc, const char *argv[]);
void usage_graft(void);
int cmd_graft(int argc, const char *argv[]);
int cmd_catobj(int argc, const char *argv[]); // Debug
int cmd_listobj(int argc, const char *argv[]); // Debug
int cmd_refcount(int argc, const char *argv[]); // Debug
int cmd_purgeobj(int argc, const char *argv[]); // Debug
// local
static int cmd_help(int argc, const char *argv[]);
static int cmd_selftest(int argc, const char *argv[]);

static Cmd commands[] = {
    {
        "init",
        "Initialize the repository",
        cmd_init,
        NULL,
    },
    {
        "show",
        "Show repository information",
        cmd_show,
        NULL,
    },
    {
        "status",
        "Scan for changes since last commit",
        cmd_status,
        NULL,
    },
    {
	"clone",
	"Clone a repository into the local directory",
	cmd_clone,
	NULL,
    },
    {
	"commit",
	"Commit changes into the repository",
	cmd_commit,
	usage_commit,
    },
    {
	"checkout",
	"Checkout a revision of the repository",
	cmd_checkout,
	NULL,
    },
    {
	"pull",
	"Pull changes from a repository",
	cmd_pull,
	NULL,
    },
    {
	"log",
	"Display a log of commits to the repository",
	cmd_log,
	NULL,
    },
    {
	"verify",
	"Verify the repository",
	cmd_verify,
	NULL,
    },
    {
	"graft",
	"Graft a subtree from a repository into the local repository",
	cmd_graft,
	usage_graft,
    },
    /* Debugging */
    {
	"catobj",
	"Print an object from the repository (DEBUG)",
	cmd_catobj,
	NULL,
    },
    {
	"listobj",
	"List objects (DEBUG)",
	cmd_listobj,
	NULL,
    },
    {
	"refcount",
	"Print the reference count for all objects (DEBUG)",
	cmd_refcount,
	NULL,
    },
    {
	"purgeobj",
	"Purge object (DEBUG)",
	cmd_purgeobj,
	NULL,
    },
    {
        "selftest",
        "Built-in unit tests (DEBUG)",
        cmd_selftest,
        NULL
    },
    {
        "help",
        "Show help for a given topic",
        cmd_help,
        NULL
    },
    { NULL, NULL, NULL, NULL }
};

static int
lookupcmd(const char *cmd)
{
    int i;

    for (i = 0; commands[i].name != NULL; i++)
    {
        if (strcmp(commands[i].name, cmd) == 0)
            return i;
    }

    return -1;
}

/********************************************************************
 *
 *
 * Logging
 *
 *
 ********************************************************************/

static int logfd = -1;

void
get_timespec(struct timespec *ts)
{
#ifdef __MACH__
    clock_serv_t clk;
    mach_timespec_t mts;
    host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &clk);
    clock_get_time(clk, &mts);
    mach_port_deallocate(mach_task_self(), clk);
    ts->tv_sec = mts.tv_sec;
    ts->tv_nsec = mts.tv_nsec;
#else
    clock_gettime(CLOCK_REALTIME, ts);
#endif
}

void
ori_log(const char *fmt, ...)
{
    va_list ap;
    struct timespec ts;
    char buf[32];

    if (logfd == -1)
        return;

    get_timespec(&ts);
    strftime(buf, 32, "%Y-%m-%d %H:%M:%S ", localtime(&ts.tv_sec));
    dprintf(logfd, "%s", buf);

    va_start(ap, fmt);
    vdprintf(logfd, fmt, ap);
    va_end(ap);

    // XXX: May cause performance issues disable on release builds
    fsync(logfd);
}

int util_selftest(void);

static int
cmd_selftest(int argc, const char *argv[])
{
    util_selftest();

    return 0;
}

static int
cmd_help(int argc, const char *argv[])
{
    int i = 0;

    if (argc >= 2) {
        i = lookupcmd(argv[1]);
        if (i != -1 && commands[i].usage != NULL) {
            commands[i].usage();
            return 0;
        }
        if (i == -1) {
            printf("Unknown command '%s'\n", argv[1]);
        } else {
            printf("No help for command '%s'\n", argv[1]);
            return 0;
        }
    }

    for (i = 0; commands[i].name != NULL; i++)
    {
        if (commands[i].desc != NULL)
            printf("%-20s %s\n", commands[i].name, commands[i].desc);
    }

    return 0;
}

int
main(int argc, char *argv[])
{
    int idx;
    string logPath = Repo::getLogPath();

    if (logPath.compare("") != 0) {
        logfd = open(logPath.c_str(), O_CREAT|O_WRONLY|O_APPEND, 0660);
        if (logfd == -1) {
            perror("open");
            return 1;
        }
    } else {
        logfd = -1;
    }

    if (argc == 1) {
        return cmd_help(0, NULL);
    }

    // Open the repository for all command except the following
    if (strcmp(argv[1], "clone") != 0 &&
        strcmp(argv[1], "help") != 0 &&
        strcmp(argv[1], "init") != 0 &&
        strcmp(argv[1], "selftest") != 0 &&
        strcmp(argv[1], "sshserver"))
    {
        if (!repository.open()) {
            printf("No repository found!\n");
            exit(1);
        }
    }

    idx = lookupcmd(argv[1]);
    if (idx == -1) {
        printf("Unknown command '%s'\n", argv[1]);
        cmd_help(0, NULL);
        return 1;
    }

    LOG("Executing '%s'", argv[1]);
    commands[idx].cmd(argc-1, (const char **)argv+1);

    return 0;
}

<|endoftext|>


<commit_before>#include <core/mat4.h>
#include "core/draw.h"
#include "core/random.h"
#include "core/shufflebag.h"
#include "core/filesystem.h"
#include "core/mat4.h"
#include "core/axisangle.h"
#include "core/aabb.h"
#include "core/texturetypes.h"
#include "core/filesystemimagegenerator.h"
#include "core/path.h"
#include "core/os.h"
#include "core/range.h"
#include "core/camera.h"
#include "core/stringutils.h"
#include "core/stdutils.h"

#include <render/init.h>
#include <render/debuggl.h>
#include <render/materialshader.h>
#include <render/compiledmesh.h>
#include <render/texturecache.h>
#include "render/shaderattribute3d.h"
#include "render/texture.h"
#include "render/world.h"
#include "render/viewport.h"
#include "render/materialshadercache.h"
#include "render/defaultfiles.h"

#include "window/imguilibrary.h"
#include "window/timer.h"
#include "window/imgui_ext.h"
#include "window/fpscontroller.h"
#include "window/sdllibrary.h"
#include "window/sdlwindow.h"
#include "window/sdlglcontext.h"
#include "window/filesystem.h"

#include "editor/browser.h"
#include "editor/scimed.h"

#include "imgui/imgui.h"
#include <SDL.h>
#include <iostream>
#include <memory>

ImVec2
operator+(const ImVec2& lhs, const ImVec2& rhs)
{
  return ImVec2{lhs.x + rhs.x, lhs.y + rhs.y};
}

struct StyleData
{
  ScimedConfig scc = ScimedConfig{};
  CanvasConfig cc  = CanvasConfig{};
};

struct GenericWindow
{
  std::string name;
  bool        open = true;

  virtual void
  Run(StyleData* style_data) = 0;
};

template <typename CreateWindowFunction>
void
OpenOrFocusWindow(
    std::vector<std::shared_ptr<GenericWindow>>* windows,
    const std::string&                           title_name,
    CreateWindowFunction                         create_window_function)
{
  const auto found =
      Search(*windows, [&](std::shared_ptr<GenericWindow>& wind) -> bool {
        return wind->name == title_name;
      });

  if(found == windows->end())
  {
    auto the_window  = create_window_function();
    the_window->name = title_name;
    windows->emplace_back(the_window);
  }
  else
  {
    ImGui::SetNextWindowFocus();
    ImGui::Begin(title_name.c_str());
    ImGui::End();
  }
}

struct ScimedWindow : public GenericWindow
{
  Scimed scimed;

  void
  Run(StyleData* style_data) override
  {
    scimed.Run(style_data->cc, style_data->scc);
  }
};

struct StyleEditorWindow : GenericWindow
{
  ImVec4 color;

  void
  Run(StyleData* s) override
  {
    ImGui::ColorEdit4("Color", &color.x);
  }
};

void
OpenOrFocusStyleEditor(std::vector<std::shared_ptr<GenericWindow>>* windows)
{
  OpenOrFocusWindow(windows, "Style editor", []() {
    return std::make_shared<StyleEditorWindow>();
  });
}

int
main(int argc, char** argv)
{
  SdlLibrary sdl;
  if(sdl.ok == false)
  {
    return -1;
  }

  int width  = 1280;
  int height = 720;

  SdlWindow window{"Euphoria Demo", width, height};
  if(window.window == nullptr)
  {
    return -1;
  }

  SdlGlContext context{&window};

  if(context.context == nullptr)
  {
    return -1;
  }

  Init init{SDL_GL_GetProcAddress};
  if(init.ok == false)
  {
    return -4;
  }

  SetupOpenglDebug();

  const auto current_directory = GetCurrentDirectory();
  const auto base_path         = GetBasePath();
  const auto pref_path         = GetPrefPath();

  ImguiLibrary imgui{window.window, pref_path};
  ImGui::StyleColorsLight();

  Viewport viewport{
      Recti::FromWidthHeight(width, height).SetBottomLeftToCopy(0, 0)};
  viewport.Activate();

  FileSystem file_system;
  auto       catalog = FileSystemRootCatalog::AddRoot(&file_system);

  FileSystemRootFolder::AddRoot(&file_system, current_directory);
  FileSystemImageGenerator::AddRoot(&file_system, "img-plain");

  SetupDefaultFiles(catalog);

  TextureCache texture_cache{&file_system};

  bool running = true;

  FileBrowser browser{&file_system};
  browser.Refresh();
  std::vector<std::shared_ptr<GenericWindow>> scimeds;
  StyleData                                   style_data = StyleData{};

  OpenOrFocusStyleEditor(&scimeds);

  while(running)
  {
    SDL_Event e;
    while(SDL_PollEvent(&e) != 0)
    {
      imgui.ProcessEvents(&e);

      switch(e.type)
      {
        case SDL_QUIT:
          running = false;
          break;
        default:
          // ignore other events
          break;
      }
    }

    imgui.StartNewFrame();

    if(ImGui::BeginMainMenuBar())
    {
      if(ImGui::BeginMenu("File"))
      {
        if(ImGui::MenuItem("Exit", "Ctrl+Q"))
        {
          running = false;
        }
        if(ImGui::MenuItem("Style editor"))
        {
          OpenOrFocusStyleEditor(&scimeds);
        }
        ImGui::EndMenu();
      }

      if(ImGui::BeginMenu("Window"))
      {
        for(const auto& window : scimeds)
        {
          if(ImGui::MenuItem(window->name.c_str()))
          {
            ImGui::SetNextWindowFocus();
            ImGui::Begin(window->name.c_str());
            ImGui::End();
          }
        }

        ImGui::EndMenu();
      }
    }
    ImGui::EndMainMenuBar();

    if(ImGui::Begin("Solution explorer"))
    {
      if(browser.Run())
      {
        const auto file = browser.GetSelectedFile();

        OpenOrFocusWindow(
            &scimeds,
            Str{} << "Scimed: " << file,
            [&]() -> std::shared_ptr<GenericWindow> {
              auto scimed = std::make_shared<ScimedWindow>();
              scimed->scimed.LoadFile(&texture_cache, &file_system, file);
              return scimed;
            });
      }
    }
    ImGui::End();

    for(auto& scimed : scimeds)
    {
      ImGui::SetNextWindowSize(ImVec2{300, 300}, ImGuiCond_FirstUseEver);
      if(ImGui::Begin(scimed->name.c_str(), &scimed->open))
      {
        scimed->Run(&style_data);
      }
      ImGui::End();
    }

    // ImGui::ShowMetricsWindow();

    init.ClearScreen(Color::Wheat);
    imgui.Render();

    RemoveMatching(&scimeds, [](const std::shared_ptr<GenericWindow>& window) {
      return !window->open;
    });

    SDL_GL_SwapWindow(window.window);
  }

  return 0;
}
<commit_msg>style editor working<commit_after>#include <core/mat4.h>
#include "core/draw.h"
#include "core/random.h"
#include "core/shufflebag.h"
#include "core/filesystem.h"
#include "core/mat4.h"
#include "core/axisangle.h"
#include "core/aabb.h"
#include "core/texturetypes.h"
#include "core/filesystemimagegenerator.h"
#include "core/path.h"
#include "core/os.h"
#include "core/range.h"
#include "core/camera.h"
#include "core/stringutils.h"
#include "core/stdutils.h"

#include <render/init.h>
#include <render/debuggl.h>
#include <render/materialshader.h>
#include <render/compiledmesh.h>
#include <render/texturecache.h>
#include "render/shaderattribute3d.h"
#include "render/texture.h"
#include "render/world.h"
#include "render/viewport.h"
#include "render/materialshadercache.h"
#include "render/defaultfiles.h"

#include "window/imguilibrary.h"
#include "window/timer.h"
#include "window/imgui_ext.h"
#include "window/fpscontroller.h"
#include "window/sdllibrary.h"
#include "window/sdlwindow.h"
#include "window/sdlglcontext.h"
#include "window/filesystem.h"

#include "editor/browser.h"
#include "editor/scimed.h"

#include "imgui/imgui.h"
#include <SDL.h>
#include <iostream>
#include <memory>

ImVec2
operator+(const ImVec2& lhs, const ImVec2& rhs)
{
  return ImVec2{lhs.x + rhs.x, lhs.y + rhs.y};
}

struct StyleData
{
  ScimedConfig scc = ScimedConfig{};
  CanvasConfig cc  = CanvasConfig{};
};

struct GenericWindow
{
  std::string name;
  bool        open = true;

  virtual void
  Run(StyleData* style_data) = 0;
};

template <typename CreateWindowFunction>
void
OpenOrFocusWindow(
    std::vector<std::shared_ptr<GenericWindow>>* windows,
    const std::string&                           title_name,
    CreateWindowFunction                         create_window_function)
{
  const auto found =
      Search(*windows, [&](std::shared_ptr<GenericWindow>& wind) -> bool {
        return wind->name == title_name;
      });

  if(found == windows->end())
  {
    auto the_window  = create_window_function();
    the_window->name = title_name;
    windows->emplace_back(the_window);
  }
  else
  {
    ImGui::SetNextWindowFocus();
    ImGui::Begin(title_name.c_str());
    ImGui::End();
  }
}

struct ScimedWindow : public GenericWindow
{
  Scimed scimed;

  void
  Run(StyleData* style_data) override
  {
    scimed.Run(style_data->cc, style_data->scc);
  }
};

void
ColorEdit4(const char* label, ImU32* color)
{
  ImVec4 temp = ImColor{*color};

  if(ImGui::ColorEdit4(label, &temp.x))
  {
    *color = ImColor(temp);
  }
}

struct StyleEditorWindow : GenericWindow
{
  void
  Run(StyleData* s) override
  {
    ColorEdit4("Background color", &s->cc.background_color);
    ColorEdit4("Grid color", &s->cc.grid_color);
    ColorEdit4("Split color", &s->scc.split_color);
    ColorEdit4("Sizer color", &s->scc.sizer_color);

    ImGui::InputFloat("Grid Size", &s->cc.grid_size, 1.0f, 5.0f);
    ImGui::InputFloat("Zoom speed", &s->cc.zoom_speed);
    ImGui::InputInt("Anchor size", &s->scc.anchor_size);
    ImGui::InputInt("Sizer distance", &s->scc.sizer_distance);
    ImGui::InputInt("Sizer text distance", &s->scc.sizer_text_distance);

    if(ImGui::Button("Set Default"))
    {
      *s = StyleData{};
    }
  }
};

void
OpenOrFocusStyleEditor(std::vector<std::shared_ptr<GenericWindow>>* windows)
{
  OpenOrFocusWindow(windows, "Style editor", []() {
    return std::make_shared<StyleEditorWindow>();
  });
}

int
main(int argc, char** argv)
{
  SdlLibrary sdl;
  if(sdl.ok == false)
  {
    return -1;
  }

  int width  = 1280;
  int height = 720;

  SdlWindow window{"Euphoria Demo", width, height};
  if(window.window == nullptr)
  {
    return -1;
  }

  SdlGlContext context{&window};

  if(context.context == nullptr)
  {
    return -1;
  }

  Init init{SDL_GL_GetProcAddress};
  if(init.ok == false)
  {
    return -4;
  }

  SetupOpenglDebug();

  const auto current_directory = GetCurrentDirectory();
  const auto base_path         = GetBasePath();
  const auto pref_path         = GetPrefPath();

  ImguiLibrary imgui{window.window, pref_path};
  ImGui::StyleColorsLight();

  Viewport viewport{
      Recti::FromWidthHeight(width, height).SetBottomLeftToCopy(0, 0)};
  viewport.Activate();

  FileSystem file_system;
  auto       catalog = FileSystemRootCatalog::AddRoot(&file_system);

  FileSystemRootFolder::AddRoot(&file_system, current_directory);
  FileSystemImageGenerator::AddRoot(&file_system, "img-plain");

  SetupDefaultFiles(catalog);

  TextureCache texture_cache{&file_system};

  bool running = true;

  FileBrowser browser{&file_system};
  browser.Refresh();
  std::vector<std::shared_ptr<GenericWindow>> scimeds;
  StyleData                                   style_data = StyleData{};

  OpenOrFocusStyleEditor(&scimeds);

  while(running)
  {
    SDL_Event e;
    while(SDL_PollEvent(&e) != 0)
    {
      imgui.ProcessEvents(&e);

      switch(e.type)
      {
        case SDL_QUIT:
          running = false;
          break;
        default:
          // ignore other events
          break;
      }
    }

    imgui.StartNewFrame();

    if(ImGui::BeginMainMenuBar())
    {
      if(ImGui::BeginMenu("File"))
      {
        if(ImGui::MenuItem("Exit", "Ctrl+Q"))
        {
          running = false;
        }
        if(ImGui::MenuItem("Style editor"))
        {
          OpenOrFocusStyleEditor(&scimeds);
        }
        ImGui::EndMenu();
      }

      if(ImGui::BeginMenu("Window"))
      {
        for(const auto& window : scimeds)
        {
          if(ImGui::MenuItem(window->name.c_str()))
          {
            ImGui::SetNextWindowFocus();
            ImGui::Begin(window->name.c_str());
            ImGui::End();
          }
        }

        ImGui::EndMenu();
      }
    }
    ImGui::EndMainMenuBar();

    if(ImGui::Begin("Solution explorer"))
    {
      if(browser.Run())
      {
        const auto file = browser.GetSelectedFile();

        OpenOrFocusWindow(
            &scimeds,
            Str{} << "Scimed: " << file,
            [&]() -> std::shared_ptr<GenericWindow> {
              auto scimed = std::make_shared<ScimedWindow>();
              scimed->scimed.LoadFile(&texture_cache, &file_system, file);
              return scimed;
            });
      }
    }
    ImGui::End();

    for(auto& scimed : scimeds)
    {
      ImGui::SetNextWindowSize(ImVec2{300, 300}, ImGuiCond_FirstUseEver);
      if(ImGui::Begin(scimed->name.c_str(), &scimed->open))
      {
        scimed->Run(&style_data);
      }
      ImGui::End();
    }

    // ImGui::ShowMetricsWindow();

    init.ClearScreen(Color::Wheat);
    imgui.Render();

    RemoveMatching(&scimeds, [](const std::shared_ptr<GenericWindow>& window) {
      return !window->open;
    });

    SDL_GL_SwapWindow(window.window);
  }

  return 0;
}
<|endoftext|>


<commit_before>#include "GUI.h"
#include "Queen.h"
#include "Rook.h"
#include "Bishop.h"
#include "Knight.h"

using namespace sf;
using namespace Chess;

namespace GUI {
	GUI::GUI(int width, int height, Board& board) : board(board) {
		this->width = width;
		this->height = height;

		window = new RenderWindow(VideoMode(width, height), "Ninja Chess");
		window->setVerticalSyncEnabled(true);

		font.loadFromFile("Resources/stchess.ttf");

		text.setFont(font);
		text.setCharacterSize(height / 8);
		text.setColor(Color::Black);

		notationMap['P'] = "A";
		notationMap['p'] = "a";
		notationMap['R'] = "D";
		notationMap['r'] = "d";
		notationMap['N'] = "B";
		notationMap['n'] = "b";
		notationMap['B'] = "C";
		notationMap['b'] = "c";
		notationMap['Q'] = "E";
		notationMap['q'] = "e";
		notationMap['K'] = "F";
		notationMap['k'] = "f";
	}

	GUI::~GUI() {
		delete window;
	}

	bool GUI::isOpen() const {
		return window->isOpen();
	}

	void GUI::update() {
		if (showPromoteWindow == false){
			updateGame();
		}
		else{
			updatePromote();
		}
	}

	void GUI::updateGame(){
		Event event;
		while (window->pollEvent(event)) {
			if (event.type == Event::Closed)
				window->close();
		}

		bool pressed = Mouse::isButtonPressed(Mouse::Left);
		if (pressed && !mousePressed) {
			Vector2i mousePos = Mouse::getPosition(*window);
			Position tempPos(mousePos.x * 8 / width, mousePos.y * 8 / height);
			tempPos.y = 7 - tempPos.y;
			if (tempPos.valid()) {
				Piece* tempPiece = board.getPiece(tempPos);
				if (selected) {
					Piece* selectedPiece = board.getPiece(selection);
					if (selectedPiece->isLegal(board, tempPos)) {
						board.move(selection, tempPos);
						lastMovedPiece = tempPiece;
						selected = false;
					}
					else if (tempPiece != nullptr) {
						if (tempPiece->isWhite() && (board.getState() == GameState::BLACKPLAYS))
							return;
						else if (!tempPiece->isWhite() && (board.getState() == GameState::WHITEPLAYS))
							return;
						selection = tempPos;
						selected = true;
						highlights = tempPiece->legalMoves(board);
					}
				}
				else if (tempPiece != nullptr) {
					if (tempPiece->isWhite() && (board.getState() == GameState::BLACKPLAYS))
						return;
					else if (!tempPiece->isWhite() && (board.getState() == GameState::WHITEPLAYS))
						return;
					selection = tempPos;
					selected = true;
					highlights = tempPiece->legalMoves(board);
				}
			}
		}
		if (board.signalPromote() == true)
			showPromoteWindow = true;
		mousePressed = pressed;
	}

	void GUI::updatePromote()
	{
		Event event;
		while (window->pollEvent(event)) {
			if (event.type == Event::Closed)
				window->close();
		}
		bool pressed = Mouse::isButtonPressed(Mouse::Left);
		if (pressed && !mousePressed){
			Vector2i mousePos = Mouse::getPosition(*window);
			Position tempPosition;
			tempPosition.x = lastMovedPiece->getPosition().x;
			tempPosition.y = lastMovedPiece->getPosition().y;
			bool tempIsWhite = lastMovedPiece->isWhite();
			if ((mousePos.x < width / 2.f) && (mousePos.y < height / 2.f)){
				printf("QUEEN");
				text.setCharacterSize(height / 8);
				delete lastMovedPiece;
				lastMovedPiece = new Queen(tempPosition, tempIsWhite);
				showPromoteWindow = false;
			}
			else if ((mousePos.x > width / 2.f) && (mousePos.y < height / 2.f)){
				printf("ROOK");
				text.setCharacterSize(height / 8);
				delete lastMovedPiece;
				lastMovedPiece = new Rook(tempPosition, tempIsWhite);
				showPromoteWindow = false;
			}
			else if ((mousePos.x < width / 2.f) && (mousePos.y > height / 2.f)){
				text.setCharacterSize(height / 8);
				printf("BISHOP");
				delete lastMovedPiece;
				lastMovedPiece = new Bishop(tempPosition, tempIsWhite);
				showPromoteWindow = false;
			}
			else if ((mousePos.x > width / 2.f) && (mousePos.y > height / 2.f)){
				text.setCharacterSize(height / 8);
				printf("KNIGHT");
				delete lastMovedPiece;
				lastMovedPiece = new Knight(tempPosition, tempIsWhite);
				showPromoteWindow = false;
			}
		}
		mousePressed = pressed;
	}

	void GUI::render() {
		window->clear();
		if (showPromoteWindow == false)
		{
			drawBoard();
			drawPieces();
		}
		else
		{
			drawPromote();
		}
		window->display();
	}

	void GUI::drawPromote()
	{
		Color brightSquare(224, 217, 190);
		Color darkSquare(152, 145, 135);
		RectangleShape square(Vector2f(width / 2.f, width / 2.f));
		for (int x = 0; x < 2; x++) {
			for (int y = 0; y < 2; y++) {
				square.setPosition(x * width / 2.f, y * height / 2.f);

				if (selected && selection == Position(x, 1 - y))
					square.setFillColor(Color::Yellow);
				else if (selected && highlighted(Position(x, 1 - y)))
					square.setFillColor(Color::Green);
				else if ((x + y) % 2 == 0)
					square.setFillColor(brightSquare);
				else
					square.setFillColor(darkSquare);

				window->draw(square);
			}
		}
		char tempPromotes[4] = { 'q', 'R', 'B', 'n' };
		int i = 0;
		for (int x = 0; x < 2; x++) {
			for (int y = 0; y < 2; y++) {
				text.setCharacterSize(height / 2);
				text.setPosition(Vector2f(x * width / 2.f, (y - 0.2f) * width / 2.f));
				text.setString(notationMap[tempPromotes[i]]);
				i++;
				window->draw(text);
			}
		}
	}

	void GUI::drawBoard() {
		Color brightSquare(224, 217, 190);
		Color darkSquare(152, 145, 135);

		RectangleShape square(Vector2f(width / 8.f, height / 8.f));
		for (int x = 0; x < 8; x++) {
			for (int y = 0; y < 8; y++) {
				square.setPosition(x * width / 8.f, y * height / 8.f);

				if (selected && selection == Position(x, 7 - y))
					square.setFillColor(Color::Yellow);
				else if (selected && highlighted(Position(x, 7 - y)))
					square.setFillColor(Color::Green);
				else if ((x + y) % 2 == 0)
					square.setFillColor(brightSquare);
				else
					square.setFillColor(darkSquare);

				window->draw(square);
			}
		}
	}

	void GUI::drawPieces() {
		for (int x = 0; x < 8; x++) {
			for (int y = 0; y < 8; y++) {
				Piece* piece = board.getPiece(Position(x, 7-y));
				if (piece != nullptr) {
					text.setPosition(Vector2f(x * width / 8.f, (y - 0.2f) * width / 8.f));
					text.setString(notationMap[piece->notation()]);
					window->draw(text);
				}
			}
		}
	}

	bool GUI::highlighted(const Position& position) {
		for (Position move : highlights) {
			if (move == position)
				return true;
		}

		return false;
	}
}<commit_msg>Promotion fixed.<commit_after>#include "GUI.h"
#include "Queen.h"
#include "Rook.h"
#include "Bishop.h"
#include "Knight.h"

using namespace sf;
using namespace Chess;

namespace GUI {
	GUI::GUI(int width, int height, Board& board) : board(board) {
		this->width = width;
		this->height = height;

		window = new RenderWindow(VideoMode(width, height), "Ninja Chess");
		window->setVerticalSyncEnabled(true);

		font.loadFromFile("Resources/stchess.ttf");

		text.setFont(font);
		text.setCharacterSize(height / 8);
		text.setColor(Color::Black);

		notationMap['P'] = "A";
		notationMap['p'] = "a";
		notationMap['R'] = "D";
		notationMap['r'] = "d";
		notationMap['N'] = "B";
		notationMap['n'] = "b";
		notationMap['B'] = "C";
		notationMap['b'] = "c";
		notationMap['Q'] = "E";
		notationMap['q'] = "e";
		notationMap['K'] = "F";
		notationMap['k'] = "f";
	}

	GUI::~GUI() {
		delete window;
	}

	bool GUI::isOpen() const {
		return window->isOpen();
	}

	void GUI::update() {
		if (showPromoteWindow == false){
			updateGame();
		}
		else{
			updatePromote();
		}
	}

	void GUI::updateGame(){
		Event event;
		while (window->pollEvent(event)) {
			if (event.type == Event::Closed)
				window->close();
		}

		bool pressed = Mouse::isButtonPressed(Mouse::Left);
		if (pressed && !mousePressed) {
			Vector2i mousePos = Mouse::getPosition(*window);
			Position tempPos(mousePos.x * 8 / width, mousePos.y * 8 / height);
			tempPos.y = 7 - tempPos.y;
			if (tempPos.valid()) {
				Piece* tempPiece = board.getPiece(tempPos);
				if (selected) {
					Piece* selectedPiece = board.getPiece(selection);
					if (selectedPiece->isLegal(board, tempPos)) {
						board.move(selection, tempPos);
						lastMovedPiece = selectedPiece;
						selected = false;
					}
					else if (tempPiece != nullptr) {
						if (tempPiece->isWhite() && (board.getState() == GameState::BLACKPLAYS))
							return;
						else if (!tempPiece->isWhite() && (board.getState() == GameState::WHITEPLAYS))
							return;
						selection = tempPos;
						selected = true;
						highlights = tempPiece->legalMoves(board);
					}
				}
				else if (tempPiece != nullptr) {
					if (tempPiece->isWhite() && (board.getState() == GameState::BLACKPLAYS))
						return;
					else if (!tempPiece->isWhite() && (board.getState() == GameState::WHITEPLAYS))
						return;
					selection = tempPos;
					selected = true;
					highlights = tempPiece->legalMoves(board);
				}
			}
		}
		if (board.signalPromote() == true)
			showPromoteWindow = true;
		mousePressed = pressed;
	}

	void GUI::updatePromote()
	{
		Event event;
		while (window->pollEvent(event)) {
			if (event.type == Event::Closed)
				window->close();
		}
		bool pressed = Mouse::isButtonPressed(Mouse::Left);
		if (pressed && !mousePressed){
			Vector2i mousePos = Mouse::getPosition(*window);
			Position tempPosition = lastMovedPiece->getPosition();
			bool tempIsWhite = lastMovedPiece->isWhite();
			if ((mousePos.x < width / 2.f) && (mousePos.y < height / 2.f)){
				printf("QUEEN");
				text.setCharacterSize(height / 8);
				delete lastMovedPiece;
				lastMovedPiece = new Queen(tempPosition, tempIsWhite);
				showPromoteWindow = false;
			}
			else if ((mousePos.x > width / 2.f) && (mousePos.y < height / 2.f)){
				printf("ROOK");
				text.setCharacterSize(height / 8);
				delete lastMovedPiece;
				lastMovedPiece = new Rook(tempPosition, tempIsWhite);
				showPromoteWindow = false;
			}
			else if ((mousePos.x < width / 2.f) && (mousePos.y > height / 2.f)){
				text.setCharacterSize(height / 8);
				printf("BISHOP");
				delete lastMovedPiece;
				lastMovedPiece = new Bishop(tempPosition, tempIsWhite);
				showPromoteWindow = false;
			}
			else if ((mousePos.x > width / 2.f) && (mousePos.y > height / 2.f)){
				text.setCharacterSize(height / 8);
				printf("KNIGHT");
				delete lastMovedPiece;
				lastMovedPiece = new Knight(tempPosition, tempIsWhite);
				showPromoteWindow = false;
			}
		}
		mousePressed = pressed;
	}

	void GUI::render() {
		window->clear();
		if (showPromoteWindow == false)
		{
			drawBoard();
			drawPieces();
		}
		else
		{
			drawPromote();
		}
		window->display();
	}

	void GUI::drawPromote()
	{
		Color brightSquare(224, 217, 190);
		Color darkSquare(152, 145, 135);
		RectangleShape square(Vector2f(width / 2.f, width / 2.f));
		for (int x = 0; x < 2; x++) {
			for (int y = 0; y < 2; y++) {
				square.setPosition(x * width / 2.f, y * height / 2.f);

				if (selected && selection == Position(x, 1 - y))
					square.setFillColor(Color::Yellow);
				else if (selected && highlighted(Position(x, 1 - y)))
					square.setFillColor(Color::Green);
				else if ((x + y) % 2 == 0)
					square.setFillColor(brightSquare);
				else
					square.setFillColor(darkSquare);

				window->draw(square);
			}
		}
		char tempPromotes[4] = { 'q', 'R', 'B', 'n' };
		int i = 0;
		for (int x = 0; x < 2; x++) {
			for (int y = 0; y < 2; y++) {
				text.setCharacterSize(height / 2);
				text.setPosition(Vector2f(x * width / 2.f, (y - 0.2f) * width / 2.f));
				text.setString(notationMap[tempPromotes[i]]);
				i++;
				window->draw(text);
			}
		}
	}

	void GUI::drawBoard() {
		Color brightSquare(224, 217, 190);
		Color darkSquare(152, 145, 135);

		RectangleShape square(Vector2f(width / 8.f, height / 8.f));
		for (int x = 0; x < 8; x++) {
			for (int y = 0; y < 8; y++) {
				square.setPosition(x * width / 8.f, y * height / 8.f);

				if (selected && selection == Position(x, 7 - y))
					square.setFillColor(Color::Yellow);
				else if (selected && highlighted(Position(x, 7 - y)))
					square.setFillColor(Color::Green);
				else if ((x + y) % 2 == 0)
					square.setFillColor(brightSquare);
				else
					square.setFillColor(darkSquare);

				window->draw(square);
			}
		}
	}

	void GUI::drawPieces() {
		for (int x = 0; x < 8; x++) {
			for (int y = 0; y < 8; y++) {
				Piece* piece = board.getPiece(Position(x, 7-y));
				if (piece != nullptr) {
					text.setPosition(Vector2f(x * width / 8.f, (y - 0.2f) * width / 8.f));
					text.setString(notationMap[piece->notation()]);
					window->draw(text);
				}
			}
		}
	}

	bool GUI::highlighted(const Position& position) {
		for (Position move : highlights) {
			if (move == position)
				return true;
		}

		return false;
	}
}<|endoftext|>


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

#define BOOST_NO_RTTI
#define BOOST_NO_TYPEID
#include <boost/range/adaptors.hpp>

#include "Type.hpp"
#include "FunctionContext.hpp"
#include "GlobalContext.hpp"
#include "Variable.hpp"

#include "mtac/DeadCodeElimination.hpp"
#include "mtac/GlobalOptimizations.hpp"
#include "mtac/LiveVariableAnalysisProblem.hpp"
#include "mtac/Utils.hpp"
#include "mtac/Offset.hpp"
#include "mtac/Quadruple.hpp"

using namespace eddic;

bool mtac::dead_code_elimination::operator()(mtac::Function& function){
    bool optimized = false;

    std::vector<std::size_t> to_delete;

    //1. DCE based on data-flow analysis

    mtac::LiveVariableAnalysisProblem problem;
    auto results = mtac::data_flow(function, problem);

    for(auto& block : function){
        auto& out = results->OUT[block];

        for(auto& quadruple : boost::adaptors::reverse(block->statements)){
            if(quadruple.result && mtac::erase_result(quadruple.op)){
                if(out.top() || out.values().find(quadruple.result) == out.values().end()){
                    to_delete.push_back(quadruple.uid());
                }
            }

            problem.transfer(block, quadruple, out);
        }
    }

    //2. Remove variables that contribute only to themselves
    //TODO This could probably be done directly in the data-flow DCE

    std::unordered_set<std::shared_ptr<Variable>> candidates;

    for(auto& block : function){
        for(auto& quadruple : block->statements){
            if(quadruple.result && mtac::erase_result(quadruple.op)){
                if_init_equals(quadruple.arg1, quadruple.result, [&candidates, &quadruple](){ candidates.insert(quadruple.result);});
                if_init_equals(quadruple.arg2, quadruple.result, [&candidates, &quadruple](){ candidates.insert(quadruple.result);});
            }
        }
    }

    for(auto& block : function){
        for(auto& quadruple : block->statements){
            if(quadruple.result && mtac::erase_result(quadruple.op)){
                if_init_not_equals<std::shared_ptr<Variable>>(quadruple.arg1, quadruple.result, [&candidates](std::shared_ptr<Variable>& var){ candidates.erase(var);});
                if_init_not_equals<std::shared_ptr<Variable>>(quadruple.arg2, quadruple.result, [&candidates](std::shared_ptr<Variable>& var){ candidates.erase(var);});
            } else {
                candidates.erase(quadruple.result);

                if_init<std::shared_ptr<Variable>>(quadruple.arg1, [&candidates](std::shared_ptr<Variable>& var){ candidates.erase(var); });
                if_init<std::shared_ptr<Variable>>(quadruple.arg2, [&candidates](std::shared_ptr<Variable>& var){ candidates.erase(var); });
            }
        }
    }

    if(!candidates.empty()){
        for(auto& block : function){
            for(auto& quadruple : block->statements){
                if(quadruple.result && mtac::erase_result(quadruple.op) && candidates.find(quadruple.result) != candidates.end()){
                    to_delete.push_back(quadruple.uid());
                }
            }
        }
    }

    //Delete what has been found on previous steps

    if(!to_delete.empty()){
        optimized = true;

        for(auto& block : function){
            for(auto& quadruple : block->statements){
                if(std::find(to_delete.begin(), to_delete.end(), quadruple.uid()) != to_delete.end()){
                    mtac::transform_to_nop(quadruple);
                }
            }
        }
    }

    //TODO Review or remove this optimization, this is quite unsafe

    std::unordered_set<Offset, mtac::OffsetHash> used_offsets;
    std::unordered_set<std::shared_ptr<Variable>> invalidated_offsets;

    for(auto& block : function){
        for(auto& quadruple : block->statements){
            if(quadruple.op == mtac::Operator::DOT || quadruple.op == mtac::Operator::FDOT || quadruple.op == mtac::Operator::PDOT){
                if(auto* var_ptr = boost::get<std::shared_ptr<Variable>>(&*quadruple.arg1)){
                    if(auto* offset_ptr = boost::get<int>(&*quadruple.arg2)){
                        mtac::Offset offset(*var_ptr, *offset_ptr);
                        used_offsets.insert(offset);
                    } else {
                        invalidated_offsets.insert(*var_ptr);
                    }
                }
            }
        }
    }

    for(auto& block : function){
        auto it = iterate(block->statements);

        while(it.has_next()){
            auto& quadruple = *it;

            if(quadruple.op == mtac::Operator::DOT_ASSIGN || quadruple.op == mtac::Operator::DOT_FASSIGN || quadruple.op == mtac::Operator::DOT_PASSIGN){
                if(invalidated_offsets.find(quadruple.result) == invalidated_offsets.end()){
                    //Arrays are a problem because they are not considered as escaped after being passed in parameters
                    if(!quadruple.result->type()->is_pointer() && !quadruple.result->type()->is_array()){
                        if(auto* offset_ptr = boost::get<int>(&*quadruple.arg1)){
                            if(quadruple.result->type()->is_custom_type() || quadruple.result->type()->is_template_type()){
                                auto struct_type = function.context->global()->get_struct(quadruple.result->type()->mangle());
                                auto member_type = function.context->global()->member_type(struct_type, *offset_ptr);

                                if(member_type->is_pointer()){
                                    ++it;
                                    continue;
                                }
                            }

                            mtac::Offset offset(quadruple.result, *offset_ptr);

                            if(problem.pointer_escaped->find(quadruple.result) == problem.pointer_escaped->end() && used_offsets.find(offset) == used_offsets.end()){
                                it.erase();
                                optimized=true;
                                continue;
                            }
                        }
                    }
                }
            }

            ++it;
        }
    }

    return optimized;
}
<commit_msg>Cleanup<commit_after>//=======================================================================
// Copyright Baptiste Wicht 2011-2013.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)
//=======================================================================

#define BOOST_NO_RTTI
#define BOOST_NO_TYPEID
#include <boost/range/adaptors.hpp>

#include "Type.hpp"
#include "FunctionContext.hpp"
#include "GlobalContext.hpp"
#include "Variable.hpp"

#include "mtac/DeadCodeElimination.hpp"
#include "mtac/GlobalOptimizations.hpp"
#include "mtac/LiveVariableAnalysisProblem.hpp"
#include "mtac/Utils.hpp"
#include "mtac/Offset.hpp"
#include "mtac/Quadruple.hpp"

using namespace eddic;

bool mtac::dead_code_elimination::operator()(mtac::Function& function){
    bool optimized = false;

    std::vector<std::size_t> to_delete;

    //1. DCE based on data-flow analysis

    mtac::LiveVariableAnalysisProblem problem;
    auto results = mtac::data_flow(function, problem);

    for(auto& block : function){
        auto& out = results->OUT[block];

        for(auto& quadruple : boost::adaptors::reverse(block->statements)){
            if(quadruple.result && mtac::erase_result(quadruple.op)){
                if(out.top() || out.values().find(quadruple.result) == out.values().end()){
                    to_delete.push_back(quadruple.uid());
                }
            }

            problem.transfer(block, quadruple, out);
        }
    }

    //Delete what has been found on previous steps

    if(!to_delete.empty()){
        optimized = true;

        for(auto& block : function){
            for(auto& quadruple : block->statements){
                if(std::find(to_delete.begin(), to_delete.end(), quadruple.uid()) != to_delete.end()){
                    mtac::transform_to_nop(quadruple);
                }
            }
        }
    }

    //2. Remove variables that contribute only to themselves
    //TODO This could probably be done directly in the data-flow DCE

    std::unordered_set<std::shared_ptr<Variable>> candidates;

    for(auto& block : function){
        for(auto& quadruple : block->statements){
            if(quadruple.result && mtac::erase_result(quadruple.op)){
                if_init_equals(quadruple.arg1, quadruple.result, [&candidates, &quadruple](){ candidates.insert(quadruple.result);});
                if_init_equals(quadruple.arg2, quadruple.result, [&candidates, &quadruple](){ candidates.insert(quadruple.result);});
            }
        }
    }

    for(auto& block : function){
        for(auto& quadruple : block->statements){
            if(quadruple.result && mtac::erase_result(quadruple.op)){
                if_init_not_equals<std::shared_ptr<Variable>>(quadruple.arg1, quadruple.result, [&candidates](std::shared_ptr<Variable>& var){ candidates.erase(var);});
                if_init_not_equals<std::shared_ptr<Variable>>(quadruple.arg2, quadruple.result, [&candidates](std::shared_ptr<Variable>& var){ candidates.erase(var);});
            } else {
                candidates.erase(quadruple.result);

                if_init<std::shared_ptr<Variable>>(quadruple.arg1, [&candidates](std::shared_ptr<Variable>& var){ candidates.erase(var); });
                if_init<std::shared_ptr<Variable>>(quadruple.arg2, [&candidates](std::shared_ptr<Variable>& var){ candidates.erase(var); });
            }
        }
    }

    if(!candidates.empty()){
        for(auto& block : function){
            for(auto& quadruple : block->statements){
                if(quadruple.result && mtac::erase_result(quadruple.op) && candidates.find(quadruple.result) != candidates.end()){
                    mtac::transform_to_nop(quadruple);
                    optimized = true;
                }
            }
        }
    }

    //TODO Review or remove this optimization, this is quite unsafe

    std::unordered_set<Offset, mtac::OffsetHash> used_offsets;
    std::unordered_set<std::shared_ptr<Variable>> invalidated_offsets;

    for(auto& block : function){
        for(auto& quadruple : block->statements){
            if(quadruple.op == mtac::Operator::DOT || quadruple.op == mtac::Operator::FDOT || quadruple.op == mtac::Operator::PDOT){
                if(auto* var_ptr = boost::get<std::shared_ptr<Variable>>(&*quadruple.arg1)){
                    if(auto* offset_ptr = boost::get<int>(&*quadruple.arg2)){
                        mtac::Offset offset(*var_ptr, *offset_ptr);
                        used_offsets.insert(offset);
                    } else {
                        invalidated_offsets.insert(*var_ptr);
                    }
                }
            }
        }
    }

    for(auto& block : function){
        auto it = iterate(block->statements);

        while(it.has_next()){
            auto& quadruple = *it;

            if(quadruple.op == mtac::Operator::DOT_ASSIGN || quadruple.op == mtac::Operator::DOT_FASSIGN || quadruple.op == mtac::Operator::DOT_PASSIGN){
                if(invalidated_offsets.find(quadruple.result) == invalidated_offsets.end()){
                    //Arrays are a problem because they are not considered as escaped after being passed in parameters
                    if(!quadruple.result->type()->is_pointer() && !quadruple.result->type()->is_array()){
                        if(auto* offset_ptr = boost::get<int>(&*quadruple.arg1)){
                            if(quadruple.result->type()->is_custom_type() || quadruple.result->type()->is_template_type()){
                                auto struct_type = function.context->global()->get_struct(quadruple.result->type()->mangle());
                                auto member_type = function.context->global()->member_type(struct_type, *offset_ptr);

                                if(member_type->is_pointer()){
                                    ++it;
                                    continue;
                                }
                            }

                            mtac::Offset offset(quadruple.result, *offset_ptr);

                            if(problem.pointer_escaped->find(quadruple.result) == problem.pointer_escaped->end() && used_offsets.find(offset) == used_offsets.end()){
                                mtac::transform_to_nop(quadruple);
                                optimized=true;
                            }
                        }
                    }
                }
            }

            ++it;
        }
    }

    return optimized;
}
<|endoftext|>


<commit_before>#include <ros/ros.h>
#include <geometry_msgs/Twist.h>
#include <sensor_msgs/PointCloud2.h>
#include <sensor_msgs/PointCloud.h>
#include <sensor_msgs/point_cloud_conversion.h>
#include <math.h>

static const float tol = 0.000000000000001f;

double magnitude(double vec[3]){
    return sqrt(vec[0]*vec[0] + vec[1]*vec[1] + vec[2]*vec[2]);
}

void normalize(double vec[3]){
    float m = magnitude(vec);
    if(tol >= m) m = 1;
    vec[0] /= m;
    vec[1] /= m;
    vec[2] /= m;

    if(fabs(vec[0]) < tol) vec[0] = 0.0f;
    if(fabs(vec[1]) < tol) vec[1] = 0.0f;
    if(fabs(vec[2]) < tol) vec[2] = 0.0f;
}

class ArtificialPotentialField{
public:
    ArtificialPotentialField(ros::NodeHandle &node) :
        cmd_pub_(node.advertise<geometry_msgs::Twist>("cmd_vel", 10)),
        obs_sub_(node.subscribe("/camera/depth/points", 10, &ArtificialPotentialField::obstacleCallback, this))

    {
        for(int i=0; i < 3; i++) obs_[i] = 0;
    }

    void spin(){
        ros::Rate r(10);

        ros::Duration(1).sleep();
        geometry_msgs::Twist cmd;
        cmd.linear.z = 0.15;
        cmd_pub_.publish(cmd);
        ros::Duration(3).sleep();

        cmd.linear.z = 0;
        cmd_pub_.publish(cmd);
        ros::Duration(3).sleep();

        const double force = 0.025;

        while(ros::ok()){
            double Fs[3];
            Fs[0] = Fs[1] = Fs[2] = 0;

            double f_in[3];
            get_potential_force(obs_, f_in, 0, 2, 1, 1.5);

            Fs[0] += f_in[0];
            Fs[1] += f_in[1];
            Fs[2] += f_in[2];

            double g[3];
            g[0] = 0.5;
            g[1] = 0;
            g[2] = 0;

            get_potential_force(g, f_in, 2, 0, 1.5, 1);

            Fs[0] += f_in[0];
            Fs[1] += f_in[1];
            Fs[2] += f_in[2];

            cmd.linear.x = -Fs[0] * force;
            cmd.linear.y = Fs[1] * force;

            ROS_INFO("obs = (%f, %f)", obs_[0], obs_[1]);
            ROS_INFO_STREAM("cmd = " << cmd);
            cmd_pub_.publish(cmd);
            r.sleep();
            ros::spinOnce();
        }
    }

private:
    void get_potential_force(double dest_lc[3], double f_out[3], double A = 1, double B = 1, double n = 1, double m = 1){
        double u[3];
        u[0] = dest_lc[0];
        u[1] = dest_lc[1];
        u[2] = dest_lc[2];
        normalize(u);

        const double d = magnitude(dest_lc);
        double U = 0;
        if(fabs(d) > tol){
            U = -A/pow(d, n) + B/pow(d, m);
        }

        f_out[0] = U * u[0];
        f_out[1] = U * u[1];
        f_out[2] = U * u[2];
    }

    void obstacleCallback(const sensor_msgs::PointCloud2Ptr &obs_msg){
        sensor_msgs::PointCloud obs_data;
        sensor_msgs::convertPointCloud2ToPointCloud(*obs_msg, obs_data);

        if(obs_data.points.size() == 0){
            obs_[0] = 0;
            obs_[1] = 0;
            obs_[2] = 0;
            return;
        }

        double min_obs[3];
        min_obs[0] = obs_data.points[0].x;
        min_obs[1] = obs_data.points[0].y;
        min_obs[2] = obs_data.points[0].z;

        float min_dist = magnitude(min_obs);

        for(int i=1; i < obs_data.points.size(); i++){
            double obs[3];
            obs[0] = obs_data.points[i].x;
            obs[1] = obs_data.points[i].y;
            obs[2] = obs_data.points[i].z;

            //ROS_INFO("(%f, %f)", obs[0], obs[1]);

            double dist = magnitude(obs);
            if(dist < min_dist){
                min_obs[0] = obs[0];
                min_obs[1] = obs[1];
                min_obs[2] = obs[2];
                min_dist = dist;
            }
        }

        obs_[0] = min_obs[0];
        obs_[1] = min_obs[1];
        obs_[2] = min_obs[2];
    }

    double obs_[3];
    ros::Publisher cmd_pub_;
    ros::Subscriber obs_sub_;
};

int main(int argc, char *argv[]){
    ros::init(argc, argv, "apf_planner");

    ros::NodeHandle node;
    ArtificialPotentialField apf = ArtificialPotentialField(node);
    apf.spin();

    return 0;
}

<commit_msg>Use tf_listener for converting point cloud<commit_after>#include <ros/ros.h>
#include <geometry_msgs/Twist.h>
#include <sensor_msgs/PointCloud2.h>
#include <sensor_msgs/PointCloud.h>
#include <sensor_msgs/point_cloud_conversion.h>
#include <tf/transform_listener.h>

#include <string>
#include <math.h>

static const float tol = 0.000000000000001f;

double magnitude(double vec[3]){
    return sqrt(vec[0]*vec[0] + vec[1]*vec[1] + vec[2]*vec[2]);
}

void normalize(double vec[3]){
    float m = magnitude(vec);
    if(tol >= m) m = 1;
    vec[0] /= m;
    vec[1] /= m;
    vec[2] /= m;

    if(fabs(vec[0]) < tol) vec[0] = 0.0f;
    if(fabs(vec[1]) < tol) vec[1] = 0.0f;
    if(fabs(vec[2]) < tol) vec[2] = 0.0f;
}

class ArtificialPotentialField{
public:
    ArtificialPotentialField(ros::NodeHandle &node) :
        cmd_pub_(node.advertise<geometry_msgs::Twist>("cmd_vel", 10)),
        obs_sub_(node.subscribe("/camera/depth/points", 10, &ArtificialPotentialField::obstacleCallback, this))

    {
        for(int i=0; i < 3; i++) obs_[i] = 0;
    }

    void spin(){
        ros::Rate r(10);

        ros::Duration(1).sleep();
        geometry_msgs::Twist cmd;
        cmd.linear.z = 0.15;
        cmd_pub_.publish(cmd);
        ros::Duration(3).sleep();

        cmd.linear.z = 0;
        cmd_pub_.publish(cmd);
        ros::Duration(3).sleep();

        const double force = 0.025;

        while(ros::ok()){
            double Fs[3];
            Fs[0] = Fs[1] = Fs[2] = 0;

            double f_in[3];
            get_potential_force(obs_, f_in, 0, 2, 1, 1.5);

            Fs[0] += f_in[0];
            Fs[1] += f_in[1];
            Fs[2] += f_in[2];

            double g[3];
            g[0] = 0;
            g[1] = 0;
            g[2] = 0;

            get_potential_force(g, f_in, 2, 0, 1.5, 1);

            Fs[0] += f_in[0];
            Fs[1] += f_in[1];
            Fs[2] += f_in[2];

            cmd.linear.x = Fs[1] * force;
            //cmd.linear.y = Fs[1] * force;

            ROS_INFO("obs = (%f, %f)", obs_[0], obs_[1]);
            ROS_INFO_STREAM("cmd = " << cmd);
            cmd_pub_.publish(cmd);
            r.sleep();
            ros::spinOnce();
        }
    }

private:
    void get_potential_force(double dest_lc[3], double f_out[3], double A = 1, double B = 1, double n = 1, double m = 1){
        double u[3];
        u[0] = dest_lc[0];
        u[1] = dest_lc[1];
        u[2] = dest_lc[2];
        normalize(u);

        const double d = magnitude(dest_lc);
        double U = 0;
        if(fabs(d) > tol){
            U = -A/pow(d, n) + B/pow(d, m);
        }

        f_out[0] = U * u[0];
        f_out[1] = U * u[1];
        f_out[2] = U * u[2];
    }

    void obstacleCallback(const sensor_msgs::PointCloud2Ptr &obs_msg){
        sensor_msgs::PointCloud obs_lsr, obs_base;
        sensor_msgs::convertPointCloud2ToPointCloud(*obs_msg, obs_lsr);
        tf_listener_.transformPointCloud(obs_lsr.header.frame_id, obs_lsr.header.stamp, obs_lsr, base_link_, obs_base);

        if(obs_base.points.size() == 0){
            obs_[0] = 0;
            obs_[1] = 0;
            obs_[2] = 0;
            return;
        }

        double min_obs[3];
        min_obs[0] = obs_base.points[0].x;
        min_obs[1] = obs_base.points[0].y;
        min_obs[2] = obs_base.points[0].z;

        float min_dist = magnitude(min_obs);

        for(int i=1; i < obs_base.points.size(); i++){
            double obs[3];
            obs[0] = obs_base.points[i].x;
            obs[1] = obs_base.points[i].y;
            obs[2] = obs_base.points[i].z;

            //ROS_INFO("(%f, %f)", obs[0], obs[1]);

            double dist = magnitude(obs);
            if(dist < min_dist){
                min_obs[0] = obs[0];
                min_obs[1] = obs[1];
                min_obs[2] = obs[2];
                min_dist = dist;
            }
        }

        obs_[0] = min_obs[0];
        obs_[1] = min_obs[1];
        obs_[2] = min_obs[2];
    }

    double obs_[3];
    ros::Publisher cmd_pub_;
    ros::Subscriber obs_sub_;
    tf::TransformListener tf_listener_;
    std::string base_link_;
};

int main(int argc, char *argv[]){
    ros::init(argc, argv, "apf_planner");

    ros::NodeHandle node;
    ArtificialPotentialField apf = ArtificialPotentialField(node);
    apf.spin();

    return 0;
}

<|endoftext|>


<commit_before>#ifndef SILICIUM_LINUX_OPEN_HPP
#define SILICIUM_LINUX_OPEN_HPP

#include <silicium/error_or.hpp>
#include <silicium/file_descriptor.hpp>
#include <boost/filesystem/path.hpp>

#ifdef __linux__
#	include <fcntl.h>
#endif

namespace Si
{
	inline error_or<file_descriptor> open_reading(boost::filesystem::path const &name)
	{
		native_file_handle const fd = ::open(name.c_str(), O_RDONLY);
		if (fd < 0)
		{
			return boost::system::error_code(errno, boost::system::system_category());
		}
		return file_descriptor(fd);
	}

	inline error_or<file_descriptor> create_file(boost::filesystem::path const &name)
	{
		native_file_handle const fd = ::open(name.c_str(), O_WRONLY | O_CREAT | O_EXCL, S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH);
		if (fd < 0)
		{
			return boost::system::error_code(errno, boost::system::system_category());
		}
		return file_descriptor(fd);
	}
}

#endif
<commit_msg>implement open_read_write for Linux<commit_after>#ifndef SILICIUM_LINUX_OPEN_HPP
#define SILICIUM_LINUX_OPEN_HPP

#include <silicium/error_or.hpp>
#include <silicium/file_descriptor.hpp>
#include <boost/filesystem/path.hpp>

#ifdef __linux__
#	include <fcntl.h>
#endif

namespace Si
{
	inline error_or<file_descriptor> open_reading(boost::filesystem::path const &name)
	{
		native_file_handle const fd = ::open(name.c_str(), O_RDONLY);
		if (fd < 0)
		{
			return boost::system::error_code(errno, boost::system::system_category());
		}
		return file_descriptor(fd);
	}

	inline error_or<file_descriptor> create_file(boost::filesystem::path const &name)
	{
		native_file_handle const fd = ::open(name.c_str(), O_WRONLY | O_CREAT | O_EXCL, S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH);
		if (fd < 0)
		{
			return boost::system::error_code(errno, boost::system::system_category());
		}
		return file_descriptor(fd);
	}

	inline error_or<file_descriptor> open_read_write(boost::filesystem::path const &name)
	{
		native_file_handle const fd = ::open(name.c_str(), O_RDWR | O_CREAT, S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH);
		if (fd < 0)
		{
			return boost::system::error_code(errno, boost::system::system_category());
		}
		return file_descriptor(fd);
	}
}

#endif
<|endoftext|>