<commit_before>/*
 * The Apache Software License, Version 1.1
 *
 *
 * Copyright (c) 1999-2004 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xalan" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.ibm.com.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */
#include "XercesDOMImplementationBridge.hpp"

#if XERCES_VERSION_MAJOR >= 2
#include <xercesc/dom/deprecated/DOM_DOMImplementation.hpp>
#else
#include <xercesc/dom/DOM_DOMImplementation.hpp>
#endif

#include <xalanc/PlatformSupport/DOMStringHelper.hpp>

#include <xalanc/XercesParserLiaison/XercesDOMException.hpp>

XALAN_CPP_NAMESPACE_BEGIN

XercesDOMImplementationBridge::XercesDOMImplementationBridge(DOM_DOMImplementationType&	theXercesDOMImplementation) :
	XalanDOMImplementation(),
	m_xercesNode(theXercesDOMImplementation)
{
}

XercesDOMImplementationBridge::~XercesDOMImplementationBridge()
{
}

XercesDOMImplementationBridge::XercesDOMImplementationBridge(const XercesDOMImplementationBridge&	theSource) :
	XalanDOMImplementation(theSource),
	m_xercesNode(theSource.m_xercesNode)
{
}

bool
XercesDOMImplementationBridge::hasFeature(
			const XalanDOMString&	feature,
			const XalanDOMString&	version)
{
	return m_xercesNode.hasFeature(c_wstr(feature), c_wstr(version));
}

XalanDocumentType*
XercesDOMImplementationBridge::createDocumentType(
			const XalanDOMString&	qualifiedName,
			const XalanDOMString&	publicId,
			const XalanDOMString&	systemId)
{
	// $$$ ToDo: Fix this!!!
	throw XercesDOMException(XercesDOMException::NO_MODIFICATION_ALLOWED_ERR);

	return 0;
}

XalanDocument*
XercesDOMImplementationBridge::createDocument(
			const XalanDOMString&		namespaceURI,
			const XalanDOMString&		qualifiedName,
			const XalanDocumentType&	doctype)
{
	// $$$ ToDo: Fix this!!!
	throw XercesDOMException(XercesDOMException::NO_MODIFICATION_ALLOWED_ERR);

	return 0;
}

XALAN_CPP_NAMESPACE_END
<commit_msg>Commented out unused parameters and fixed exception code.<commit_after>/*
 * The Apache Software License, Version 1.1
 *
 *
 * Copyright (c) 1999-2004 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xalan" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.ibm.com.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */
#include "XercesDOMImplementationBridge.hpp"

#if XERCES_VERSION_MAJOR >= 2
#include <xercesc/dom/deprecated/DOM_DOMImplementation.hpp>
#else
#include <xercesc/dom/DOM_DOMImplementation.hpp>
#endif

#include <xalanc/PlatformSupport/DOMStringHelper.hpp>

#include <xalanc/XercesParserLiaison/XercesDOMException.hpp>

XALAN_CPP_NAMESPACE_BEGIN

XercesDOMImplementationBridge::XercesDOMImplementationBridge(DOM_DOMImplementationType&	theXercesDOMImplementation) :
	XalanDOMImplementation(),
	m_xercesNode(theXercesDOMImplementation)
{
}

XercesDOMImplementationBridge::~XercesDOMImplementationBridge()
{
}

XercesDOMImplementationBridge::XercesDOMImplementationBridge(const XercesDOMImplementationBridge&	theSource) :
	XalanDOMImplementation(theSource),
	m_xercesNode(theSource.m_xercesNode)
{
}

bool
XercesDOMImplementationBridge::hasFeature(
			const XalanDOMString&	feature,
			const XalanDOMString&	version)
{
	return m_xercesNode.hasFeature(c_wstr(feature), c_wstr(version));
}

XalanDocumentType*
XercesDOMImplementationBridge::createDocumentType(
			const XalanDOMString&	/* qualifiedName */,
			const XalanDOMString&	/* publicId */,
			const XalanDOMString&	/* systemId */)
{
	throw XercesDOMException(XercesDOMException::NOT_SUPPORTED_ERR);

	return 0;
}

XalanDocument*
XercesDOMImplementationBridge::createDocument(
			const XalanDOMString&		/* namespaceURI */,
			const XalanDOMString&		/* qualifiedName */,
			const XalanDocumentType&	/* doctype */)
{
	throw XercesDOMException(XercesDOMException::NOT_SUPPORTED_ERR);

	return 0;
}

XALAN_CPP_NAMESPACE_END
<|endoftext|>


<commit_before>
#include <ros/ros.h>
#include <cv_bridge/cv_bridge.h>
#include <sensor_msgs/image_encodings.h>
#include <opencv2/opencv.hpp>
#include <sensor_msgs/Image.h>
#include <dynamic_reconfigure/server.h>
#include <hanse_object_detection/ObjectDetectionConfig.h>
#include "blobs/blob.h"
#include "blobs/BlobResult.h"
#include <vector>
#include <hanse_msgs/Object.h>

class ObjectDetection {
public:
    ObjectDetection(ros::NodeHandle nh) {
        image_pub = nh.advertise<sensor_msgs::Image>("/image_object_detection", 1);
        object_pub = nh.advertise<hanse_msgs::Object>("/object", 1);
        init();
    }

    void init() {
    }

    void configCallback(hanse_object_detection::ObjectDetectionConfig &config, uint32_t level)
    {
        init();
    }

    void imageCB(const sensor_msgs::ImageConstPtr& visual_img_msg)
    {
        cv_bridge::CvImagePtr cv_ptr;
        try {
            cv_ptr = cv_bridge::toCvCopy(visual_img_msg, sensor_msgs::image_encodings::RGB8);
        } catch (cv_bridge::Exception& e) {
            ROS_ERROR("cv_bridge excepion: %s",e.what());
            return;
        }

        cv::Mat image_rgb = cv_ptr->image;

        std::vector<cv::Mat> channels;
        cv::split(image_rgb, channels);
        cv::Mat gray = channels[0];

        cv::Mat binary;
        cv::threshold(gray, binary, 0, 255, cv::THRESH_BINARY_INV | cv::THRESH_OTSU);

        IplImage *thresh = new IplImage(binary);
        cvDilate(thresh, thresh, NULL, 20);
        cvErode(thresh, thresh, NULL, 20);

        CBlobResult blobs(thresh, NULL, 0);
        blobs.Filter(blobs, B_EXCLUDE, CBlobGetArea(), B_LESS, 100 );

        // Get largest blob.
        int maxArea = 0;
        int maxBlob = -1;
        for (int j = 0; j < blobs.GetNumBlobs(); j++) {
            CBlob *blob = blobs.GetBlob(j);
            if (blob->Area() > maxArea) {
                maxArea = blob->Area();
                maxBlob = j;
            }
        }

        float size = 0;
        float orientation = 0;
        float x = 0;
        float y = 0;

        if (maxBlob >= 0) {
            size = blobs.GetBlob(maxBlob)->Moment(0, 0);

            // First order moments -> mean position
            double m10 = blobs.GetBlob(maxBlob)->Moment(1, 0) / size;
            double m01 = blobs.GetBlob(maxBlob)->Moment(0, 1) / size;
            x = m10;
            y = m01;

            // Second order moments -> orientation
            double mu11 = blobs.GetBlob(maxBlob)->Moment(1, 1) / size;
            double mu20 = blobs.GetBlob(maxBlob)->Moment(2, 0) / size;
            double mu02 = blobs.GetBlob(maxBlob)->Moment(0, 2) / size;
            orientation = 0.5 * atan2( 2 * mu11 , ( mu20 - mu02 ) );

            // Draw blob to gray image.
            binary = binary.setTo(cv::Scalar(0));
            blobs.GetBlob(maxBlob)->FillBlob(thresh, cvScalar(255), 0, 0);
        }

        CvMoments M;
        cvMoments(thresh, &M, 1);

        // Second order moments -> orientation
        double mu11 = cvGetCentralMoment( &M, 1, 1 ) / size;
        double mu20 = cvGetCentralMoment( &M, 2, 0 ) / size;
        double mu02 = cvGetCentralMoment( &M, 0, 2 ) / size;
        orientation = 0.5 * atan2( 2 * mu11 , ( mu20 - mu02 ) );

        cv::line(binary, cv::Point(x, y),
                cv::Point(x + cos(orientation)*200, y + sin(orientation)*200),
                cv::Scalar(120), 4, CV_FILLED);

        // Theta is now the rotation angle reletive to the x axis.
        // We want it relative to the y axis -> 90° ccw
        orientation -= CV_PI / 2;
        if (orientation < -CV_PI) {
            orientation += CV_PI;
        }

        if (orientation < -CV_PI/2) {
            orientation += CV_PI;
        } else if (orientation > CV_PI/2) {
            orientation -= CV_PI;
        }

        size /= (binary.rows * binary.cols);

        hanse_msgs::Object objMsg;
        objMsg.header = visual_img_msg->header;
        objMsg.size = size;
        objMsg.x = x;
        objMsg.y = y;
        objMsg.orientation = orientation;
        object_pub.publish(objMsg);

        cv_bridge::CvImage out_msg;
        out_msg.header   = visual_img_msg->header;
        out_msg.encoding = sensor_msgs::image_encodings::MONO8;
        out_msg.image    = binary;
        image_pub.publish(out_msg.toImageMsg());
    }

private:
    ros::Publisher image_pub;
    ros::Publisher object_pub;
};

int main(int argc, char** argv)
{
  ros::init(argc, argv, "object_detection_node");
  ros::NodeHandle nh("~");

  std::string image_topic = "/camera/rgb/image_color";
  nh.getParam("image_topic", image_topic);

  ObjectDetection od(nh);

  dynamic_reconfigure::Server<hanse_object_detection::ObjectDetectionConfig> server;
  dynamic_reconfigure::Server<hanse_object_detection::ObjectDetectionConfig>::CallbackType f;

  f = boost::bind(&ObjectDetection::configCallback, &od, _1, _2);
  server.setCallback(f);

  ros::Subscriber camSub =
          nh.subscribe<sensor_msgs::Image>(image_topic, 1, boost::bind(&ObjectDetection::imageCB, &od, _1));

  ros::spin();
}
<commit_msg>object detection dynamic reconfigure<commit_after>
#include <ros/ros.h>
#include <cv_bridge/cv_bridge.h>
#include <sensor_msgs/image_encodings.h>
#include <opencv2/opencv.hpp>
#include <sensor_msgs/Image.h>
#include <dynamic_reconfigure/server.h>
#include <hanse_object_detection/ObjectDetectionConfig.h>
#include "blobs/blob.h"
#include "blobs/BlobResult.h"
#include <vector>
#include <hanse_msgs/Object.h>

typedef enum {R, G, B} Channel;

class ObjectDetection {
public:
    ObjectDetection(ros::NodeHandle nh) {
        image_pub = nh.advertise<sensor_msgs::Image>("/image_object_detection", 1);
        object_pub = nh.advertise<hanse_msgs::Object>("/object", 1);

        channel = R;
        inverted = false;
    }

    void configCallback(hanse_object_detection::ObjectDetectionConfig &config, uint32_t level)
    {
        std::string channelStr = config.channel;
        if (channelStr.compare("R")) {
            channel = R;
        } else if (channelStr.compare("G")) {
            channel = G;
        } else if (channelStr.compare("B")) {
            channel = B;
        }
        inverted = config.inverted;
    }

    void imageCB(const sensor_msgs::ImageConstPtr& visual_img_msg)
    {
        cv_bridge::CvImagePtr cv_ptr;
        try {
            cv_ptr = cv_bridge::toCvCopy(visual_img_msg, sensor_msgs::image_encodings::RGB8);
        } catch (cv_bridge::Exception& e) {
            ROS_ERROR("cv_bridge excepion: %s",e.what());
            return;
        }

        cv::Mat image_rgb = cv_ptr->image;

        std::vector<cv::Mat> channels;
        cv::split(image_rgb, channels);
        cv::Mat gray;

        switch (channel) {
        case R:
            gray = channels[0];
            break;
        case G:
            gray = channels[1];
            break;
        case B:
            gray = channels[2];
            break;
        }

        cv::Mat binary;

        if (inverted) {
            cv::threshold(gray, binary, 0, 255, cv::THRESH_BINARY_INV | cv::THRESH_OTSU);
        } else {
            cv::threshold(gray, binary, 0, 255, cv::THRESH_BINARY | cv::THRESH_OTSU);
        }

        IplImage *thresh = new IplImage(binary);
        cvDilate(thresh, thresh, NULL, 5);
        cvErode(thresh, thresh, NULL, 5);

        CBlobResult blobs(thresh, NULL, 0);
        blobs.Filter(blobs, B_EXCLUDE, CBlobGetArea(), B_LESS, 100 );

        // Get largest blob.
        int maxArea = 0;
        int maxBlob = -1;
        for (int j = 0; j < blobs.GetNumBlobs(); j++) {
            CBlob *blob = blobs.GetBlob(j);
            if (blob->Area() > maxArea) {
                maxArea = blob->Area();
                maxBlob = j;
            }
        }

        float size = 0;
        float orientation = 0;
        float x = 0;
        float y = 0;

        if (maxBlob >= 0) {
            size = blobs.GetBlob(maxBlob)->Moment(0, 0);

            // First order moments -> mean position
            double m10 = blobs.GetBlob(maxBlob)->Moment(1, 0) / size;
            double m01 = blobs.GetBlob(maxBlob)->Moment(0, 1) / size;
            x = m10;
            y = m01;

            // Second order moments -> orientation
            double mu11 = blobs.GetBlob(maxBlob)->Moment(1, 1) / size;
            double mu20 = blobs.GetBlob(maxBlob)->Moment(2, 0) / size;
            double mu02 = blobs.GetBlob(maxBlob)->Moment(0, 2) / size;
            orientation = 0.5 * atan2( 2 * mu11 , ( mu20 - mu02 ) );

            // Draw blob to gray image.
            binary = binary.setTo(cv::Scalar(0));
            blobs.GetBlob(maxBlob)->FillBlob(thresh, cvScalar(255), 0, 0);
        }

        CvMoments M;
        cvMoments(thresh, &M, 1);

        // Second order moments -> orientation
        double mu11 = cvGetCentralMoment( &M, 1, 1 ) / size;
        double mu20 = cvGetCentralMoment( &M, 2, 0 ) / size;
        double mu02 = cvGetCentralMoment( &M, 0, 2 ) / size;
        orientation = 0.5 * atan2( 2 * mu11 , ( mu20 - mu02 ) );

        cv::line(binary, cv::Point(x, y),
                cv::Point(x + cos(orientation)*200, y + sin(orientation)*200),
                cv::Scalar(120), 4, CV_FILLED);

        // Theta is now the rotation angle reletive to the x axis.
        // We want it relative to the y axis -> 90° ccw
        orientation -= CV_PI / 2;
        if (orientation < -CV_PI) {
            orientation += CV_PI;
        }

        if (orientation < -CV_PI/2) {
            orientation += CV_PI;
        } else if (orientation > CV_PI/2) {
            orientation -= CV_PI;
        }

        size /= (binary.rows * binary.cols);

        hanse_msgs::Object objMsg;
        objMsg.header = visual_img_msg->header;
        objMsg.size = size;
        objMsg.x = x;
        objMsg.y = y;
        objMsg.orientation = orientation;
        object_pub.publish(objMsg);

        cv_bridge::CvImage out_msg;
        out_msg.header   = visual_img_msg->header;
        out_msg.encoding = sensor_msgs::image_encodings::MONO8;
        out_msg.image    = binary;
        image_pub.publish(out_msg.toImageMsg());
    }

private:
    ros::Publisher image_pub;
    ros::Publisher object_pub;
    Channel channel;
    bool inverted;
};

int main(int argc, char** argv)
{
  ros::init(argc, argv, "object_detection_node");
  ros::NodeHandle nh("~");

  std::string image_topic = "/camera/rgb/image_color";
  nh.getParam("image_topic", image_topic);

  ObjectDetection od(nh);

  dynamic_reconfigure::Server<hanse_object_detection::ObjectDetectionConfig> server;
  dynamic_reconfigure::Server<hanse_object_detection::ObjectDetectionConfig>::CallbackType f;

  f = boost::bind(&ObjectDetection::configCallback, &od, _1, _2);
  server.setCallback(f);

  ros::Subscriber camSub =
          nh.subscribe<sensor_msgs::Image>(image_topic, 1, boost::bind(&ObjectDetection::imageCB, &od, _1));

  ros::spin();
}
<|endoftext|>


<commit_before>/*
 * This is part of the FL library, a C++ Bayesian filtering library
 * (https://github.com/filtering-library)
 *
 * Copyright (c) 2014 Jan Issac (jan.issac@gmail.com)
 * Copyright (c) 2014 Manuel Wuthrich (manuel.wuthrich@gmail.com)
 *
 * Max-Planck Institute for Intelligent Systems, AMD Lab
 * University of Southern California, CLMC Lab
 *
 * This Source Code Form is subject to the terms of the MIT License (MIT).
 * A copy of the license can be found in the LICENSE file distributed with this
 * source code.
 */

/**
 * \file process_model_interface.hpp
 * \date October 2014
 * \author Jan Issac (jan.issac@gmail.com)
 */

#ifndef FL__MODEL__PROCESS__PROCESS_MODEL_INTERFACE_HPP
#define FL__MODEL__PROCESS__PROCESS_MODEL_INTERFACE_HPP

#include <fl/util/traits.hpp>

namespace fl
{

/**
 * \interface ProcessModelInterface
 * \ingroup process_models
 *
 * \brief This reprersents the common process model interface of the form
 *        \f$p(x\mid x_t, u_t, v_t)\f$
 *
 * \tparam State    Type of the state variable \f$x_t\f$
 * \tparam Noise    Type of the noise term \f$v_t\f$
 * \tparam Input    Type of the control input \f$u_t\f$
 */
template <
    typename State,
    typename Noise,
    typename Input = internal::Empty
>
class ProcessModelInterface
    : public internal::ProcessModelType
{
public:
    typedef internal::ProcessModelType ModelType;

public:
    /**
     * Sets the conditional arguments \f$x_t, u_t\f$ of \f$p(x\mid x_t, u_t)\f$
     *
     * \param delta_time    Prediction duration \f$\Delta t\f$
     * \param state         Previous state \f$x_{t}\f$
     * \param input         Control input \f$u_t\f$
     *
     * Once the conditional have been set, may either sample from this model
     * since it also represents a conditional distribution or you may map
     * a SNV noise term \f$v_t\f$ onto the distribution using
     * \c map_standard_variate(\f$v_t\f$) if implemented.
     */
    virtual void condition(const double& delta_time,
                           const State& state,
                           const Input& input = Input()) { }

    /**
     * Predicts the state conditioned on the previous state and input.
     *
     * \param delta_time    Prediction duration \f$\Delta t\f$
     * \param state         Previous state \f$x_{t}\f$
     * \param noise         Additive or non-Additive noise \f$v_t\f$
     * \param input         Control input \f$u_t\f$
     *
     * \return State \f$x_{t+1}\sim p(x\mid x_t, u_t)\f$
     */

    /// \todo have a default argument for the input, a default function which
    /// has to be implemented by the derived classes
    virtual State predict_state(double delta_time,
                                const State& state,
                                const Noise& noise,
                                const Input& input) = 0;

    /**
     * \return \f$\dim(x_t)\f$, dimension of the state
     */
    virtual constexpr int state_dimension() const = 0;

    /**
     * \return \f$\dim(v_t)\f$, dimension of the noise
     */
    virtual constexpr int noise_dimension() const = 0;

    /**
     * \return \f$\dim(u_t)\f$, dimension of the control input
     */
    virtual constexpr int input_dimension() const = 0;
};

template <
    typename State_,
    typename Input_,
    typename Noise_,
    int Id = 0
>
class StateTransitionFunction
{
public:
    typedef State_ State;
    typedef Input_ Input;
    typedef Noise_ Noise;

    virtual State state(const State& prev_state,
                        const Input& input,
                        const Noise& noise) const = 0;

    /**
     * \return Dimension of the state variable $\f$x\f$
     */
    virtual int state_dimension() const = 0;

    /**
     * \return Dimension of the noise term \f$w\f$
     */
    virtual int noise_dimension() const = 0;

    /**
     * \return Dimension of the input \f$u_t\f$
     */
    virtual int input_dimension() const = 0;

    /**
     * \return Model id number
     *
     * In case of multiple sensors of the same kind, this function returns the
     * id of the individual model.
     */
    virtual int id() const { return Id; }

    /**
     * Sets the model id
     *
     * \param new_id    Model's new ID
     */
    virtual void id(int) { /* const ID */ }
};

}

#endif
<commit_msg>Moved StateTransitionFunction to the top as the main model. Removed template argument Input default value<commit_after>/*
 * This is part of the FL library, a C++ Bayesian filtering library
 * (https://github.com/filtering-library)
 *
 * Copyright (c) 2014 Jan Issac (jan.issac@gmail.com)
 * Copyright (c) 2014 Manuel Wuthrich (manuel.wuthrich@gmail.com)
 *
 * Max-Planck Institute for Intelligent Systems, AMD Lab
 * University of Southern California, CLMC Lab
 *
 * This Source Code Form is subject to the terms of the MIT License (MIT).
 * A copy of the license can be found in the LICENSE file distributed with this
 * source code.
 */

/**
 * \file process_model_interface.hpp
 * \date October 2014
 * \author Jan Issac (jan.issac@gmail.com)
 */

#ifndef FL__MODEL__PROCESS__PROCESS_MODEL_INTERFACE_HPP
#define FL__MODEL__PROCESS__PROCESS_MODEL_INTERFACE_HPP

#include <fl/util/traits.hpp>

namespace fl
{

template <
    typename State_,
    typename Noise_,
    typename Input_,
    int Id = 0
>
class StateTransitionFunction
{
public:
    typedef State_ State;
    typedef Noise_ Noise;
    typedef Input_ Input;

    virtual State state(const State& prev_state,
                        const Noise& noise,
                        const Input& input) const = 0;

    /**
     * \return Dimension of the state variable $\f$x\f$
     */
    virtual int state_dimension() const = 0;

    /**
     * \return Dimension of the noise term \f$w\f$
     */
    virtual int noise_dimension() const = 0;

    /**
     * \return Dimension of the input \f$u_t\f$
     */
    virtual int input_dimension() const = 0;

    /**
     * \return Model id number
     *
     * In case of multiple sensors of the same kind, this function returns the
     * id of the individual model.
     */
    virtual int id() const { return Id; }

    /**
     * Sets the model id
     *
     * \param new_id    Model's new ID
     */
    virtual void id(int) { /* const ID */ }
};

/**
 * \interface ProcessModelInterface
 * \ingroup process_models
 *
 * \brief This reprersents the common process model interface of the form
 *        \f$p(x\mid x_t, u_t, v_t)\f$
 *
 * \tparam State    Type of the state variable \f$x_t\f$
 * \tparam Noise    Type of the noise term \f$v_t\f$
 * \tparam Input    Type of the control input \f$u_t\f$
 */
template <
    typename State,
    typename Noise,
    typename Input
>
class ProcessModelInterface
    : public internal::ProcessModelType
{
public:
    typedef internal::ProcessModelType ModelType;

public:
    /**
     * Sets the conditional arguments \f$x_t, u_t\f$ of \f$p(x\mid x_t, u_t)\f$
     *
     * \param delta_time    Prediction duration \f$\Delta t\f$
     * \param state         Previous state \f$x_{t}\f$
     * \param input         Control input \f$u_t\f$
     *
     * Once the conditional have been set, may either sample from this model
     * since it also represents a conditional distribution or you may map
     * a SNV noise term \f$v_t\f$ onto the distribution using
     * \c map_standard_variate(\f$v_t\f$) if implemented.
     */
    virtual void condition(const double& delta_time,
                           const State& state,
                           const Input& input = Input()) { }

    /**
     * Predicts the state conditioned on the previous state and input.
     *
     * \param delta_time    Prediction duration \f$\Delta t\f$
     * \param state         Previous state \f$x_{t}\f$
     * \param noise         Additive or non-Additive noise \f$v_t\f$
     * \param input         Control input \f$u_t\f$
     *
     * \return State \f$x_{t+1}\sim p(x\mid x_t, u_t)\f$
     */

    /// \todo have a default argument for the input, a default function which
    /// has to be implemented by the derived classes
    virtual State predict_state(double delta_time,
                                const State& state,
                                const Noise& noise,
                                const Input& input) = 0;

    /**
     * \return \f$\dim(x_t)\f$, dimension of the state
     */
    virtual constexpr int state_dimension() const = 0;

    /**
     * \return \f$\dim(v_t)\f$, dimension of the noise
     */
    virtual constexpr int noise_dimension() const = 0;

    /**
     * \return \f$\dim(u_t)\f$, dimension of the control input
     */
    virtual constexpr int input_dimension() const = 0;
};

}

#endif
<|endoftext|>


<commit_before>#include<malloc.h>
#include<stdio.h>
#define OK 1
#define ERROR 0
#define STACK_INIT_SIZE 100 // 存储空间初始分配量
#define STACKINCREMENT 10 // 存储空间分配增量

typedef int SElemType; // 定义栈元素类型
typedef int Status; // Status是函数的类型,其值是函数结果状态代码，如OK等

struct SqStack
{
     SElemType *base; // 在栈构造之前和销毁之后，base的值为NULL
     SElemType *top; // 栈顶指针
     int stacksize;  // 当前已分配的存储空间，以元素为单位

     Status InitStack()
	{
	// 构造一个空栈S，该栈预定义大小为STACK_INIT_SIZE
	// 请补全代码
		base=(SElemType*) malloc(STACK_INIT_SIZE*(sizeof(SElemType)));
		if(base=NULL)return ERROR;
		top=base+1;
		stacksize=STACK_INIT_SIZE;

		return OK;
	}

	Status Push(SElemType e)
	{
		// 在栈S中插入元素e为新的栈顶元素
		// 请补全代码
		if(top-base>=stacksize){

			base=(SElemType *) realloc(base,(stacksize+STACKINCREMENT)*sizeof(SElemType));

			if(base==NULL){

				return ERROR;
			}
		}else{

			*top=e;
			top++;
		}

		return OK;

	}

	Status Pop(SElemType &e)
	{
		// 若栈不空，则删除S的栈顶元素，用e返回其值，并返回OK；否则返回ERROR
		// 请补全代码
		if( top-base<=1){
			return ERROR;
		}

		e=*(--top);

		return OK;
	}

	Status GetTop(SElemType &e)
	{
	// 若栈不空，则用e返回S的栈顶元素，并返回OK；否则返回ERROR
	// 请补全代码
		if( top-base<=1){
			return ERROR;
		}

		e=*(top-1);

		return OK;

	}

	int StackLength()
	{
	// 返回栈S的元素个数
	// 请补全代码

		return top-base-1;

	}

	Status StackTraverse()
	{
	// 从栈顶到栈底依次输出栈中的每个元素
		SElemType *p = (SElemType *)malloc(sizeof(SElemType));
		p = *top;        //请填空
		if(StackLength() ==0 )printf("The Stack is Empty!"); //请填空
		else
		{
			printf("The Stack is: ");
			p--;
			while(p-base>1)            //请填空
			{
				printf("%d ", *p);
				p--;               //请填空
			}
		}
		printf("\n");
		return OK;
	}
}; // 顺序栈

int main()
{
     int a;
     SqStack S;
	SElemType x, e;
     if(S.InitStack())    // 判断顺序表是否创建成功，请填空
{
	printf("A Stack Has Created.\n");
}
while(1)
	{
    printf("1:Push \n2:Pop \n3:Get the Top \n4:Return the Length of the Stack\n5:Load the Stack\n0:Exit\nPlease choose:\n");
	scanf("%d",&a);
		switch(a)
		{
			case 1: scanf("%d", &x);
		      if(S.Push(x)) printf("Push Error!\n"); // 判断Push是否合法，请填空
		      else printf("The Element %d is Successfully Pushed!\n", x);
		      break;
		case 2: if(S.Pop(e)) printf("Pop Error!\n"); // 判断Pop是否合法，请填空
			  else printf("The Element %d is Successfully Poped!\n", e);
		  	  break;
		case 3: if(S.top(e))printf("Get Top Error!\n"); // 判断Get Top是否合法，请填空
			  else printf("The Top Element is %d!\n", e);
		   	  break;
			case 4: printf("The Length of the Stack is %d!\n",S.StackLength()); //请填空
				  break;
			case 5: S.StackTraverse()  //请填空
				  break;
			case 0: return 1;
		}
	}
}<commit_msg>update uoj8583<commit_after>#include<malloc.h>
#include<stdio.h>
#define OK 1
#define ERROR 0
#define STACK_INIT_SIZE 100 // 存储空间初始分配量
#define STACKINCREMENT 10 // 存储空间分配增量

typedef int SElemType; // 定义栈元素类型
typedef int Status; // Status是函数的类型,其值是函数结果状态代码，如OK等

struct SqStack
{
     SElemType *base; // 在栈构造之前和销毁之后，base的值为NULL
     SElemType *top; // 栈顶指针
     int stacksize;  // 当前已分配的存储空间，以元素为单位

     Status InitStack()
	{
	// 构造一个空栈S，该栈预定义大小为STACK_INIT_SIZE
	// 请补全代码
		base=(SElemType*) malloc(STACK_INIT_SIZE*(sizeof(SElemType)));
		if(base=NULL)return ERROR;
		top=base+1;
		stacksize=STACK_INIT_SIZE;

		return OK;
	}

	Status Push(SElemType e)
	{
		// 在栈S中插入元素e为新的栈顶元素
		// 请补全代码
		if(top-base>=stacksize){

			base=(SElemType *) realloc(base,(stacksize+STACKINCREMENT)*sizeof(SElemType));

			if(base==NULL){

				return ERROR;
			}
		}else{

			*top=e;
			top++;
		}

		return OK;

	}

	Status Pop(SElemType &e)
	{
		// 若栈不空，则删除S的栈顶元素，用e返回其值，并返回OK；否则返回ERROR
		// 请补全代码
		if( top-base<=1){
			return ERROR;
		}

		e=*(--top);

		return OK;
	}

	Status GetTop(SElemType &e)
	{
	// 若栈不空，则用e返回S的栈顶元素，并返回OK；否则返回ERROR
	// 请补全代码
		if( top-base<=1){
			return ERROR;
		}

		e=*(top-1);

		return OK;

	}

	int StackLength()
	{
	// 返回栈S的元素个数
	// 请补全代码

		return top-base-1;

	}

	Status StackTraverse()
	{
	// 从栈顶到栈底依次输出栈中的每个元素
		SElemType *p = (SElemType *)malloc(sizeof(SElemType));
		p = *top;        //请填空
		if(StackLength() ==0 )printf("The Stack is Empty!"); //请填空
		else
		{
			printf("The Stack is: ");
			p--;
			while(p-base>1)            //请填空
			{
				printf("%d ", *p);
				p--;               //请填空
			}
		}
		printf("\n");
		return OK;
	}
}; // 顺序栈

int main()
{
     int a;
     SqStack S;
	SElemType x, e;
     if(S.InitStack())    // 判断顺序表是否创建成功，请填空
{
	printf("A Stack Has Created.\n");
}
while(1)
	{
    printf("1:Push \n2:Pop \n3:Get the Top \n4:Return the Length of the Stack\n5:Load the Stack\n0:Exit\nPlease choose:\n");
	scanf("%d",&a);
		switch(a)
		{
			case 1: scanf("%d", &x);
		      if(S.Push(x)) printf("Push Error!\n"); // 判断Push是否合法，请填空
		      else printf("The Element %d is Successfully Pushed!\n", x);
		      break;
		case 2: if(S.Pop(e)) printf("Pop Error!\n"); // 判断Pop是否合法，请填空
			  else printf("The Element %d is Successfully Poped!\n", e);
		  	  break;
		case 3: if(S.GetTop(e))printf("Get Top Error!\n"); // 判断Get Top是否合法，请填空
			  else printf("The Top Element is %d!\n", e);
		   	  break;
			case 4: printf("The Length of the Stack is %d!\n",S.StackLength()); //请填空
				  break;
			case 5: S.StackTraverse();  //请填空
				  break;
			case 0: return 1;
		}
	}
}<|endoftext|>


<commit_before>#ifndef VECRAND_H
#define VECRAND_H
#ifdef VEC2D
#define NDIM 2
#else
#ifndef VEC3D
#define VEC3D
#endif
#define NDIM 3
#endif
#include <iostream>
#include <ctime>
#include <vector>
#include <cmath>

#include <boost/random/mersenne_twister.hpp>
#include <boost/random/variate_generator.hpp>
#include <boost/random/normal_distribution.hpp>

#include "vec.hpp"

using namespace std;

#ifdef LONGFLOAT
typedef long double flt;
inline flt cbrt(flt n){return cbrtl(n);};
inline flt expm1(flt n){return expm1l(n);};
inline flt copysign(flt n, flt m){return copysignl(n,m);};
inline flt remainder(flt n, flt m){return remainderl(n,m);};
inline flt round(flt n){return roundl(n);};
#else
typedef double flt;
#endif

#ifdef VEC2D
typedef Vector2<flt> Vec;
#else
typedef Vector3<flt> Vec;
#endif
typedef Numvector<flt, 2> Pair;
typedef Nvector<Vec, 2> VecPair;
using namespace std;

const flt OVERNDIM = ((flt) 1.0)/NDIM;

inline Vector2<flt> vec(double x, double y){
    return Vector2<flt>(x,y);
};

inline Vector3<flt> vec(double x, double y, double z){
    return Vector3<flt>(x,y,z);
};

inline uint vecsize(){return sizeof(Vec);}

typedef boost::mt19937 engine;
typedef boost::normal_distribution<flt> normdistribution;
typedef boost::uniform_01<flt, flt> lindistribution;
typedef boost::variate_generator<engine&, normdistribution > normgenerator;
typedef boost::variate_generator<engine&, lindistribution > lingenerator;

flt rand01();
Vec randVec();
Vec randVecBoxed();
#ifdef VEC3D
Vec randVecSphere(flt radius=1);
#endif

unsigned int seed(unsigned int n);
unsigned int seed();

class gaussVec {
    protected:
        normdistribution distro;
        normgenerator gauss;
    public:
        gaussVec(flt sigma);
        void set(flt sigma){distro = normdistribution(0,sigma);};
#ifdef VEC2D
        Vec generate(){return Vec(gauss(),gauss());};
#else
        Vec generate(){return Vec(gauss(),gauss(),gauss());};
#endif
};

class bivariateGauss {
    protected:
        normdistribution distro;
        normgenerator gauss;
        flt x11;
        flt x21;
        flt x22;

    public:
        bivariateGauss(const flt s1=1, const flt s2=1, const flt corr=0);
        void set(const flt s1, const flt s2, const flt corr);
        Pair generate();
#ifdef VEC2D
        Vec genVec(){return Vec(gauss(), gauss());};
#else
        Vec genVec(){return Vec(gauss(), gauss(), gauss());};
#endif
        VecPair genVecs();
};

long double toLD(double e);
double fromLD(long double e);
vector<long double> LDVector(vector<double> dists);

#endif
<commit_msg>Fixed function collision error on Mac OS X clang<commit_after>#ifndef VECRAND_H
#define VECRAND_H
#ifdef VEC2D
#define NDIM 2
#else
#ifndef VEC3D
#define VEC3D
#endif
#define NDIM 3
#endif
#include <iostream>
#include <ctime>
#include <vector>
#include <cmath>

#include <boost/random/mersenne_twister.hpp>
#include <boost/random/variate_generator.hpp>
#include <boost/random/normal_distribution.hpp>

#include "vec.hpp"

using namespace std;

#ifdef LONGFLOAT
    typedef long double flt;

    // on MAC OS, g++ is short for clang, and they already define the following functions pretty much
    // the same way I do
    #ifndef __clang__
        inline flt cbrt(flt n){return cbrtl(n);};
        inline flt expm1(flt n){return expm1l(n);};
        inline flt copysign(flt n, flt m){return copysignl(n,m);};
        inline flt remainder(flt n, flt m){return remainderl(n,m);};
        inline flt round(flt n){return roundl(n);};
    #endif
#else
    typedef double flt;
#endif

#ifdef VEC2D
    typedef Vector2<flt> Vec;
#else
    typedef Vector3<flt> Vec;
#endif
typedef Numvector<flt, 2> Pair;
typedef Nvector<Vec, 2> VecPair;
using namespace std;

const flt OVERNDIM = ((flt) 1.0)/NDIM;

inline Vector2<flt> vec(double x, double y){
    return Vector2<flt>(x,y);
};

inline Vector3<flt> vec(double x, double y, double z){
    return Vector3<flt>(x,y,z);
};

inline uint vecsize(){return sizeof(Vec);}

typedef boost::mt19937 engine;
typedef boost::normal_distribution<flt> normdistribution;
typedef boost::uniform_01<flt, flt> lindistribution;
typedef boost::variate_generator<engine&, normdistribution > normgenerator;
typedef boost::variate_generator<engine&, lindistribution > lingenerator;

flt rand01();
Vec randVec();
Vec randVecBoxed();
#ifdef VEC3D
Vec randVecSphere(flt radius=1);
#endif

unsigned int seed(unsigned int n);
unsigned int seed();

class gaussVec {
    protected:
        normdistribution distro;
        normgenerator gauss;
    public:
        gaussVec(flt sigma);
        void set(flt sigma){distro = normdistribution(0,sigma);};
#ifdef VEC2D
        Vec generate(){return Vec(gauss(),gauss());};
#else
        Vec generate(){return Vec(gauss(),gauss(),gauss());};
#endif
};

class bivariateGauss {
    protected:
        normdistribution distro;
        normgenerator gauss;
        flt x11;
        flt x21;
        flt x22;

    public:
        bivariateGauss(const flt s1=1, const flt s2=1, const flt corr=0);
        void set(const flt s1, const flt s2, const flt corr);
        Pair generate();
#ifdef VEC2D
        Vec genVec(){return Vec(gauss(), gauss());};
#else
        Vec genVec(){return Vec(gauss(), gauss(), gauss());};
#endif
        VecPair genVecs();
};

long double toLD(double e);
double fromLD(long double e);
vector<long double> LDVector(vector<double> dists);

#endif
<|endoftext|>


<commit_before>// Copyright (c) 2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <string>

#include "version.h"

// Name of client reported in the 'version' message. Report the same name
// for both bitcoind and bitcoin-qt, to make it harder for attackers to
// target servers or GUI users specifically.
const std::string CLIENT_NAME("Satoshi");

// Client version number
#define CLIENT_VERSION_SUFFIX   "-cgb"

// The following part of the code determines the CLIENT_BUILD variable.
// Several mechanisms are used for this:
// * first, if HAVE_BUILD_INFO is defined, include build.h, a file that is
//   generated by the build environment, possibly containing the output
//   of git-describe in a macro called BUILD_DESC
// * secondly, if this is an exported version of the code, GIT_ARCHIVE will
//   be defined (automatically using the export-subst git attribute), and
//   GIT_COMMIT will contain the commit id.
// * then, three options exist for determining CLIENT_BUILD:
//   * if BUILD_DESC is defined, use that literally (output of git-describe)
//   * if not, but GIT_COMMIT is defined, use v[maj].[min].[rev].[build]-g[commit]
//   * otherwise, use v[maj].[min].[rev].[build]-unk
// finally CLIENT_VERSION_SUFFIX is added

// First, include build.h if requested
#ifdef HAVE_BUILD_INFO
#    include "build.h"
#endif

// git will put "#define GIT_ARCHIVE 1" on the next line inside archives.
#define GIT_ARCHIVE 1
#ifdef GIT_ARCHIVE
#    define GIT_COMMIT_ID "6b6dfda"
#    define GIT_COMMIT_DATE "$Format:%cD"
#endif

#define BUILD_DESC_FROM_COMMIT(maj,min,rev,build,commit) \
    "v" DO_STRINGIZE(maj) "." DO_STRINGIZE(min) "." DO_STRINGIZE(rev) "." DO_STRINGIZE(build) "-g" commit

#define BUILD_DESC_FROM_UNKNOWN(maj,min,rev,build) \
    "v" DO_STRINGIZE(maj) "." DO_STRINGIZE(min) "." DO_STRINGIZE(rev) "." DO_STRINGIZE(build) "-unk"

#ifndef BUILD_DESC
#    ifdef GIT_COMMIT_ID
#        define BUILD_DESC BUILD_DESC_FROM_COMMIT(DISPLAY_VERSION_MAJOR, DISPLAY_VERSION_MINOR, DISPLAY_VERSION_REVISION, DISPLAY_VERSION_BUILD, GIT_COMMIT_ID)
#    else
#        define BUILD_DESC BUILD_DESC_FROM_UNKNOWN(DISPLAY_VERSION_MAJOR, DISPLAY_VERSION_MINOR, DISPLAY_VERSION_REVISION, DISPLAY_VERSION_BUILD)
#    endif
#endif

#ifndef BUILD_DATE
#    ifdef GIT_COMMIT_DATE
#        define BUILD_DATE GIT_COMMIT_DATE
#    else
#        define BUILD_DATE __DATE__ ", " __TIME__
#    endif
#endif

const std::string CLIENT_BUILD(BUILD_DESC CLIENT_VERSION_SUFFIX);
const std::string CLIENT_DATE(BUILD_DATE);
<commit_msg>Revert "Git commit 6b6dfda"<commit_after>// Copyright (c) 2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <string>

#include "version.h"

// Name of client reported in the 'version' message. Report the same name
// for both bitcoind and bitcoin-qt, to make it harder for attackers to
// target servers or GUI users specifically.
const std::string CLIENT_NAME("Satoshi");

// Client version number
#define CLIENT_VERSION_SUFFIX   "-cgb"

// The following part of the code determines the CLIENT_BUILD variable.
// Several mechanisms are used for this:
// * first, if HAVE_BUILD_INFO is defined, include build.h, a file that is
//   generated by the build environment, possibly containing the output
//   of git-describe in a macro called BUILD_DESC
// * secondly, if this is an exported version of the code, GIT_ARCHIVE will
//   be defined (automatically using the export-subst git attribute), and
//   GIT_COMMIT will contain the commit id.
// * then, three options exist for determining CLIENT_BUILD:
//   * if BUILD_DESC is defined, use that literally (output of git-describe)
//   * if not, but GIT_COMMIT is defined, use v[maj].[min].[rev].[build]-g[commit]
//   * otherwise, use v[maj].[min].[rev].[build]-unk
// finally CLIENT_VERSION_SUFFIX is added

// First, include build.h if requested
#ifdef HAVE_BUILD_INFO
#    include "build.h"
#endif

// git will put "#define GIT_ARCHIVE 1" on the next line inside archives.
#define GIT_ARCHIVE 1
#ifdef GIT_ARCHIVE
#    define GIT_COMMIT_ID "32a928e"
#    define GIT_COMMIT_DATE "$Format:%cD"
#endif

#define BUILD_DESC_FROM_COMMIT(maj,min,rev,build,commit) \
    "v" DO_STRINGIZE(maj) "." DO_STRINGIZE(min) "." DO_STRINGIZE(rev) "." DO_STRINGIZE(build) "-g" commit

#define BUILD_DESC_FROM_UNKNOWN(maj,min,rev,build) \
    "v" DO_STRINGIZE(maj) "." DO_STRINGIZE(min) "." DO_STRINGIZE(rev) "." DO_STRINGIZE(build) "-unk"

#ifndef BUILD_DESC
#    ifdef GIT_COMMIT_ID
#        define BUILD_DESC BUILD_DESC_FROM_COMMIT(DISPLAY_VERSION_MAJOR, DISPLAY_VERSION_MINOR, DISPLAY_VERSION_REVISION, DISPLAY_VERSION_BUILD, GIT_COMMIT_ID)
#    else
#        define BUILD_DESC BUILD_DESC_FROM_UNKNOWN(DISPLAY_VERSION_MAJOR, DISPLAY_VERSION_MINOR, DISPLAY_VERSION_REVISION, DISPLAY_VERSION_BUILD)
#    endif
#endif

#ifndef BUILD_DATE
#    ifdef GIT_COMMIT_DATE
#        define BUILD_DATE GIT_COMMIT_DATE
#    else
#        define BUILD_DATE __DATE__ ", " __TIME__
#    endif
#endif

const std::string CLIENT_BUILD(BUILD_DESC CLIENT_VERSION_SUFFIX);
const std::string CLIENT_DATE(BUILD_DATE);
<|endoftext|>


<commit_before>#include "version.hpp"

// Get the git version macro from the build system
#include "vg_git_version.hpp"

// Do the same for the build environment info
#include "vg_environment_version.hpp"

#include <iostream>
#include <sstream>

// If the VG_GIT_VERSION deosn't exist at all, define a placeholder
// This lets us be somewhat robust to undeterminable versions
#ifndef VG_GIT_VERSION
    #define VG_GIT_VERSION "not-from-git"
#endif

// Define a way to quote macro values.
// See https://stackoverflow.com/a/196093
#define QUOTE(arg) #arg
// We need another level to get the macro's value and not its name.
#define STR(macro) QUOTE(macro)

// Work out the standard library version
#ifdef _LIBCPP_VERSION
    #define VG_STANDARD_LIBRARY_VERSION ("libc++ " STR(_LIBCPP_VERSION))
#endif
#ifdef __GLIBCXX__
    #define VG_STANDARD_LIBRARY_VERSION ("libstd++ " STR(__GLIBCXX__))
#endif
#ifndef VG_STANDARD_LIBRARY_VERSION
    #define VG_STANDARD_LIBRARY_VERSION "unknown standard library"
#endif

namespace vg {

using namespace std;

// Define all the strings as the macros' values
const string Version::VERSION = VG_GIT_VERSION;
const string Version::COMPILER = VG_COMPILER_VERSION;
const string Version::STANDARD_LIBRARY = VG_STANDARD_LIBRARY_VERSION;
const string Version::OS = VG_OS;
const string Version::BUILD_USER = VG_BUILD_USER;
const string Version::BUILD_HOST = VG_BUILD_HOST;

// Keep the list of codenames.
// Add new codenames here
const unordered_map<string, string> Version::codenames = {
    {"v1.8.0", "Vallata"},
    {"v1.9.0", "Miglionico"},
    {"v1.10.0", "Rionero"},
    {"v1.11.0", "Cairano"},
    {"v1.12.0", "Parolise"},
    {"v1.12.1", "Parolise"},
    {"v1.13.0", "Moschiano"},
    {"v1.14.0", "Quadrelle"},
    {"v1.15.0", "Tufo"},
    {"v1.16.0", "Rotondi"},
    {"v1.17.0", "Candida"},
    {"v1.18.0", "Zungoli"},
    {"v1.19.0", "Tramutola"},
    {"v1.20.0", "Ginestra"},
    {"v1.21.0", "Fanano"},
    {"v1.22.0", "Rotella"},
    {"v1.23.0", "Lavello"},
    {"v1.24.0", "Montieri"},
    {"v1.25.0", "Apice"},
    {"v1.26.0", "Stornara"},
    {"v1.26.1", "Stornara"},
    {"v1.27.0", "Deliceto"},
    {"v1.28.0", "Acquafredda"},
    {"v1.29.0", "Sospiro"},
    {"v1.30.0", "Carentino"},
    {"v1.31.0", "Caffaraccia"},
    {"v1.32.0", "Sedlo"},
    {"v1.33.0", "Moscona"},
    {"v1.34.0", "Arguello"},
    {"v1.35.0", "Ghizzano"},
    {"v1.36.0", "Cibottola"}
    // Add more codenames here
};

string Version::get_version() {
    return VERSION;
}

string Version::get_release() {
    auto dash = VERSION.find('-');
    if (dash == -1) {
        // Pure tag versions have no dash
        return VERSION;
    } else {
        // Otherwise it is tag-count-ghash and the tag describes the release
        return VERSION.substr(0, dash);
    }
}

string Version::get_codename() {
    auto release = get_release();

    auto found = codenames.find(release);

    if (found == codenames.end()) {
        // No known codename for this release.
        // Return an empty string so we can just not show it.
        return "";
    } else {
        // We have a known codename!
        return found->second;
    }
}

string Version::get_short() {
    stringstream s;
    s << VERSION;

    auto codename = get_codename();
    if (!codename.empty()) {
        // Add the codename if we have one
        s << " \"" << codename << "\"";
    }

    return s.str();
}

string Version::get_long() {
    stringstream s;
    s << "vg version " << get_short() << endl;
    s << "Compiled with " << COMPILER << " on " << OS << endl;
    s << "Linked against " << STANDARD_LIBRARY << endl;
    s << "Built by " << BUILD_USER << "@" << BUILD_HOST;
    return s.str();
}

}
<commit_msg>Add another patch release<commit_after>#include "version.hpp"

// Get the git version macro from the build system
#include "vg_git_version.hpp"

// Do the same for the build environment info
#include "vg_environment_version.hpp"

#include <iostream>
#include <sstream>

// If the VG_GIT_VERSION deosn't exist at all, define a placeholder
// This lets us be somewhat robust to undeterminable versions
#ifndef VG_GIT_VERSION
    #define VG_GIT_VERSION "not-from-git"
#endif

// Define a way to quote macro values.
// See https://stackoverflow.com/a/196093
#define QUOTE(arg) #arg
// We need another level to get the macro's value and not its name.
#define STR(macro) QUOTE(macro)

// Work out the standard library version
#ifdef _LIBCPP_VERSION
    #define VG_STANDARD_LIBRARY_VERSION ("libc++ " STR(_LIBCPP_VERSION))
#endif
#ifdef __GLIBCXX__
    #define VG_STANDARD_LIBRARY_VERSION ("libstd++ " STR(__GLIBCXX__))
#endif
#ifndef VG_STANDARD_LIBRARY_VERSION
    #define VG_STANDARD_LIBRARY_VERSION "unknown standard library"
#endif

namespace vg {

using namespace std;

// Define all the strings as the macros' values
const string Version::VERSION = VG_GIT_VERSION;
const string Version::COMPILER = VG_COMPILER_VERSION;
const string Version::STANDARD_LIBRARY = VG_STANDARD_LIBRARY_VERSION;
const string Version::OS = VG_OS;
const string Version::BUILD_USER = VG_BUILD_USER;
const string Version::BUILD_HOST = VG_BUILD_HOST;

// Keep the list of codenames.
// Add new codenames here
const unordered_map<string, string> Version::codenames = {
    {"v1.8.0", "Vallata"},
    {"v1.9.0", "Miglionico"},
    {"v1.10.0", "Rionero"},
    {"v1.11.0", "Cairano"},
    {"v1.12.0", "Parolise"},
    {"v1.12.1", "Parolise"},
    {"v1.13.0", "Moschiano"},
    {"v1.14.0", "Quadrelle"},
    {"v1.15.0", "Tufo"},
    {"v1.16.0", "Rotondi"},
    {"v1.17.0", "Candida"},
    {"v1.18.0", "Zungoli"},
    {"v1.19.0", "Tramutola"},
    {"v1.20.0", "Ginestra"},
    {"v1.21.0", "Fanano"},
    {"v1.22.0", "Rotella"},
    {"v1.23.0", "Lavello"},
    {"v1.24.0", "Montieri"},
    {"v1.25.0", "Apice"},
    {"v1.26.0", "Stornara"},
    {"v1.26.1", "Stornara"},
    {"v1.27.0", "Deliceto"},
    {"v1.27.1", "Deliceto"},
    {"v1.28.0", "Acquafredda"},
    {"v1.29.0", "Sospiro"},
    {"v1.30.0", "Carentino"},
    {"v1.31.0", "Caffaraccia"},
    {"v1.32.0", "Sedlo"},
    {"v1.33.0", "Moscona"},
    {"v1.34.0", "Arguello"},
    {"v1.35.0", "Ghizzano"},
    {"v1.36.0", "Cibottola"}
    // Add more codenames here
};

string Version::get_version() {
    return VERSION;
}

string Version::get_release() {
    auto dash = VERSION.find('-');
    if (dash == -1) {
        // Pure tag versions have no dash
        return VERSION;
    } else {
        // Otherwise it is tag-count-ghash and the tag describes the release
        return VERSION.substr(0, dash);
    }
}

string Version::get_codename() {
    auto release = get_release();

    auto found = codenames.find(release);

    if (found == codenames.end()) {
        // No known codename for this release.
        // Return an empty string so we can just not show it.
        return "";
    } else {
        // We have a known codename!
        return found->second;
    }
}

string Version::get_short() {
    stringstream s;
    s << VERSION;

    auto codename = get_codename();
    if (!codename.empty()) {
        // Add the codename if we have one
        s << " \"" << codename << "\"";
    }

    return s.str();
}

string Version::get_long() {
    stringstream s;
    s << "vg version " << get_short() << endl;
    s << "Compiled with " << COMPILER << " on " << OS << endl;
    s << "Linked against " << STANDARD_LIBRARY << endl;
    s << "Built by " << BUILD_USER << "@" << BUILD_HOST;
    return s.str();
}

}
<|endoftext|>


<commit_before>// -------------------------------------------------------------------------------------
//         Author: Sourabh S Joshi (cbrghostrider); Copyright - All rights reserved.
//                       For email, run on linux (perl v5.8.5):
//   perl -e 'print pack "H*","736f75726162682e732e6a6f73686940676d61696c2e636f6d0a"'
// -------------------------------------------------------------------------------------

// Functionally correct solution. works for small inputs, but needs more
// algorithmic optimization for large inputs
#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
#include <assert.h>

using namespace std;
typedef unsigned int Ways;
#define MODNUM (1000000007)

class HyperCuboid {
private:
    const int nsteps; //the number of steps to be taken
    vector<int> spos; //the starting position in the hypercube
    vector<int> dims; //the dimensions of the hypercube
    Ways *cache[2];   //stores prev and next values of steps over the hypercube

    //cache alloc/dealloc methods
    void allocateCache();
    void freeCache();

    //checking, reading, and writing to indexes
    bool onBoard(const vector<int>& index);
    inline Ways& position(const vector<int>& index, int prevOrNext);
    inline void writeIndex(const vector<int>& index, Ways value, int prevOrNext);
    inline Ways readIndex(const vector<int>& index, int prevOrNext);

    //iterating over indices
    vector<int> getStartIndex();
    void getNextIndex(vector<int>& index, bool& exists); //simple scheme to iterate on all indices

public:
    HyperCuboid(int steps, const vector<int>& start, const vector<int>& dims);
    Ways computeWays();
};

HyperCuboid::HyperCuboid(int steps, const vector<int>& start, const vector<int>& d)
: nsteps(steps), spos(start), dims(d) {
    cache[0] = cache[1] = NULL;
}

vector<int> HyperCuboid::getStartIndex() {
    return vector<int>(dims.size(), 0);
}

void HyperCuboid::getNextIndex(vector<int>& index, bool& exists) {
    for (int i=dims.size()-1; i>=0; i--) {
        if (index[i] == dims[i] - 1) { //this index reached the end
            index[i] = 0;              //reset it
        } else {
            index[i] += 1;
            break;
        }
    }
    if (index == getStartIndex()) {
        exists = false;
        return;
    }
}

void HyperCuboid::allocateCache() {
    int cellsNeeded = 1;
    for (const int& d : dims) cellsNeeded *= d;
    cache[0] = new Ways[cellsNeeded];
    cache[1] = new Ways[cellsNeeded];

    //initialize cache, this is base step of recursion
    //at steps=0, I can only go to one place, that is my current place
    vector<int> index = getStartIndex();
    bool exists = true;
    while (exists) {
        writeIndex(index, 1, 0);
        writeIndex(index, 0, 1);
        getNextIndex(index, exists);
    }
}

void HyperCuboid::freeCache() {
    delete [] cache[0];
    delete [] cache[1];
}

bool HyperCuboid::onBoard(const vector<int>& index) {
    for (int i=0; i<dims.size(); i++) {
        if (index[i] < 0 || index[i] >= dims[i]) return false;
    }
    return true;
}

Ways& HyperCuboid::position(const vector<int>& index, int prevOrNext) {
    int chunkSize = 1;              //stores size of current chunk
    for (int i = 0; i<dims.size(); i++) chunkSize *= dims[i];
    int offset = 0;
    for (int i = 0; i<index.size(); i++) {
        chunkSize /= dims[i];                 //adjust my chunkSize
        offset += index[i] * chunkSize;
    }
    return cache[prevOrNext][offset];
}

Ways HyperCuboid::readIndex(const vector<int>& index, int prevOrNext) {
    return position(index, prevOrNext);
}

void HyperCuboid::writeIndex(const vector<int>& index, Ways value, int prevOrNext) {
    position(index, prevOrNext) = value;
}

Ways HyperCuboid::computeWays() {
    allocateCache();

    //take the required number of steps
    int prev=0, next=1;
    for (int s=0; s<nsteps; s++) {
        vector<int> index = getStartIndex();
        bool exists = true;
        while (exists) {
            Ways curWays = 0;
            for (int i=0; i<index.size(); i++) {
                vector<int> stepIndexPlus  = index;
                vector<int> stepIndexMinus = index;
                stepIndexPlus[i]  += 1;
                stepIndexMinus[i] -= 1;
                if (onBoard(stepIndexPlus)) {
                    curWays += readIndex(stepIndexPlus, prev);
                }
                if (onBoard(stepIndexMinus)) {
                    curWays += readIndex(stepIndexMinus, prev);
                }
            }
            curWays %= ((Ways) MODNUM);
            writeIndex(index, curWays, next);
            getNextIndex(index, exists);
        }
        next = 1-next;
        prev = 1-prev;
    }

    Ways ways = readIndex(spos, prev);
    freeCache();
    ways = ways % ((Ways) MODNUM);
    return ways;
}

int main() {
    int tc; std::cin >> tc;
    for (int t=0; t<tc; t++) {
        int n, m;
        std::cin >> n >> m;
        vector<int> dims, pos;
        for (int i=0; i<n; i++)  {
            int p; std::cin >> p;
            pos.push_back(p-1); //make this 0-indexed right here
        }
        for (int i=0; i<n; i++)  {
            int d; std::cin >> d;
            dims.push_back(d);
        }
        HyperCuboid hc(m, pos, dims);
        Ways ans = hc.computeWays();
        std::cout << ans << std::endl;
    }
}
<commit_msg>Removing old version.<commit_after><|endoftext|>


<commit_before>#pragma once

#include <eosio/trace_api_plugin/trace.hpp>
#include <exception>
#include <functional>
#include <map>

namespace eosio { namespace trace_api_plugin {

using chain::transaction_id_type;
using chain::packed_transaction;

template <typename StoreProvider>
class chain_extraction_impl_type {
public:
   /**
    * Chain Extractor for capturing transaction traces, action traces, and block info.
    * @param store provider of append_data_log & append_metadata_log
    * @param except_handler called on exceptions, logging if any is left to the user
    * @param shutdown called when this class determines application should shutdown because of fatal error
    */
   chain_extraction_impl_type( StoreProvider& store, std::function<void(std::exception_ptr)> except_handler )
   : store(store)
   , except_handler(std::move(except_handler))
   {}

   /// connect to chain controller applied_transaction signal
   void signal_applied_transaction( const chain::transaction_trace_ptr& trace, const chain::signed_transaction& strx ) {
      on_applied_transaction( trace, strx );
   }

   /// connect to chain controller accepted_block signal
   void signal_accepted_block( const chain::block_state_ptr& bsp ) {
      on_accepted_block( bsp );
   }

   /// connect to chain controller irreversible_block signal
   void signal_irreversible_block( const chain::block_state_ptr& bsp ) {
      on_irreversible_block( bsp );
   }

private:
   static bool is_onblock(const chain::transaction_trace_ptr& p) {
      if (p->action_traces.size() != 1)
         return false;
      const auto& act = p->action_traces[0].act;
      if (act.account != eosio::chain::config::system_account_name || act.name != N(onblock) ||
          act.authorization.size() != 1)
         return false;
      const auto& auth = act.authorization[0];
      return auth.actor == eosio::chain::config::system_account_name &&
             auth.permission == eosio::chain::config::active_name;
   }

   void on_applied_transaction(const chain::transaction_trace_ptr& p, const chain::signed_transaction& t) {
      if (p->receipt) {
         if( is_onblock( p )) {
            onblock_trace.emplace( p );
         } else if (p->failed_dtrx_trace) {
            cached_traces[p->failed_dtrx_trace->id] = p;
         } else {
            cached_traces[p->id] = p;
         }
      }
   }

   void on_accepted_block(const chain::block_state_ptr& block_state) {
      store_block_trace( block_state );
   }

   void on_irreversible_block( const chain::block_state_ptr& block_state ) {
      store_lib( block_state );
   }

   void store_block_trace( const chain::block_state_ptr& block_state ) {
      try {
         block_trace_v0 bt = create_block_trace_v0( block_state );

         std::vector<transaction_trace_v0>& traces = bt.transactions;
         traces.reserve( block_state->block->transactions.size() + 1 );
         if( onblock_trace )
            traces.emplace_back( to_transaction_trace_v0( *onblock_trace ));
         for( const auto& r : block_state->block->transactions ) {
            transaction_id_type id;
            if( r.trx.contains<transaction_id_type>()) {
               id = r.trx.get<transaction_id_type>();
            } else {
               id = r.trx.get<packed_transaction>().id();
            }
            const auto it = cached_traces.find( id );
            // could assert, go with best effort
            if( it != cached_traces.end() ) {
               traces.emplace_back( to_transaction_trace_v0( it->second ));
            } else {
               traces.emplace_back( transaction_trace_v0{ .id = id } );
            }
         }
         cached_traces.clear();
         onblock_trace.reset();

         uint64_t offset = store.append_data_log( std::move( bt ));
         store.append_metadata_log( block_entry_v0{.id = block_state->id, .number = block_state->block_num, .offset = offset} );

      } catch( ... ) {
         except_handler( std::current_exception() );
      }
   }

   void store_lib( const chain::block_state_ptr& bsp ) {
      try {
         store.append_metadata_log( lib_entry_v0{ .lib = bsp->block_num } );
      } catch( ... ) {
         except_handler( std::current_exception() );
      }
   }

private:
   StoreProvider&                                               store;
   std::function<void(std::exception_ptr)>                      except_handler;
   std::map<transaction_id_type, chain::transaction_trace_ptr>  cached_traces;
   fc::optional<chain::transaction_trace_ptr>                   onblock_trace;

};

}}<commit_msg>Take by value<commit_after>#pragma once

#include <eosio/trace_api_plugin/trace.hpp>
#include <eosio/trace_api_plugin/extract_util.hpp>
#include <exception>
#include <functional>
#include <map>

namespace eosio { namespace trace_api_plugin {

using chain::transaction_id_type;
using chain::packed_transaction;

template <typename StoreProvider>
class chain_extraction_impl_type {
public:
   /**
    * Chain Extractor for capturing transaction traces, action traces, and block info.
    * @param store provider of append_data_log & append_metadata_log
    * @param except_handler called on exceptions, logging if any is left to the user
    * @param shutdown called when this class determines application should shutdown because of fatal error
    */
   chain_extraction_impl_type( StoreProvider store, std::function<void(std::exception_ptr)> except_handler )
   : store(std::move(store))
   , except_handler(std::move(except_handler))
   {}

   /// connect to chain controller applied_transaction signal
   void signal_applied_transaction( const chain::transaction_trace_ptr& trace, const chain::signed_transaction& strx ) {
      on_applied_transaction( trace, strx );
   }

   /// connect to chain controller accepted_block signal
   void signal_accepted_block( const chain::block_state_ptr& bsp ) {
      on_accepted_block( bsp );
   }

   /// connect to chain controller irreversible_block signal
   void signal_irreversible_block( const chain::block_state_ptr& bsp ) {
      on_irreversible_block( bsp );
   }

private:
   static bool is_onblock(const chain::transaction_trace_ptr& p) {
      if (p->action_traces.size() != 1)
         return false;
      const auto& act = p->action_traces[0].act;
      if (act.account != eosio::chain::config::system_account_name || act.name != N(onblock) ||
          act.authorization.size() != 1)
         return false;
      const auto& auth = act.authorization[0];
      return auth.actor == eosio::chain::config::system_account_name &&
             auth.permission == eosio::chain::config::active_name;
   }

   void on_applied_transaction(const chain::transaction_trace_ptr& p, const chain::signed_transaction& t) {
      if (p->receipt) {
         if( is_onblock( p )) {
            onblock_trace.emplace( p );
         } else if (p->failed_dtrx_trace) {
            cached_traces[p->failed_dtrx_trace->id] = p;
         } else {
            cached_traces[p->id] = p;
         }
      }
   }

   void on_accepted_block(const chain::block_state_ptr& block_state) {
      store_block_trace( block_state );
   }

   void on_irreversible_block( const chain::block_state_ptr& block_state ) {
      store_lib( block_state );
   }

   void store_block_trace( const chain::block_state_ptr& block_state ) {
      try {
         block_trace_v0 bt = create_block_trace_v0( block_state );

         std::vector<transaction_trace_v0>& traces = bt.transactions;
         traces.reserve( block_state->block->transactions.size() + 1 );
         if( onblock_trace )
            traces.emplace_back( to_transaction_trace_v0( *onblock_trace ));
         for( const auto& r : block_state->block->transactions ) {
            transaction_id_type id;
            if( r.trx.contains<transaction_id_type>()) {
               id = r.trx.get<transaction_id_type>();
            } else {
               id = r.trx.get<packed_transaction>().id();
            }
            const auto it = cached_traces.find( id );
            // could assert, go with best effort
            if( it != cached_traces.end() ) {
               traces.emplace_back( to_transaction_trace_v0( it->second ));
            } else {
               traces.emplace_back( transaction_trace_v0{ .id = id } );
            }
         }
         cached_traces.clear();
         onblock_trace.reset();

         uint64_t offset = store.append_data_log( std::move( bt ));
         store.append_metadata_log( block_entry_v0{.id = block_state->id, .number = block_state->block_num, .offset = offset} );

      } catch( ... ) {
         except_handler( std::current_exception() );
      }
   }

   void store_lib( const chain::block_state_ptr& bsp ) {
      try {
         store.append_metadata_log( lib_entry_v0{ .lib = bsp->block_num } );
      } catch( ... ) {
         except_handler( std::current_exception() );
      }
   }

private:
   StoreProvider                                                store;
   std::function<void(std::exception_ptr)>                      except_handler;
   std::map<transaction_id_type, chain::transaction_trace_ptr>  cached_traces;
   fc::optional<chain::transaction_trace_ptr>                   onblock_trace;

};

}}<|endoftext|>


<commit_before>/*
	This file is part of cpp-ethereum.

	cpp-ethereum is free software: you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

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

	You should have received a copy of the GNU General Public License
	along with cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.
*/
/**
 * @author Lefteris <lefteris@ethdev.com>
 * @date 2014
 * Solidity command line interface.
 */
#include "CommandLineInterface.h"

#include <string>
#include <iostream>
#include <fstream>

#include <boost/filesystem.hpp>

#include "BuildInfo.h"
#include <libdevcore/Common.h>
#include <libdevcore/CommonData.h>
#include <libdevcore/CommonIO.h>
#include <libevmcore/Instruction.h>
#include <libsolidity/Scanner.h>
#include <libsolidity/Parser.h>
#include <libsolidity/ASTPrinter.h>
#include <libsolidity/NameAndTypeResolver.h>
#include <libsolidity/Exceptions.h>
#include <libsolidity/CompilerStack.h>
#include <libsolidity/SourceReferenceFormatter.h>

using namespace std;
namespace po = boost::program_options;

namespace dev
{
namespace solidity
{

static void version()
{
	cout << "solc, the solidity complier commandline interface " << dev::Version << endl
		 << "  by Christian <c@ethdev.com> and Lefteris <lefteris@ethdev.com>, (c) 2014." << endl
		 << "Build: " << DEV_QUOTED(ETH_BUILD_PLATFORM) << "/" << DEV_QUOTED(ETH_BUILD_TYPE) << endl;
	exit(0);
}

static inline bool argToStdout(po::variables_map const& _args, const char* _name)
{
	return _args.count(_name) && _args[_name].as<OutputType>() != OutputType::FILE;
}

static bool needStdout(po::variables_map const& _args)
{
	return argToStdout(_args, "abi") || argToStdout(_args, "natspec-user") || argToStdout(_args, "natspec-dev") ||
		   argToStdout(_args, "asm") || argToStdout(_args, "opcodes") || argToStdout(_args, "binary");
}

static inline bool outputToFile(OutputType type)
{
	return type == OutputType::FILE || type == OutputType::BOTH;
}

static inline bool outputToStdout(OutputType type)
{
	return type == OutputType::STDOUT || type == OutputType::BOTH;
}

static std::istream& operator>>(std::istream& _in, OutputType& io_output)
{
	std::string token;
	_in >> token;
	if (token == "stdout")
		io_output = OutputType::STDOUT;
	else if (token == "file")
		io_output = OutputType::FILE;
	else if (token == "both")
		io_output = OutputType::BOTH;
	else
		throw boost::program_options::invalid_option_value(token);
	return _in;
}

void CommandLineInterface::handleBytecode(string const& _argName,
										  string const& _title,
										  string const& _contract,
										  string const& _suffix)
{
	if (m_args.count(_argName))
	{
		auto choice = m_args[_argName].as<OutputType>();
		if (outputToStdout(choice))
		{
			cout << _title << endl;
			if (_suffix == "opcodes")
				;
				// TODO: Figure out why after moving to own class ostream operator does not work for vector of bytes
				// cout << m_compiler.getBytecode(_contract) << endl;
			else
				cout << toHex(m_compiler.getBytecode(_contract)) << endl;
		}

		if (outputToFile(choice))
		{
			ofstream outFile(_contract + _suffix);
			if (_suffix == "opcodes")
				;
				// TODO: Figure out why after moving to own class ostream operator does not work for vector of bytes
				// outFile << m_compiler.getBytecode(_contract);
			else
				outFile << toHex(m_compiler.getBytecode(_contract));
			outFile.close();
		}
	}
}

void CommandLineInterface::handleJson(DocumentationType _type,
									  string const& _contract)
{
	std::string argName;
	std::string suffix;
	std::string title;
	switch(_type)
	{
	case DocumentationType::ABI_INTERFACE:
		argName = "abi";
		suffix = ".abi";
		title = "Contract ABI";
		break;
	case DocumentationType::NATSPEC_USER:
		argName = "natspec-user";
		suffix = ".docuser";
		title = "User Documentation";
		break;
	case DocumentationType::NATSPEC_DEV:
		argName = "natspec-dev";
		suffix = ".docdev";
		title = "Developer Documentation";
		break;
	default:
		// should never happen
		BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Unknown documentation _type"));
	}

	if (m_args.count(argName))
	{
		auto choice = m_args[argName].as<OutputType>();
		if (outputToStdout(choice))
		{
			cout << title << endl;
			cout << m_compiler.getJsonDocumentation(_contract, _type);
		}

		if (outputToFile(choice))
		{
			ofstream outFile(_contract + suffix);
			outFile << m_compiler.getJsonDocumentation(_contract, _type);
			outFile.close();
		}
	}
}

bool CommandLineInterface::parseArguments(int argc, char** argv)
{
#define OUTPUT_TYPE_STR "Legal values:\n"				\
		"\tstdout: Print it to standard output\n"		\
		"\tfile: Print it to a file with same name\n"	\
		"\tboth: Print both to a file and the stdout\n"
	// Declare the supported options.
	po::options_description desc("Allowed options");
	desc.add_options()
		("help", "Show help message and exit")
		("version", "Show version and exit")
		("optimize", po::value<bool>()->default_value(false), "Optimize bytecode for size")
		("input-file", po::value<vector<string>>(), "input file")
		("ast", po::value<OutputType>(),
		 "Request to output the AST of the contract. " OUTPUT_TYPE_STR)
		("asm", po::value<OutputType>(),
		 "Request to output the EVM assembly of the contract. "	 OUTPUT_TYPE_STR)
		("opcodes", po::value<OutputType>(),
		 "Request to output the Opcodes of the contract. "	OUTPUT_TYPE_STR)
		("binary", po::value<OutputType>(),
		 "Request to output the contract in binary (hexadecimal). "	 OUTPUT_TYPE_STR)
		("abi", po::value<OutputType>(),
		 "Request to output the contract's ABI interface. "	 OUTPUT_TYPE_STR)
		("natspec-user", po::value<OutputType>(),
		 "Request to output the contract's Natspec user documentation. "  OUTPUT_TYPE_STR)
		("natspec-dev", po::value<OutputType>(),
		 "Request to output the contract's Natspec developer documentation. "  OUTPUT_TYPE_STR);
#undef OUTPUT_TYPE_STR

	// All positional options should be interpreted as input files
	po::positional_options_description p;
	p.add("input-file", -1);

	// parse the compiler arguments
	try
	{
		po::store(po::command_line_parser(argc, argv).options(desc).positional(p).allow_unregistered().run(), m_args);
	}
	catch (po::error const& exception)
	{
		cout << exception.what() << endl;
		return false;
	}
	po::notify(m_args);

	if (m_args.count("help"))
	{
		cout << desc;
		return false;
	}

	if (m_args.count("version"))
	{
		version();
		return false;
	}

	return true;
}

bool CommandLineInterface::processInput()
{
	if (!m_args.count("input-file"))
	{
		string s;
		while (!cin.eof())
		{
			getline(cin, s);
			m_sourceCodes["<stdin>"].append(s);
		}
	}
	else
		for (string const& infile: m_args["input-file"].as<vector<string>>())
			m_sourceCodes[infile] = asString(dev::contents(infile));

	try
	{
		for (auto const& sourceCode: m_sourceCodes)
			m_compiler.addSource(sourceCode.first, sourceCode.second);
		// TODO: Perhaps we should not compile unless requested
		m_compiler.compile(m_args["optimize"].as<bool>());
	}
	catch (ParserError const& exception)
	{
		SourceReferenceFormatter::printExceptionInformation(cerr, exception, "Parser error", m_compiler);
		return false;
	}
	catch (DeclarationError const& exception)
	{
		SourceReferenceFormatter::printExceptionInformation(cerr, exception, "Declaration error", m_compiler);
		return false;
	}
	catch (TypeError const& exception)
	{
		SourceReferenceFormatter::printExceptionInformation(cerr, exception, "Type error", m_compiler);
		return false;
	}
	catch (CompilerError const& exception)
	{
		SourceReferenceFormatter::printExceptionInformation(cerr, exception, "Compiler error", m_compiler);
		return false;
	}
	catch (InternalCompilerError const& exception)
	{
		SourceReferenceFormatter::printExceptionInformation(cerr, exception, "Internal compiler error", m_compiler);
		return false;
	}
	catch (Exception const& exception)
	{
		cerr << "Exception during compilation: " << boost::diagnostic_information(exception) << endl;
		return false;
	}
	catch (...)
	{
		cerr << "Unknown exception during compilation." << endl;
		return false;
	}

	return true;
}

void CommandLineInterface::actOnInput()
{
	// do we need AST output?
	if (m_args.count("ast"))
	{
		auto choice = m_args["ast"].as<OutputType>();
		if (outputToStdout(choice))
		{
			cout << "Syntax trees:" << endl << endl;
			for (auto const& sourceCode: m_sourceCodes)
			{
				cout << endl << "======= " << sourceCode.first << " =======" << endl;
				ASTPrinter printer(m_compiler.getAST(sourceCode.first), sourceCode.second);
				printer.print(cout);
			}
		}

		if (outputToFile(choice))
		{
			for (auto const& sourceCode: m_sourceCodes)
			{
				boost::filesystem::path p(sourceCode.first);
				ofstream outFile(p.stem().string() + ".ast");
				ASTPrinter printer(m_compiler.getAST(sourceCode.first), sourceCode.second);
				printer.print(outFile);
				outFile.close();
			}
		}
	}

	vector<string> contracts = m_compiler.getContractNames();
	for (string const& contract: contracts)
	{
		if (needStdout(m_args))
			cout << endl << "======= " << contract << " =======" << endl;

		// do we need EVM assembly?
		if (m_args.count("asm"))
		{
			auto choice = m_args["asm"].as<OutputType>();
			if (outputToStdout(choice))
			{
				cout << "EVM assembly:" << endl;
				m_compiler.streamAssembly(cout, contract);
			}

			if (outputToFile(choice))
			{
				ofstream outFile(contract + ".evm");
				m_compiler.streamAssembly(outFile, contract);
				outFile.close();
			}
		}

		handleBytecode("opcodes", "Opcodes:", contract, ".opcodes");
		handleBytecode("binary", "Binary:", contract, ".binary");
		handleJson(DocumentationType::ABI_INTERFACE, contract);
		handleJson(DocumentationType::NATSPEC_DEV, contract);
		handleJson(DocumentationType::NATSPEC_USER, contract);
	} // end of contracts iteration
}

}
}
<commit_msg>Explicitly calling dev::operator<<() on two occassions due to mixup with boost<commit_after>/*
	This file is part of cpp-ethereum.

	cpp-ethereum is free software: you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

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

	You should have received a copy of the GNU General Public License
	along with cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.
*/
/**
 * @author Lefteris <lefteris@ethdev.com>
 * @date 2014
 * Solidity command line interface.
 */
#include "CommandLineInterface.h"

#include <string>
#include <iostream>
#include <fstream>

#include <boost/filesystem.hpp>

#include "BuildInfo.h"
#include <libdevcore/Common.h>
#include <libdevcore/CommonData.h>
#include <libdevcore/CommonIO.h>
#include <libevmcore/Instruction.h>
#include <libsolidity/Scanner.h>
#include <libsolidity/Parser.h>
#include <libsolidity/ASTPrinter.h>
#include <libsolidity/NameAndTypeResolver.h>
#include <libsolidity/Exceptions.h>
#include <libsolidity/CompilerStack.h>
#include <libsolidity/SourceReferenceFormatter.h>

using namespace std;
namespace po = boost::program_options;

namespace dev
{
namespace solidity
{

static void version()
{
	cout << "solc, the solidity complier commandline interface " << dev::Version << endl
		 << "  by Christian <c@ethdev.com> and Lefteris <lefteris@ethdev.com>, (c) 2014." << endl
		 << "Build: " << DEV_QUOTED(ETH_BUILD_PLATFORM) << "/" << DEV_QUOTED(ETH_BUILD_TYPE) << endl;
	exit(0);
}

static inline bool argToStdout(po::variables_map const& _args, const char* _name)
{
	return _args.count(_name) && _args[_name].as<OutputType>() != OutputType::FILE;
}

static bool needStdout(po::variables_map const& _args)
{
	return argToStdout(_args, "abi") || argToStdout(_args, "natspec-user") || argToStdout(_args, "natspec-dev") ||
		   argToStdout(_args, "asm") || argToStdout(_args, "opcodes") || argToStdout(_args, "binary");
}

static inline bool outputToFile(OutputType type)
{
	return type == OutputType::FILE || type == OutputType::BOTH;
}

static inline bool outputToStdout(OutputType type)
{
	return type == OutputType::STDOUT || type == OutputType::BOTH;
}

static std::istream& operator>>(std::istream& _in, OutputType& io_output)
{
	std::string token;
	_in >> token;
	if (token == "stdout")
		io_output = OutputType::STDOUT;
	else if (token == "file")
		io_output = OutputType::FILE;
	else if (token == "both")
		io_output = OutputType::BOTH;
	else
		throw boost::program_options::invalid_option_value(token);
	return _in;
}

void CommandLineInterface::handleBytecode(string const& _argName,
										  string const& _title,
										  string const& _contract,
										  string const& _suffix)
{
	if (m_args.count(_argName))
	{
		auto choice = m_args[_argName].as<OutputType>();
		if (outputToStdout(choice))
		{
			cout << _title << endl;
			if (_suffix == "opcodes")
			{
				// TODO: Figure out why the wrong operator << (from boost) is used here
				dev::operator<<(cout, m_compiler.getBytecode(_contract));
				cout << endl;
			}
			else
				cout << toHex(m_compiler.getBytecode(_contract)) << endl;
		}

		if (outputToFile(choice))
		{
			ofstream outFile(_contract + _suffix);
			if (_suffix == "opcodes")
				// TODO: Figure out why the wrong operator << (from boost) is used here
				dev::operator<<(outFile, m_compiler.getBytecode(_contract));

			else
				outFile << toHex(m_compiler.getBytecode(_contract));
			outFile.close();
		}
	}
}

void CommandLineInterface::handleJson(DocumentationType _type,
									  string const& _contract)
{
	std::string argName;
	std::string suffix;
	std::string title;
	switch(_type)
	{
	case DocumentationType::ABI_INTERFACE:
		argName = "abi";
		suffix = ".abi";
		title = "Contract ABI";
		break;
	case DocumentationType::NATSPEC_USER:
		argName = "natspec-user";
		suffix = ".docuser";
		title = "User Documentation";
		break;
	case DocumentationType::NATSPEC_DEV:
		argName = "natspec-dev";
		suffix = ".docdev";
		title = "Developer Documentation";
		break;
	default:
		// should never happen
		BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Unknown documentation _type"));
	}

	if (m_args.count(argName))
	{
		auto choice = m_args[argName].as<OutputType>();
		if (outputToStdout(choice))
		{
			cout << title << endl;
			cout << m_compiler.getJsonDocumentation(_contract, _type);
		}

		if (outputToFile(choice))
		{
			ofstream outFile(_contract + suffix);
			outFile << m_compiler.getJsonDocumentation(_contract, _type);
			outFile.close();
		}
	}
}

bool CommandLineInterface::parseArguments(int argc, char** argv)
{
#define OUTPUT_TYPE_STR "Legal values:\n"				\
		"\tstdout: Print it to standard output\n"		\
		"\tfile: Print it to a file with same name\n"	\
		"\tboth: Print both to a file and the stdout\n"
	// Declare the supported options.
	po::options_description desc("Allowed options");
	desc.add_options()
		("help", "Show help message and exit")
		("version", "Show version and exit")
		("optimize", po::value<bool>()->default_value(false), "Optimize bytecode for size")
		("input-file", po::value<vector<string>>(), "input file")
		("ast", po::value<OutputType>(),
		 "Request to output the AST of the contract. " OUTPUT_TYPE_STR)
		("asm", po::value<OutputType>(),
		 "Request to output the EVM assembly of the contract. "	 OUTPUT_TYPE_STR)
		("opcodes", po::value<OutputType>(),
		 "Request to output the Opcodes of the contract. "	OUTPUT_TYPE_STR)
		("binary", po::value<OutputType>(),
		 "Request to output the contract in binary (hexadecimal). "	 OUTPUT_TYPE_STR)
		("abi", po::value<OutputType>(),
		 "Request to output the contract's ABI interface. "	 OUTPUT_TYPE_STR)
		("natspec-user", po::value<OutputType>(),
		 "Request to output the contract's Natspec user documentation. "  OUTPUT_TYPE_STR)
		("natspec-dev", po::value<OutputType>(),
		 "Request to output the contract's Natspec developer documentation. "  OUTPUT_TYPE_STR);
#undef OUTPUT_TYPE_STR

	// All positional options should be interpreted as input files
	po::positional_options_description p;
	p.add("input-file", -1);

	// parse the compiler arguments
	try
	{
		po::store(po::command_line_parser(argc, argv).options(desc).positional(p).allow_unregistered().run(), m_args);
	}
	catch (po::error const& exception)
	{
		cout << exception.what() << endl;
		return false;
	}
	po::notify(m_args);

	if (m_args.count("help"))
	{
		cout << desc;
		return false;
	}

	if (m_args.count("version"))
	{
		version();
		return false;
	}

	return true;
}

bool CommandLineInterface::processInput()
{
	if (!m_args.count("input-file"))
	{
		string s;
		while (!cin.eof())
		{
			getline(cin, s);
			m_sourceCodes["<stdin>"].append(s);
		}
	}
	else
		for (string const& infile: m_args["input-file"].as<vector<string>>())
			m_sourceCodes[infile] = asString(dev::contents(infile));

	try
	{
		for (auto const& sourceCode: m_sourceCodes)
			m_compiler.addSource(sourceCode.first, sourceCode.second);
		// TODO: Perhaps we should not compile unless requested
		m_compiler.compile(m_args["optimize"].as<bool>());
	}
	catch (ParserError const& exception)
	{
		SourceReferenceFormatter::printExceptionInformation(cerr, exception, "Parser error", m_compiler);
		return false;
	}
	catch (DeclarationError const& exception)
	{
		SourceReferenceFormatter::printExceptionInformation(cerr, exception, "Declaration error", m_compiler);
		return false;
	}
	catch (TypeError const& exception)
	{
		SourceReferenceFormatter::printExceptionInformation(cerr, exception, "Type error", m_compiler);
		return false;
	}
	catch (CompilerError const& exception)
	{
		SourceReferenceFormatter::printExceptionInformation(cerr, exception, "Compiler error", m_compiler);
		return false;
	}
	catch (InternalCompilerError const& exception)
	{
		SourceReferenceFormatter::printExceptionInformation(cerr, exception, "Internal compiler error", m_compiler);
		return false;
	}
	catch (Exception const& exception)
	{
		cerr << "Exception during compilation: " << boost::diagnostic_information(exception) << endl;
		return false;
	}
	catch (...)
	{
		cerr << "Unknown exception during compilation." << endl;
		return false;
	}

	return true;
}

void CommandLineInterface::actOnInput()
{
	// do we need AST output?
	if (m_args.count("ast"))
	{
		auto choice = m_args["ast"].as<OutputType>();
		if (outputToStdout(choice))
		{
			cout << "Syntax trees:" << endl << endl;
			for (auto const& sourceCode: m_sourceCodes)
			{
				cout << endl << "======= " << sourceCode.first << " =======" << endl;
				ASTPrinter printer(m_compiler.getAST(sourceCode.first), sourceCode.second);
				printer.print(cout);
			}
		}

		if (outputToFile(choice))
		{
			for (auto const& sourceCode: m_sourceCodes)
			{
				boost::filesystem::path p(sourceCode.first);
				ofstream outFile(p.stem().string() + ".ast");
				ASTPrinter printer(m_compiler.getAST(sourceCode.first), sourceCode.second);
				printer.print(outFile);
				outFile.close();
			}
		}
	}

	vector<string> contracts = m_compiler.getContractNames();
	for (string const& contract: contracts)
	{
		if (needStdout(m_args))
			cout << endl << "======= " << contract << " =======" << endl;

		// do we need EVM assembly?
		if (m_args.count("asm"))
		{
			auto choice = m_args["asm"].as<OutputType>();
			if (outputToStdout(choice))
			{
				cout << "EVM assembly:" << endl;
				m_compiler.streamAssembly(cout, contract);
			}

			if (outputToFile(choice))
			{
				ofstream outFile(contract + ".evm");
				m_compiler.streamAssembly(outFile, contract);
				outFile.close();
			}
		}

		handleBytecode("opcodes", "Opcodes:", contract, ".opcodes");
		handleBytecode("binary", "Binary:", contract, ".binary");
		handleJson(DocumentationType::ABI_INTERFACE, contract);
		handleJson(DocumentationType::NATSPEC_DEV, contract);
		handleJson(DocumentationType::NATSPEC_USER, contract);
	} // end of contracts iteration
}

}
}
<|endoftext|>


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

#include "test/cctest/trace-extension.h"

#include "src/sampler.h"
#include "test/cctest/cctest.h"

namespace v8 {
namespace internal {

const char* TraceExtension::kSource =
    "native function trace();"
    "native function js_trace();"
    "native function js_entry_sp();"
    "native function js_entry_sp_level2();";

v8::Handle<v8::FunctionTemplate> TraceExtension::GetNativeFunctionTemplate(
    v8::Isolate* isolate, v8::Handle<v8::String> name) {
  if (name->Equals(v8::String::NewFromUtf8(isolate, "trace"))) {
    return v8::FunctionTemplate::New(isolate, TraceExtension::Trace);
  } else if (name->Equals(v8::String::NewFromUtf8(isolate, "js_trace"))) {
    return v8::FunctionTemplate::New(isolate, TraceExtension::JSTrace);
  } else if (name->Equals(v8::String::NewFromUtf8(isolate, "js_entry_sp"))) {
    return v8::FunctionTemplate::New(isolate, TraceExtension::JSEntrySP);
  } else if (name->Equals(v8::String::NewFromUtf8(isolate,
                                                  "js_entry_sp_level2"))) {
    return v8::FunctionTemplate::New(isolate, TraceExtension::JSEntrySPLevel2);
  } else {
    CHECK(false);
    return v8::Handle<v8::FunctionTemplate>();
  }
}

Address TraceExtension::GetFP(const v8::FunctionCallbackInfo<v8::Value>& args) {
  // Convert frame pointer from encoding as smis in the arguments to a pointer.
  CHECK_EQ(2, args.Length());  // Ignore second argument on 32-bit platform.
#if defined(V8_HOST_ARCH_32_BIT)
  Address fp = *reinterpret_cast<Address*>(*args[0]);
#elif defined(V8_HOST_ARCH_64_BIT)
  int64_t low_bits = *reinterpret_cast<uint64_t*>(*args[0]) >> 32;
  int64_t high_bits = *reinterpret_cast<uint64_t*>(*args[1]);
  Address fp = reinterpret_cast<Address>(high_bits | low_bits);
#else
#error Host architecture is neither 32-bit nor 64-bit.
#endif
  printf("Trace: %p\n", fp);
  return fp;
}

static struct {
  TickSample* sample;
} trace_env = { NULL };

void TraceExtension::InitTraceEnv(TickSample* sample) {
  trace_env.sample = sample;
}

void TraceExtension::DoTrace(Address fp) {
  RegisterState regs;
  regs.fp = fp;
  // sp is only used to define stack high bound
  regs.sp =
      reinterpret_cast<Address>(trace_env.sample) - 10240;
  trace_env.sample->Init(CcTest::i_isolate(), regs,
                         TickSample::kSkipCEntryFrame);
}

void TraceExtension::Trace(const v8::FunctionCallbackInfo<v8::Value>& args) {
  DoTrace(GetFP(args));
}

// Hide c_entry_fp to emulate situation when sampling is done while
// pure JS code is being executed
static void DoTraceHideCEntryFPAddress(Address fp) {
  v8::internal::Address saved_c_frame_fp =
      *(CcTest::i_isolate()->c_entry_fp_address());
  CHECK(saved_c_frame_fp);
  *(CcTest::i_isolate()->c_entry_fp_address()) = 0;
  i::TraceExtension::DoTrace(fp);
  *(CcTest::i_isolate()->c_entry_fp_address()) = saved_c_frame_fp;
}

void TraceExtension::JSTrace(const v8::FunctionCallbackInfo<v8::Value>& args) {
  DoTraceHideCEntryFPAddress(GetFP(args));
}

Address TraceExtension::GetJsEntrySp() {
  CHECK_NE(NULL, CcTest::i_isolate()->thread_local_top());
  return CcTest::i_isolate()->js_entry_sp();
}

void TraceExtension::JSEntrySP(
    const v8::FunctionCallbackInfo<v8::Value>& args) {
  CHECK_NE(0, GetJsEntrySp());
}

void TraceExtension::JSEntrySPLevel2(
    const v8::FunctionCallbackInfo<v8::Value>& args) {
  v8::HandleScope scope(args.GetIsolate());
  const Address js_entry_sp = GetJsEntrySp();
  CHECK_NE(0, js_entry_sp);
  CompileRun("js_entry_sp();");
  CHECK_EQ(js_entry_sp, GetJsEntrySp());
}

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

#include "test/cctest/trace-extension.h"

#include "src/sampler.h"
#include "src/vm-state-inl.h"
#include "test/cctest/cctest.h"

namespace v8 {
namespace internal {

const char* TraceExtension::kSource =
    "native function trace();"
    "native function js_trace();"
    "native function js_entry_sp();"
    "native function js_entry_sp_level2();";

v8::Handle<v8::FunctionTemplate> TraceExtension::GetNativeFunctionTemplate(
    v8::Isolate* isolate, v8::Handle<v8::String> name) {
  if (name->Equals(v8::String::NewFromUtf8(isolate, "trace"))) {
    return v8::FunctionTemplate::New(isolate, TraceExtension::Trace);
  } else if (name->Equals(v8::String::NewFromUtf8(isolate, "js_trace"))) {
    return v8::FunctionTemplate::New(isolate, TraceExtension::JSTrace);
  } else if (name->Equals(v8::String::NewFromUtf8(isolate, "js_entry_sp"))) {
    return v8::FunctionTemplate::New(isolate, TraceExtension::JSEntrySP);
  } else if (name->Equals(v8::String::NewFromUtf8(isolate,
                                                  "js_entry_sp_level2"))) {
    return v8::FunctionTemplate::New(isolate, TraceExtension::JSEntrySPLevel2);
  } else {
    CHECK(false);
    return v8::Handle<v8::FunctionTemplate>();
  }
}

Address TraceExtension::GetFP(const v8::FunctionCallbackInfo<v8::Value>& args) {
  // Convert frame pointer from encoding as smis in the arguments to a pointer.
  CHECK_EQ(2, args.Length());  // Ignore second argument on 32-bit platform.
#if defined(V8_HOST_ARCH_32_BIT)
  Address fp = *reinterpret_cast<Address*>(*args[0]);
#elif defined(V8_HOST_ARCH_64_BIT)
  int64_t low_bits = *reinterpret_cast<uint64_t*>(*args[0]) >> 32;
  int64_t high_bits = *reinterpret_cast<uint64_t*>(*args[1]);
  Address fp = reinterpret_cast<Address>(high_bits | low_bits);
#else
#error Host architecture is neither 32-bit nor 64-bit.
#endif
  printf("Trace: %p\n", fp);
  return fp;
}

static struct {
  TickSample* sample;
} trace_env = { NULL };

void TraceExtension::InitTraceEnv(TickSample* sample) {
  trace_env.sample = sample;
}

void TraceExtension::DoTrace(Address fp) {
  RegisterState regs;
  regs.fp = fp;
  // sp is only used to define stack high bound
  regs.sp =
      reinterpret_cast<Address>(trace_env.sample) - 10240;
  trace_env.sample->Init(CcTest::i_isolate(), regs,
                         TickSample::kSkipCEntryFrame);
}

void TraceExtension::Trace(const v8::FunctionCallbackInfo<v8::Value>& args) {
  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(args.GetIsolate());
  i::VMState<EXTERNAL> state(isolate);
  Address address = reinterpret_cast<Address>(
      reinterpret_cast<intptr_t>(&TraceExtension::Trace));
  i::ExternalCallbackScope call_scope(isolate, address);
  DoTrace(GetFP(args));
}

// Hide c_entry_fp to emulate situation when sampling is done while
// pure JS code is being executed
static void DoTraceHideCEntryFPAddress(Address fp) {
  v8::internal::Address saved_c_frame_fp =
      *(CcTest::i_isolate()->c_entry_fp_address());
  CHECK(saved_c_frame_fp);
  *(CcTest::i_isolate()->c_entry_fp_address()) = 0;
  i::TraceExtension::DoTrace(fp);
  *(CcTest::i_isolate()->c_entry_fp_address()) = saved_c_frame_fp;
}

void TraceExtension::JSTrace(const v8::FunctionCallbackInfo<v8::Value>& args) {
  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(args.GetIsolate());
  i::VMState<EXTERNAL> state(isolate);
  Address address = reinterpret_cast<Address>(
      reinterpret_cast<intptr_t>(&TraceExtension::JSTrace));
  i::ExternalCallbackScope call_scope(isolate, address);
  DoTraceHideCEntryFPAddress(GetFP(args));
}

Address TraceExtension::GetJsEntrySp() {
  CHECK_NE(NULL, CcTest::i_isolate()->thread_local_top());
  return CcTest::i_isolate()->js_entry_sp();
}

void TraceExtension::JSEntrySP(
    const v8::FunctionCallbackInfo<v8::Value>& args) {
  CHECK_NE(0, GetJsEntrySp());
}

void TraceExtension::JSEntrySPLevel2(
    const v8::FunctionCallbackInfo<v8::Value>& args) {
  v8::HandleScope scope(args.GetIsolate());
  const Address js_entry_sp = GetJsEntrySp();
  CHECK_NE(0, js_entry_sp);
  CompileRun("js_entry_sp();");
  CHECK_EQ(js_entry_sp, GetJsEntrySp());
}

} }  // namespace v8::internal
<|endoftext|>